numparam, bsim4, and small tweeks

This commit is contained in:
stefanjones 2006-08-31 18:11:27 +00:00
parent e68098914e
commit 317ce09249
46 changed files with 9864 additions and 1205 deletions

View File

@ -1,3 +1,28 @@
2006-08-31 Stefan Jones <stefan.jones@multigig.com>
* configure.in:
Version 0.2.19
* configure.in
src/Makefile.am
src/frontend/Makefile.am
src/frontend/numparam/{.cvsignore,Makefile.am,downgrad.txt,general.h,
mystring.c,ngconfig.sh,numpaif.h,numparam.h,nupatest.c,readme.txt,
spicenum.c,washprog.c,xpressn.c} :
numparam port from ngspice
* src/frontend/subckt.h src/include/fteext.h:
gcc-4 compile fixes
* src/spicelib/analysis/dctran.c:
Stop printing initial DC solution if over 30 nodes
* src/spicelib/devices/bsim4/{.cvsignore,B4TERMS_OF_USE,Makefile.am,
b4.c,b4acld.c,b4ask.c,b4check.c,b4cvtest.c,b4del.c,b4dest.c,b4geo.c,
b4getic.c,b4ld.c,b4mask.c,b4mdel.c,b4mpar.c,b4noi.c,b4par.c,b4pzld.c,
b4set.c,b4temp.c,b4trunc.c,bsim4def.h,bsim4ext.h,bsim4init.c,bsim4itf.h}:
Bsim4 update from ngspice
2005-07-22 Stefan Jones <stefan.jones@multigig.com>
* Changelog:

View File

@ -5,7 +5,7 @@ dnl Create a configuration header
AM_CONFIG_HEADER(config.h)
dnl Initialize automake stuff
AM_INIT_AUTOMAKE(tclspice,0.2.18)
AM_INIT_AUTOMAKE(tclspice,0.2.19)
dnl --enable-ftedebug : enable frontend debug macros
AC_ARG_ENABLE(ftedebug,
@ -68,6 +68,10 @@ dnl exclude readline libs by saying --with-readline=no at configure time.
AC_ARG_WITH(readline,
[ --with-readline[=yes/no] Enable GNU readline support for CLI. Default=yes.])
dnl --enable-numparams: define NUMPARAMS in the code. This is for .param support
AC_ARG_ENABLE(numparam,
[ --enable-numparam Enable numparams library support, experimental *not in standard distribution*])
dnl Enable maintainer commands only if requested
AM_MAINTAINER_MODE
@ -435,6 +439,18 @@ if test "$enable_cluster" = "yes"; then
LIBS="$LIBS -lpthread"
fi
if test "$enable_numparam" = "yes"; then
AC_MSG_RESULT(Numparam library is enabled)
AC_DEFINE(NUMPARAMS)
NUMPARAMDIR="numparam"
NUMPARAMLIB="frontend/numparam/libnumparam.a"
else
NUMPARAMDIR=""
NUMPARAMLIB=""
fi
AC_SUBST(NUMPARAMDIR)
AC_SUBST(NUMPARAMLIB)
dnl ---- Option to include GNU readline support in ngspice CLI ----
if test "$with_readline" != "no" -a \
\( "x$with_tcl" == "x" -o "$with_tcl" == "no" \) ; then
@ -503,6 +519,7 @@ src/spicelib/devices/vcvs/Makefile \
src/spicelib/devices/vsrc/Makefile \
src/spicelib/parser/Makefile \
src/frontend/Makefile \
src/frontend/numparam/Makefile \
src/frontend/help/Makefile \
src/frontend/parser/Makefile \
src/frontend/plotting/Makefile \

View File

@ -77,6 +77,7 @@ ngspice_LDADD = \
spicelib/devices/libdev.a \
@XSPICELIB2@ \
frontend/parser/libparser.a \
@NUMPARAMLIB@ \
frontend/help/libhlp.a \
spicelib/parser/libinp.a \
maths/deriv/libderiv.a \
@ -101,6 +102,7 @@ ngnutmeg_LDADD = \
frontend/libfte.a \
frontend/plotting/libplotting.a \
frontend/parser/libparser.a \
@NUMPARAMLIB@ \
frontend/help/libhlp.a \
maths/cmaths/libcmaths.a \
maths/poly/libpoly.a \

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = plotting help parser
SUBDIRS = plotting help parser @NUMPARAMDIR@
noinst_LIBRARIES = libfte.a

View File

@ -0,0 +1,3 @@
Makefile.in
Makefile
.deps

View File

@ -0,0 +1,16 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = downgrad.txt ngconfig.sh readme.txt nupatest.c washprog.c
noinst_LIBRARIES = libnumparam.a
libnumparam_a_SOURCES = \
spicenum.c \
xpressn.c \
mystring.c \
general.h \
numpaif.h \
numparam.h
INCLUDES = -I$(top_srcdir)/src/include
MAINTAINERCLEANFILES = Makefile.in

View File

@ -0,0 +1,89 @@
! downgrad.txt, Use with 'washprog.c'
! opcodes: x=exclusion, m=macro, w=wordsubst s= general subst
! Macros to keep: Cconst Hi Lo Str Strbig Use ...?
w Proc void
w Begin {
w EndProc ;}
w Func ""
w EndFunc ;}
w If "if ("
w Then ") {"
w Else ";} else {"
w ElsIf ";} else if ("
w EndIf ;}
w While "while ("
w Do ") {"
w Done ;}
w Repeat "do {"
w Until ";} while ( !("
w EndRep ));
w For "for ("
w Switch "switch ("
w CaseOne ") { case"
w Case "; break; } case"
w AndCase ":; case"
w Is :{
w Default "; break;} default: {"
w EndSw ";break;} }"
m Const(1,2) "const short 1 = 2;"
m Record(1) "typedef struct _t1 {"
m RecPtr(1) "typedef struct _t1 *"
m EndRec(1) "} 1;"
m Addr(1) &1
w False 0
w True 1
w Not !
w And &&
w Or ||
w Div /
w Mod %
w Shl <<
w Shr >>
w AND &
w OR |
w XOR \^
w NOT ~
w AT *
m Inc(1) 1++
m Dec(1) 1--
w Null NULL
w Void void
m Table(1) "[1]= {"
w EndTab };
m chr(1) (char)(1)
m Zero(1) (!(1))
m NotZ(1) (1)
w Pointer "void *"
w Pfile "FILE *"
w Char "unsigned char"
w Byte "unsigned char"
w Bool "unsigned char"
w Word "unsigned short"
w Pchar "char *"
w Intern static
w Extern extern
m Tarray(1,2,3) "typedef 2 1[3];"
m Tarray\2(1,2,3,4) "typedef 2 1[3][4];"
m Darray(1,2,3) "2 1[3];"
!m Cconst(1,2) "typedef enum {1 = 2} _n1;"
!m Str(1,2) "char 2[1+03]={00,00,(char)1}"
!m Strbig(1,2) "char 2[1+04]={00, (char)Hi(1), (char)Lo(1)}"
w Aconst(1,2,3) "2 1[3] ={"
w EndAco "};"
m Sini(1) "sini(1,sizeof(1)-04)"
m New(1) "(1 *)new(sizeof(1))"
m Dispose(1) "dispose((void *)1)"
m NewArr(1,2) "(1 *)new(sizeof(1)*2)"

View File

@ -0,0 +1,211 @@
/* general.h */
/*** Part 1: the C language redefined for quiche eaters ****
*
* Real Hackers: undo all these macros with the 'washprog.c' utility !
*/
/* Proc ...... Begin .... EndProc */
#define Proc void
#define Begin {
#define EndProc ;}
/* Func short ...(...) Begin...EndFunc */
#define Func
#define EndFunc ;}
/* If ... Then...ElsIf..Then...Else...EndIf */
#define If if(
#define Then ){
#define Else ;}else{
#define ElsIf ;}else if(
#define EndIf ;}
/* While...Do...Done */
#define While while(
#define Do ){
#define Done ;}
/* Repeat...Until...EndRep */
#define Repeat do{
#define Until ;}while(!(
#define EndRep ));
/* For i=1;i<=10; Inc(i) Do...Done */
#define For for(
/* Switch...CaseOne...Is...Case..Is...Default...EndSw */
#define Switch switch(
#define CaseOne ){ case
#define Case ;break;}case
#define AndCase :; case
#define Is :{
#define Default ;break;}default:{
#define EndSw ;break;}}
#define Record(x) typedef struct _t ## x {
#define RecPtr(x) typedef struct _t ## x *
#define EndRec(x) } x;
#define Addr(x) &x
#define False 0
#define True 1
#define Not !
#define And &&
#define Or ||
#define Div /
#define Mod %
#define Shl <<
#define Shr >>
#define AND &
#define OR |
#define XOR ^
#define NOT ~
#define AT *
#define Inc(p) (p)++
#define Dec(p) (p)--
/* see screened versions below:
#define New(t) (t*)malloc(sizeof(t))
#define Dispose(p) free((void*)p)
*/
#ifdef NULL
#define Null NULL
#else
#define Null (void *)0L
#endif
#define chr(x) (char)(x)
#define Zero(x) (!(x))
#define NotZ(x) (x)
typedef void* Pointer;
#define Type(a,b) typedef b a;
#ifdef _STDIO_H /* somebody pulled stdio */
Type(Pfile, FILE AT)
#else
#ifdef __STDIO_H /* Turbo C */
Type(Pfile, FILE AT)
#else
Type(Pfile, FILE*) /* sjb - was Pointer, now FILE* */
#endif
#endif
Type(Char, unsigned char)
Type(Byte, unsigned char)
#ifndef Bool
Type(Bool, unsigned char)
#endif
Type(Word, unsigned short)
Type(Pchar, char AT)
#define Intern static
#define Extern extern
#define Tarray(a,d,n) typedef d a[n];
#define Tarray2(a,d,n,m) typedef d a[n][m];
#define Darray(a,d,n) d a[n];
#define Const(x,y) const short x=y;
#define Cconst(x,y) typedef enum {x=y} _n ## x;
#define Aconst(a,tp,sze) tp a[sze] ={
#define EndAco };
/* the following require the 'mystring' mini-library */
#define Mcopy(a,b) rawcopy((Pchar)a, (Pchar)b, sizeof(a),sizeof(b))
#define Rcopy(a,b) rawcopy((Pchar)(&a), (Pchar)(&b), sizeof(&a),sizeof(&b))
#define New(tp) (tp *)new(sizeof(tp))
#define Dispose(p) dispose((void *)p)
#define NewArr(t,n) (t *)new(sizeof(t)*n)
/*** Part 2: common 'foolproof' string library ******/
/*
include beforehand the following:
#include <stdio.h> // NULL FILE fopen feof fgets fclose fputs fputc gets
#include <stdlib.h>
the function code is in 'mystring.c' .
*/
#define Use(x) x=0;x=x
#define Uses(s) s=s
#define Usep(x) x=x
#define Hi(x) (((x) Shr 8) AND 0xff)
#define Lo(x) ((x) AND 0xff)
#define Strbig(n,a) char a[n+4]={0, (char)Hi(n), (char)Lo(n)}
#define Str(n,a) char a[n+3]={0,0,(char)n} /* n<255 ! */
#define Sini(s) sini(s,sizeof(s)-4)
Cconst(Maxstr,2004) /* was 255, string maxlen, may be up to 32000 or so */
typedef char string[258];
Cconst(Esc, 27)
Cconst(Tab, 9)
Cconst(Bs, 8)
Cconst(Lf, 10)
Cconst(Cr, 13)
Proc sini( Pchar s, short i);
Proc sfix(Pchar s, short i, short max);
Func short maxlen(Pchar s);
Func Pchar pscopy( Pchar s, Pchar a, short i,short j);
Func Bool scopy( Pchar a, Pchar b);
Func Bool ccopy( Pchar a, char c);
Func Bool sadd( Pchar s, Pchar t);
Func Bool nadd( Pchar s, long n);
Func Bool cadd( Pchar s, char c);
Func Bool sins( Pchar s, Pchar t);
Func Bool cins( Pchar s, char c);
Func short cpos( char c, Pchar s);
Func short spos( Pchar sub, Pchar s);
Func short length(Pchar s);
Func Bool steq(Pchar s, Pchar t);
Func Bool stne(Pchar s, Pchar t);
Func short scompare(Pchar a, Pchar b);
Func short ord(char c);
Func short pred(short i);
Func short succ(short i);
Proc stri(long n, Pchar s);
Proc strif(long n, short f, Pchar s);
Proc strf(double x, short a, short b, Pchar s); /* float -> string */
Func long ival(Pchar s, short *err);
Func double rval(Pchar s, short *err);
Func char upcase(char c);
Func char lowcase(char c);
Func short hi(long w);
Func short lo(long w);
Func Bool odd(long x);
Func Bool alfa(char c);
Func Bool num(char c);
Func Bool alfanum(char c);
Func Pchar stupcase( Pchar s);
/***** primitive input-output ***/
Proc wc(char c);
Proc wln(void);
Proc ws( Pchar s);
Proc wi(long i);
Proc rs( Pchar s);
Func char rc(void);
Func short freadstr(Pfile f, Pchar s, short max);
Func char freadc(Pfile f);
Func long freadi(Pfile f);
Func long np_round(double d); /* sjb to avoid clash with round() in math.h */
Func long np_trunc(double x); /* sjb to avoid clash with trunc() in math.h */
Func double sqr(double x);
Func double absf(double x); /* abs */
Func long absi( long i);
Func double frac(double x);
Func Bool reset(Pfile f);
Func Bool rewrite(Pfile f);
Proc rawcopy(Pointer a, Pointer b, short la, short lb);
Func Pointer new(long sz);
Proc dispose(Pointer p);
Func Pchar newstring(short n);

View File

@ -0,0 +1,886 @@
/* mystring.c Copyright (C) 2002 Georg Post
*
* This file is part of Numparam, see: readme.txt
* Free software under the terms of the GNU Lesser General Public License
* $Id$
*/
#ifdef __TURBOC__
extern unsigned _stklen= 32000; /* Turbo C default was only 4 K */
#endif
#include <stdio.h>
#include <stdlib.h>
/* #include <math.h> -- ceil floor */
#include "config.h"
#ifdef HAS_WINDOWS
#include "wstdio.h"
#endif
#include "general.h"
#define Getmax(s,ls) (((Byte)(s[ls+1])) Shl 8) + (Byte)(s[ls+2])
/***** primitive input-output ***/
Proc wc(char c)
Begin
fputc(c, stdout)
EndProc
Proc wln(void)
Begin wc('\n') EndProc
Proc ws( Pchar s)
Begin
short k=0;
While s[k] !=0 Do
wc(s[k]); Inc(k)
Done
EndProc
Proc wi(long i)
Begin
Str(16,s);
nadd(s,i);
ws(s)
EndProc
Proc rs( Pchar s)
Begin /*basic line input, limit= 80 chars */
short max,i;
char c;
max=maxlen(s);
i=0; sini(s,max);
If max>80 Then max=80 EndIf
Repeat
c=fgetc(stdin);
If (i<max) And (c>=' ') Then
cadd(s,c); Inc(i)
EndIf
Until (c==Cr) Or (c=='\n') EndRep
/* return i */
EndFunc
Func char rc(void)
Begin
short ls;
Str(80,s);
rs(s); ls=length(s);
If ls>0 Then
return s[ls-1]
Else
return 0
EndIf
EndProc
/******* Strings ************
* are 0-terminated char arrays with a 2-byte trailer: max length.
* the string mini-library is "overflow-safe" under these conditions:
* use Str(n,s) macro: define and initialize a string s of maxlen n<255
* use sini() to initialize empty strings; sfix() for non-empty ones.
* the Sini() macro does automatic sizing, for automatic char arrays
* to allocate a string on the heap, use newstring(n).
* use maxlen() and length() to retrieve string max and actual length
* use: cadd, cins, sadd, sins, scopy, pscopy to manipulate them
* never put '\x0' characters inside strings !
*
* the 'killer idea' is the following:
* on string overflow and/or on heap allocation failure, a program
* MUST die.
*/
Intern
Proc stringbug(Pchar op, Pchar s, Pchar t, char c)
/* we brutally stop the program on string overflow */
Begin
char rep=' ';
ws(" STRING overflow ");
ws(op); wln();
ws(" Operand1: ");
ws(s); wln();
If t != Null Then
ws(" Operand2: ");
ws(t); wln();
EndIf
If c != 0 Then
wc('{'); wc(c); wc('}')
EndIf
ws(" [A]bort [I]gnore ? ");
rep=rc();
If upcase(rep)=='A' Then exit(1) EndIf
EndProc
Proc sini(Pchar s, short max) /* suppose s is allocated */
Begin
If max<1 Then
max=1
ElsIf max>Maxstr Then
max=Maxstr
EndIf
s[0]=0;
s[1]= Hi(max); s[2]= Lo(max);
EndProc
Proc sfix(Pchar s, short i, short max)
/* suppose s is allocated and filled with non-zero stuff */
Begin
short j;
If max<1 Then
max=1
ElsIf max>Maxstr Then
max=Maxstr
EndIf
If i>max Then
i=max
ElsIf i<0 Then
i=0
EndIf
s[i]=0;
s[i+1]= Hi(max); s[i+2]= Lo(max);
For j=0;j<i; Inc(j) Do /* eliminate null characters ! */
If s[j]==0 Then s[j]=1 EndIf
Done
EndProc
Intern
Proc inistring(Pchar s, char c, short max)
/* suppose s is allocated. empty it if c is zero ! */
Begin
short i=0;
s[i]=c;
If c!=0 Then
Inc(i); s[i]=0
EndIf
If max<1 Then
max=1
ElsIf max>Maxstr Then
max=Maxstr
EndIf
s[i+1]= Hi(max); s[i+2]= Lo(max);
EndProc
Func short length(Pchar s)
Begin
short lg=0;
While NotZ(s[lg]) Do Inc(lg) Done
return lg
EndFunc
Func short maxlen(Pchar s)
Begin
short ls= length(s);
return Getmax(s,ls)
EndFunc
Func Bool sadd( Pchar s, Pchar t)
Begin
Bool ok;
short i=0, max, ls= length(s);
max= Getmax(s,ls);
While (t[i] !=0) And (ls<max) Do
s[ls]= t[i];
Inc(i); Inc(ls);
Done
s[ls]=0;
s[ls+1]= Hi(max); s[ls+2]= Lo(max);
ok= (t[i]==0); /* end of t is reached */
If Not ok Then
stringbug("sadd",s,t,0)
EndIf
return ok
EndProc
Func Bool cadd( Pchar s, char c)
Begin
short max, ls= length(s);
Bool ok;
max= Getmax(s,ls);
ok= (ls<max);
If ok Then
s[ls+3]= s[ls+2]; s[ls+2]=s[ls+1];
s[ls+1]=0; s[ls]=c
EndIf
If Not ok Then
stringbug("cadd",s, Null,c)
EndIf
return ok
EndProc
Func Bool cins( Pchar s, char c)
Begin
short i, max, ls= length(s);
Bool ok;
max= Getmax(s,ls);
ok= (ls<max);
If ok Then
For i=ls+2; i>=0; Dec(i) Do s[i+1]=s[i] Done;
s[0]=c;
EndIf
If Not ok Then
stringbug("cins",s, Null,c)
EndIf
return ok
EndProc
Func Bool sins( Pchar s, Pchar t)
Begin
short i, max, ls= length(s), lt=length(t);
Bool ok;
max= Getmax(s,ls);
ok= ((ls+lt) < max);
If ok Then
For i=ls+2; i>=0; Dec(i) Do s[i+lt]=s[i] Done;
For i=0; i<lt; Inc(i) Do s[i]=t[i] Done;
EndIf
If Not ok Then
stringbug("sins",s, t,0)
EndIf
return ok
EndProc
Func short cpos(char c, Pchar s)
/* return position of c in s, or 0 if not found.
* BUG, Pascal inherited: first char is at 1, not 0 !
*/
Begin
short i=0;
While (s[i] !=c) And (s[i] !=0) Do Inc(i) Done
If s[i]==c Then
return (i+1)
Else
return 0
EndIf
EndFunc
Func char upcase(char c)
Begin
If (c>='a')And(c<='z') Then
return c+'A'-'a'
Else
return c
EndIf
EndFunc
Func Bool scopy(Pchar s, Pchar t) /* returns success flag */
Begin
Bool ok;
short i,max, ls= length(s);
max= Getmax(s,ls);
i=0;
While (t[i] !=0) And (i<max) Do
s[i]= t[i]; Inc(i);
Done
s[i]=0;
s[i+1]= Hi(max); s[i+2]= Lo(max);
ok= (t[i]==0); /* end of t is reached */
If Not ok Then
stringbug("scopy",s, t,0)
EndIf
return ok
EndProc
Func Bool ccopy(Pchar s, char c) /* returns success flag */
Begin
short max, ls= length(s);
Bool ok=False;
max= Getmax(s,ls);
If max>0 Then
s[0]=c; sfix(s,1,max);
ok=True
EndIf
If Not ok Then
stringbug("ccopy",s, Null,c)
EndIf
return ok
EndProc
Func Pchar pscopy(Pchar s, Pchar t, short start, short leng)
/* partial string copy, with Turbo Pascal convention for "start" */
/* BUG: position count starts at 1, not 0 ! */
Begin
short max= maxlen(s); /* keep it for later */
short stop= length(t);
short i;
Bool ok= (max>=0) And (max<=Maxstr);
If Not ok Then
stringbug("copy target non-init", s, t, 0)
EndIf
If leng>max Then
leng=max; ok=False
EndIf
If start>stop Then /* nothing! */
ok=False;
inistring(s,0,max)
Else
If (start+leng-1)>stop Then
leng = stop-start+1;
ok=False
EndIf
For i=0; i<leng; Inc(i) Do s[i]= t[start+i -1] Done
i=leng; s[i]=0;
s[i+1]= Hi(max); s[i+2]= Lo(max);
EndIf
/* If Not ok Then stringbug("copy",s, t, 0) EndIf */
/* If ok Then return s Else return Null EndIf */
ok=ok;
return s
EndProc
Func short ord(char c)
Begin
return c AND 0xff
EndFunc /* strip high byte */
Func short pred(short i)
Begin
return (--i)
EndFunc
Func short succ(short i)
Begin
return (++i)
EndFunc
Func Bool nadd( Pchar s, long n)
/* append a decimal integer to a string */
Begin
short d[25];
short j,k,ls,len;
char sg; /* the sign */
Bool ok;
k=0;
len=maxlen(s);
If n<0 Then
n= -n; sg='-'
Else
sg='+'
EndIf
While n>0 Do
d[k]=n Mod 10; Inc(k);
n= n Div 10
Done
If k==0 Then
ok=cadd(s,'0')
Else
ls=length(s);
ok= (len-ls)>k;
If ok Then
If sg=='-' Then
s[ls]=sg; Inc(ls)
EndIf
For j=k-1; j>=0; Dec(j) Do
s[ls]=d[j]+'0'; Inc(ls)
Done
sfix(s,ls,len);
EndIf
EndIf
If Not ok Then
stringbug("nadd",s, Null,sg)
EndIf
return ok
EndProc
Proc stri( long n, Pchar s)
/* convert integer to string */
Begin
sini(s, maxlen(s));
nadd(s,n)
EndProc
Proc rawcopy(Pointer a, Pointer b, short la, short lb)
/* dirty binary copy */
Begin
short j,n;
If lb<la Then
n=lb
Else
n=la
EndIf
For j=0; j<n; Inc(j) Do
((Pchar)a)[j]=((Pchar)b)[j]
Done
EndProc
Func short scompare(Pchar a, Pchar b)
Begin
Word j=0;
short k=0;
While (a[j]==b[j]) And (a[j]!=0) And (b[j]!=0) Do Inc(j) Done;
If a[j]<b[j] Then
k= -1
ElsIf a[j]>b[j] Then
k=1
EndIf
return k
EndFunc
Func Bool steq(Pchar a, Pchar b) /* string a==b test */
Begin
Word j=0;
While (a[j]==b[j]) And (a[j]!=0) And (b[j]!=0) Do Inc(j) Done;
return ((a[j]==0) And (b[j]==0)) /* string equality test */
EndFunc
Func Bool stne(Pchar s, Pchar t)
Begin
return scompare(s,t) !=0
EndFunc
Func short hi(long w)
Begin
return (w AND 0xff00) Shr 8
EndFunc
Func short lo(long w)
Begin
return (w AND 0xff)
EndFunc
Func char lowcase(char c)
Begin
If (c>='A')And(c<='Z') Then
return (char)(c-'A' +'a')
Else
return c
EndIf
EndFunc
Func Bool alfa( char c)
Begin
return ((c>='a') And (c<='z')) Or ((c>='A') And (c<='Z'));
EndFunc
Func Bool num( char c)
Begin
return (c>='0') And (c<='9');
EndFunc
Func Bool alfanum(char c)
Begin
return
((c>='a') And (c<='z')) Or ((c>='A')And(c<='Z'))
Or ((c>='0')And(c<='9'))
Or (c=='_')
EndFunc
Func short freadstr(Pfile f, Pchar s, short max)
/* read a line from a file.
BUG: long lines truncated without warning, ctrl chars are dumped.
*/
Begin
char c;
short i=0, mxlen=maxlen(s);
If mxlen<max Then max=mxlen EndIf
Repeat
c=fgetc(f); /* tab is the only control char accepted */
If ((c>=' ') Or (c<0) Or (c==Tab)) And (i<max) Then
s[i]=c; Inc(i)
EndIf
Until feof(f) Or (c=='\n') EndRep
s[i]=0;
s[i+1]= Hi(mxlen); s[i+2]= Lo(mxlen);
return i
EndProc
Func char freadc(Pfile f)
Begin
return fgetc(f)
EndFunc
Func long freadi(Pfile f)
/* reads next integer, but returns 0 if none found. */
Begin
long z=0;
Bool minus=False;
char c;
Repeat c=fgetc(f)
Until feof(f) Or Not ((c>0) And (c<=' ')) EndRep /* skip space */
If c=='-' Then
minus=True; c=fgetc(f)
EndIf
While num(c) Do
z= 10*z + c-'0'; c=fgetc(f)
Done
ungetc(c,f) ; /* re-push character lookahead */
If minus Then z= -z EndIf;
return z
EndFunc
Func Pchar stupcase( Pchar s)
Begin
short i=0;
While s[i] !=0 Do
s[i]= upcase(s[i]); Inc(i)
Done
return s
EndFunc
/***** pointer tricks: app won't use naked malloc(), free() ****/
Proc dispose(Pointer p)
Begin
If p != Null Then free(p) EndIf
EndProc
Func Pointer new(long sz)
Begin
Pointer p;
If sz<=0 Then
return Null
Else
#ifdef __TURBOC__
/* truncate to 64 K ! */
If sz> 0xffff Then sz= 0xffff EndIf
p= malloc((Word)sz);
#else
p= malloc(sz);
#endif
If p==Null Then /* fatal error */
ws(" new() failure. Program halted.\n");
exit(1);
EndIf
return p
EndIf
EndFunc
Func Pchar newstring(short n)
Begin
Pchar s= (Pchar)new(n+4);
sini(s, n);
return s
EndFunc
/***** elementary math *******/
Func double sqr(double x)
Begin
return x*x
EndFunc
Func double absf(double x)
Begin
If x<0.0 Then
return -x
Else
return x
EndIf
EndFunc
Func long absi(long i)
Begin
If i>=0 Then
return(i)
Else
return(-i)
EndIf
EndFunc
Proc strif(long i, short f, Pchar s)
/* formatting like str(i:f,s) in Turbo Pascal */
Begin
short j,k,n,max;
char cs;
char t[32];
k=0;
max=maxlen(s);
If i<0 Then
i= -i; cs='-'
Else
cs=' '
EndIf;
While i>0 Do
j=(short)(i Mod 10);
i=(long)(i Div 10);
t[k]=chr('0'+j); Inc(k)
Done
If k==0 Then
t[k]='0'; Inc(k)
EndIf
If cs=='-' Then
t[k]=cs
Else
Dec(k)
EndIf;
/* now the string is in 0...k in reverse order */
For j=1; j<=k; Inc(j) Do t[k+j]=t[k-j] Done /* mirror image */
t[2*k+1]=0; /* null termination */
n=0;
If (f>k) And (f<40) Then /* reasonable format */
For j=k+2; j<=f; Inc(j) Do
s[n]=' '; Inc(n)
Done
EndIf
For j=0; j<=k+1; Inc(j) Do s[n+j]=t[k+j] Done; /* shift t down */
k=length(s);
sfix(s,k,max);
EndProc
Func Bool odd(long x)
Begin
return NotZ(x AND 1)
EndFunc
Func short vali(Pchar s, long * i)
/* convert s to integer i. returns error code 0 if Ok */
/* BUG: almost identical to ival() with arg/return value swapped ... */
Begin
short k=0, digit=0, ls;
long z=0;
Bool minus=False, ok=True;
char c;
ls=length(s);
Repeat
c=s[k]; Inc(k)
Until (k>=ls) Or Not ((c>0) And (c<=' ')) EndRep /* skip space */
If c=='-' Then
minus=True;
c=s[k]; Inc(k)
EndIf
While num(c) Do
z= 10*z + c-'0';
c=s[k]; Inc(k);
Inc(digit)
Done
If minus Then z= -z EndIf;
*i= z;
ok= (digit>0) And (c==0); /* successful end of string */
If ok Then
return 0
Else
return k /* one beyond error position */
EndIf
EndFunc
Intern
Func Bool match
(Pchar s, Pchar t, short n, short tstart, Bool testcase)
Begin
/* returns 0 If tstart is out of range. But n may be 0 ? */
/* True if s matches t[tstart...tstart+n] */
short i,j,lt;
Bool ok;
char a,b;
i=0; j=tstart;
lt= length(t);
ok=(tstart<lt);
While ok And (i<n) Do
a=s[i]; b=t[j];
If Not testcase Then
a=upcase(a); b=upcase(b)
EndIf
ok= (j<lt) And (a==b);
Inc(i); Inc(j);
Done
return ok
EndFunc
Intern
Func short posi(Pchar sub, Pchar s, short opt)
/* find position of substring in s */
Begin
/* opt=0: like Turbo Pascal */
/* opt=1: like Turbo Pascal Pos, but case insensitive */
/* opt=2: position in space separated wordlist for scanners */
short a,b,k,j;
Bool ok, tstcase;
Str(250,t);
ok=False;
tstcase=( opt==0);
If opt<=1 Then
scopy(t,sub)
Else
cadd(t,' '); sadd(t,sub); cadd(t,' ');
EndIf
a= length(t);
b= (short)(length(s)-a);
k=0; j=1;
If a>0 Then /*Else return 0*/
While (k<=b) And (Not ok) Do
ok=match(t,s, a,k, tstcase); /* we must start at k=0 ! */
Inc(k);
If s[k]==' ' Then Inc(j) EndIf /* word counter */
Done
EndIf
If opt==2 Then k=j EndIf
If ok Then
return k
Else
return 0
EndIf
EndFunc
Func short spos(Pchar sub, Pchar s)
/* equivalent to Turbo Pascal pos().
BUG: counts 1 ... length(s), not from 0 like C
*/
Begin
return posi( sub, s, 0)
EndFunc
/**** float formatting with printf/scanf ******/
Func short valr(Pchar s, double *r)
/* returns 0 if ok, else length of partial string ? */
Begin
short n=sscanf(s, "%lG", r);
If n==1 Then
return(0)
Else
return(1)
EndIf
EndFunc
Proc strf( double x, short f1, short f2, Pchar t)
/* e-format if f2<0, else f2 digits after the point, total width=f1 */
/* if f1=0, also e-format with f2 digits */
Begin /*default f1=17, f2=-1*/
Str(30,fmt);
short n,mlt;
mlt=maxlen(t);
cadd(fmt,'%');
If f1>0 Then
nadd(fmt , f1); /* f1 is the total width */
If f2<0 Then
sadd(fmt,"lE") /* exponent format */
Else
cadd(fmt,'.');
nadd(fmt,f2);
sadd(fmt,"lf")
EndIf
Else
cadd(fmt,'.');
nadd(fmt, absi(f2-6)); /* note the 6 surplus positions */
cadd(fmt,'e');
EndIf
n=sprintf(t, fmt, x);
sfix(t,n, mlt);
EndProc
Func double rval(Pchar s, short *err)
/* returns err=0 if ok, else length of partial string ? */
Begin
double r= 0.0;
short n=sscanf(s, "%lG", &r);
If n==1 Then
(*err)=0
Else
(*err)=1
EndIf
return r;
EndFunc
Func long ival(Pchar s, short *err)
/* value of s as integer string. error code err= 0 if Ok */
Begin
short k=0, digit=0, ls;
long z=0;
Bool minus=False, ok=True;
char c;
ls=length(s);
Repeat
c=s[k]; Inc(k)
Until (k>=ls) Or Not ((c>0) And (c<=' ')) EndRep /* skip space */
If c=='-' Then
minus=True;
c=s[k]; Inc(k)
EndIf
While num(c) Do
z= 10*z + c-'0';
c=s[k]; Inc(k);
Inc(digit)
Done
If minus Then z= -z EndIf;
ok= (digit>0) And (c==0); /* successful end of string */
If ok Then
(*err)= 0
Else
(*err)= k /* one beyond error position */
EndIf
return z
EndFunc
#ifndef _MATH_H
Func long np_round(double x)
/* using <math.h>, it would be simpler: floor(x+0.5) */
Begin
double u;
long z;
short n;
Str(40,s);
u=2e9;
If x>u Then
x=u
ElsIf x< -u Then
x= -u
EndIf
n=sprintf(s,"%-12.0f", x);
s[n]=0;
sscanf(s,"%ld", Addr(z));
return z
EndFunc
Func long np_trunc(double x)
Begin
long n=np_round(x);
If (n>x) And (x>=0.0) Then
Dec(n)
ElsIf (n<x) And (x<0.0) Then
Inc(n)
EndIf
return n
EndFunc
Func double frac(double x)
Begin
return x- np_trunc(x)
EndFunc
Func double intp(double x)
Begin
double u=2e9;
If (x>u) Or (x< -u) Then
return x
Else
return np_trunc(x)
EndIf
EndFunc
#else /* use floor() and ceil() */
Func long np_round(double r)
Begin
return (long)floor(r+0.5)
EndFunc
Func long np_trunc(double r)
Begin
If r>=0.0 Then
return (long)floor(r)
Else
return (long)ceil(r)
EndIf
EndFunc
Func double frac(double x)
Begin
If x>=0.0 Then
return(x - floor(x))
Else
return(x - ceil(x))
EndIf
EndFunc
Func double intp(double x) /* integral part */
Begin
If x>=0.0 Then
return floor(x)
Else
return ceil(x)
EndIf
EndFunc
#endif /* _MATH_H */

View File

@ -0,0 +1,20 @@
#!/bin/sh
# ngconfig.sh
# configure options for ngspice with numparam add-on
# run this in ngspice's top-level directory
# specify your Numparam directory
HACK=/home/post/spice3f5/hack
# over-write the original subckt.c
cp -biv $HACK/ngsubckt.c src/frontend/subckt.c
# my box needs CFLAGS on 1st run, else 'terminal.c' wont find 'termcap.h' ?
CFLAGS=-I/usr/include/ncurses \
LIBS=$HACK/libnupa.a \
./configure --without-x --prefix=/usr/local/ngsp
#### end of sample script ####

View File

@ -0,0 +1,20 @@
/*
* numpaif.h
* external interface to spice frontend subckt.c
* $Id$
*/
#ifndef NUMPAIF_H
#define NUMPAIF_H
#define NUPADECKCOPY 0
#define NUPASUBSTART 1
#define NUPASUBDONE 2
#define NUPAEVALDONE 3
extern char * nupa_copy(char *s, int linenum);
extern int nupa_eval(char *s, int linenum);
extern int nupa_signal(int sig, char *info);
extern void nupa_scan(char * s, int linenum);
#endif /* NUMPAIF_H */

View File

@ -0,0 +1,77 @@
/*
* numparam.h
* $Id$
*/
/*** interface to spice frontend subckt.c ***/
#include "numpaif.h"
/***** numparam internals ********/
#define ln(x) log(x)
#define trunc(x) floor(x)
Cconst(Nul, 0)
Cconst(Nodekey,'#') /*introduces node symbol*/
Cconst(Intro ,'&') /*introduces preprocessor tokens*/
Cconst(Comment,'*') /*Spice Comment lines*/
Cconst(Pspice,'{') /*Pspice expression */
Cconst(Maxdico,200) /*size of symbol table*/
/* Composite line length
This used to be 250 characters, but this is too easy to exceed with a
.model line, especially when spread over several continuation
lines with much white space. I hope 1000 will be enough. */
Cconst(Llen,1000)
typedef char str20 [24];
typedef char str80 [84];
Cconst(Maxline, 1000) /* size of initial unexpanded circuit code */
Cconst(Maxckt, 5000) /* size of expanded circuit code */
typedef Pchar auxtable; /* dummy */
Record(entry)
char tp; /* type: I)nt R)eal S)tring F)unction M)acro P)ointer */
str20 nom;
short level; /* subckt nesting level */
double vl; /* float value if defined */
Word ivl; /*int value or string buffer index*/
Pchar sbbase; /* string buffer base address if any */
EndRec(entry)
Record(fumas) /*function,macro,string*/
Word start /*,stop*/ ; /*buffer index or location */
EndRec(fumas)
Record(tdico)
/* the input scanner data structure */
str80 srcfile; /* last piece of source file name */
short srcline;
short errcount;
entry dat[Maxdico+1];
short nbd; /* number of data entries */
fumas fms[101];
short nfms; /* number of functions & macros */
short stack[20];
short tos; /* top of stack index for symbol mark/release mechanics */
str20 option; /* one-character translator options */
auxtable nodetab;
Darray(refptr, Pchar, Maxline) /* pointers to source code lines */
Darray(category, char, Maxline) /* category of each line */
EndRec(tdico)
Proc initdico(tdico * dico);
Func short donedico(tdico * dico);
Func Bool defsubckt( tdico *dico, Pchar s, Word w, char categ);
Func short findsubckt( tdico *dico, Pchar s, Pchar subname);
Func Bool nupa_substitute( tdico *dico, Pchar s, Pchar r, Bool err);
Func Bool nupa_assignment( tdico *dico, Pchar s, char mode);
Func Bool nupa_subcktcall( tdico *dico, Pchar s, Pchar x, Bool err);
Proc nupa_subcktexit( tdico *dico);
Func tdico * nupa_fetchinstance(void);
Func char getidtype( tdico *d, Pchar s);

View File

@ -0,0 +1,454 @@
/* nupatest.c Copyright (C) 2002 Georg Post
*
* This file is part of Numparam, see: readme.txt
* Free software under the terms of the GNU Lesser General Public License
* $Id$
*/
/**** test executable for the numparam library ****/
/**** usage: nupatest <filename.cir> ****/
#include <stdio.h>
#include "general.h"
#include "numparam.h"
Cconst(pfxsep,'_') /* official prefix separator is ':' not '_' ! */
Darray(buff, Pchar, Maxline) /* input lines */
Darray(buf2, Pchar, Maxline) /* stripped lines */
Darray(pxbuf, Pchar, Maxline) /* prefix for subnodes */
Darray(runbuf, short, Maxckt) /* index list of expanded circuit */
Darray(pindex, short, Maxckt) /* prefix index list */
short irunbuf= 0; /* count lines of runbuf */
short ipx=0; /* count prefixes in pxbuf */
/*
this toy imitates the Spice subcircuit expansion.
To ckeck against Genuine Spice, use the 'listing expand' JDML command
Bug1: model or device call with parameters: incorrectly parsed
needs a database about _optional_ model/device pars...
better: Enter all .model identifiers in the symbol table !
Bug2: nested subckt declarations, local .models: might be dangerous.
expanded circuit lines, device/node names:
any line that starts with a letter (device): splice the prefix in
any node that isnt a formal param: add the prefix
any formal param node: substitute actual params and their prefixes
Node and subdevice references for prefixing:
deviceletter[n] is a device type prefix
nbofnodes [n] is the number of "node-type" arguments that follow.
nbsubdevice [n] is the number of "subdevices" for splice-in prefix.
To solve the Q ambiguity, forbid any model identifiers as node names.
Bug3:
In arbitrary dependent sources, we must parse v(,) and i(,) expressions
and substitute node/device name arguments.
*/
Func short runscript( tdico *dico, Pchar prefix,
short istart, short istop, short maxnest)
/* recursive top-down expansion: circuit --> list of line numbers */
/* keep it simple,stupid compared to Spice's code */
/* prefix: inherited string for node & device prefixing */
/* istart, istop: allowed interval in table buf[], buf2[]. */
/* return value: number of lines included */
Begin
short i,j, idef, nnest, nline, dn, myipx;
Strbig(Llen, subpfx); /* subckt prefix */
Str(80, subname);
char c;
Bool done= False;
i=istart;
nline=0;
Inc(ipx); myipx= ipx; /* local copy */
pxbuf[ipx]= newstring( length(prefix));
scopy( pxbuf[ipx], prefix);
While (maxnest>0) And (i<istop) And (Not done) Do
c= dico->category[i];
If c=='U' Then
done=True; /* subcircuit end. Keep as a comment? */
buf2[i][0]='#';
EndIf
If c=='S' Then /* skip nested subcircuits */
nnest=1;
Repeat
Inc(i); c= dico->category[i];
If c=='S' Then
Inc(nnest)
ElsIf c=='U' Then
Dec(nnest)
EndIf
Until (nnest<=0) Or (i>=istop) EndRep
ElsIf c=='X' Then /* recursion here ! */
runbuf[irunbuf]= i;
pindex[irunbuf]= myipx;
Inc(irunbuf); Inc(nline);
/* keep out-commented X line for parameter passing */
idef = findsubckt( dico, buf2[i], subname);
buf2[i][0]= '*';
If idef>0 Then
scopy(subpfx, prefix);
cadd(subpfx, pfxsep);
j=1; /* add the instance name from buf2[i] */
While buf2[i][j] > ' ' Do
cadd( subpfx, buf2[i][j]); Inc(j)
Done
dn= runscript(dico, subpfx, idef+1, istop, maxnest-1);
nline= nline+dn;
Else /* FIXME: error message here! */
ws("cannot find subckt "); ws(buf2[i]); wln();
EndIf
ElsIf (c != '?') And NotZ(buf2[i][0]) Then
/* keep any other valid non-empty line, and its prefix pointer */
runbuf[irunbuf]= i;
pindex[irunbuf]= myipx;
Inc(irunbuf); Inc(nline);
EndIf
Inc(i);
Done
return nline
EndProc
Proc gluepluslines( short imax)
/* general sweep to eliminate continuation lines */
Begin
short i,j,k, ls, p;
Strbig(Llen,s);
i=1;
While i<= imax Do
If (buff[i][0]=='+') And (i>1) Then
j= i-1;
While (i < imax) And (buff[i+1][0]=='+') Do Inc(i) Done
/* the lines j+1 ... i are continuation lines to j */
For k=j; k<=i; Inc(k) Do
ls=length(s);
sadd(s, buff[k]);
p= spos("//",s);
If p>0 Then pscopy(s,s, 1,p-1) EndIf
If ls>0 Then s[ls]=' ' EndIf /* erase the + */
Done
ls= length(s);
If ls> 80 Then
Dispose(buff[j]);
buff[j]=newstring(ls)
EndIf
scopy(buff[j], s)
EndIf
Inc(i)
Done
EndProc
#if 0 /* sjb - this is in mystring.c */
Proc rs(Pchar s) /* 78 coumn limit */
Begin
short i;
Bool done;
char c;
short max=maxlen(s);
If max>78 Then max=78 EndIf
i=0; done=False;
scopy(s,"");
While Not done Do
c=fgetc(stdin);
If (c>=' ')And(c<='~') And (i<max) Then
cadd(s,c); Inc(i)
EndIf
done= (c==Lf) Or (c==Cr)
Done
EndProc
#endif
Proc fwrites(Pfile f, Pchar s)
Begin
fputs(s,f)
EndProc
Proc fwriteln(Pfile f)
Begin
fputc('\n',f)
EndProc
Intern
Proc freadln(Pfile f, Pchar s, short max)
Begin
short ls;
freadstr(f,s,max);
ls=length(s);
If feof(f) And (ls>0) Then
pscopy(s,s,1,ls-1)
EndIf /* kill EOF character */
EndProc
Proc wordinsert(Pchar s, Pchar w, short i)
/* insert w before s[i] */
Begin
Strbig(Llen,t);
short ls=length(s);
pscopy(t,s,i+1,ls); pscopy(s,s,1,i);
sadd(s,w); sadd(s,t);
EndProc
Func short worddelete(Pchar s, short i)
/* delete word starting at s[i] */
Begin
Strbig(Llen,t);
short ls= length(s);
short j=i;
While (j<ls) And (s[j]>' ') Do Inc(j) Done
pscopy(t,s,j+1,ls);
pscopy(s,s,1,i);
sadd(s,t);
return j-i /* nb of chars deleted */
EndProc
Func short getnextword(Pchar s, Pchar u, short j)
Begin
short ls,k;
ls= length(s);
k=j;
While (j<ls) And (s[j] > ' ') Do Inc(j) Done /* skip current word */
pscopy(u, s, k+1, j-k);
While (j<ls) And (s[j] <= ' ') Do Inc(j) Done
return j
EndFunc
Func short inwordlist(Pchar u, Pchar wl)
/* suppose wl is single-space separated, plus 1 space at start and end. */
Begin
short n,p,k;
Str(80,t);
n=0;
ccopy(t,' '); sadd(t,u); cadd(t,' ');
p= spos(t,wl);
If p>0 Then
For k=0; k<p; Inc(k) Do
If wl[k] <= ' ' Then Inc(n) EndIf
Done
EndIf
return n
EndFunc
Proc takewordlist(Pchar u, short k, Pchar wl)
Begin
short i,j,lwl;
lwl= length(wl);
i=0; j=0;
scopy(u,"");
While (i<lwl) And (j<k ) Do
If wl[i] <= ' ' Then Inc(j) EndIf
Inc(i)
Done
If j==k Then /* word has been found and starts at i */
While wl[i]>' ' Do
cadd(u,wl[i]); Inc(i)
Done
EndIf
EndProc
Pchar deviceletter= "RLCVIBSGETOUWFHDQKJZM";
Pchar nbofnodes = "222222444443222240334";
Pchar nbsubdevice = "000000000000111002000";
Proc prefixing(Pchar s, Pchar p, Pchar formals, Pchar actuals,
char categ, tdico *dic)
/* s is a line in expanded subcircuit.
p is the prefix to be glued anywhere .
assume that everything except first and last word in s may be a node.
formals: node parameter list of a subckt definition line
actuals: substitutes from the last X... call line (commented-out)
subdevices (L belonging to a K line, for example) must be within the
same subckt, they get the same prefix splice-in.
There is a kludge for Q lines (may have 3 or 4 nodes, you never know).
Reminder on Numparam symbols:
naming convention: subckt,model,numparam and node names must be unique.
cannot re-use a model name as a param name elsewhere, for example.
*/
Begin
short i,j,k,ls, jnext, dsize;
short dtype, nodes, subdv;
Bool done;
char leadchar;
Str(80,u); Str(80,v); Str(80,pfx);
i=0; ls=length(s);
While (i<ls) And (s[i]<=' ') Do Inc(i) Done
If alfa(s[i]) Or (categ=='X') Then /* splice in the prefix and nodelist */
wordinsert(s,p, i+1);
j= getnextword(s,u,i);
done=False;
If p[0]== pfxsep Then
pscopy(pfx,p, 2, length(p))
Else
scopy(pfx,p)
EndIf
leadchar=upcase(s[i]);
dtype= cpos( leadchar, deviceletter) -1 ;
If dtype >= 0 Then
nodes= nbofnodes[dtype] - '0';
subdv= nbsubdevice[dtype] - '0';
Else
nodes=999; subdv=0;
EndIf
While Not done Do
jnext= getnextword(s,u,j);
done=(jnext >= length(s)); /* was the last one, do not transform */
/* bug: are there semilocal nodes ? in nested subckt declarations ? */
If (leadchar=='Q') And (Not done) Then /* BJT: watch non-node name */
scopy(v,u); stupcase(v);
done= getidtype(dic, v) == 'O'; /* a model name stops the node list */
EndIf
If (Not done) And (nodes>0) Then /* transform a node name */
k= inwordlist(u, formals);
If (k>0) Then /* parameter node */
dsize= - worddelete(s,j);
takewordlist(u,k, actuals);
wordinsert(s,u,j);
dsize= dsize + length(u);
ElsIf stne(u,"0") Then /* local node */
wordinsert(s,pfx,j);
dsize= length(pfx);
Else dsize=0 EndIf
ElsIf (Not done) And (subdv >0) Then /* splice a subdevice name */
wordinsert(s,p,j+1);
dsize= length(p);
EndIf
j= jnext + dsize; /* jnext did shift ...*/
If nodes >0 Then Dec(nodes)
ElsIf subdv >0 Then Dec(subdv)
EndIf
done= done Or (Zero(nodes) And Zero(subdv));
Done
EndIf
EndProc
Proc getnodelist(Pchar form, Pchar act, Pchar s, tdico *dic, short k)
/* the line s contains the actual node parameters, between 1st & last word */
Begin
short j,ls, idef;
Str(80,u); Strbig(Llen,t);
ccopy(act,' '); ccopy(form,' ');
j=0; ls= length(s);
j= getnextword(s,u,j);
While j<ls Do
j= getnextword(s,u,j);
If j<ls Then sadd(act,u); cadd(act,' ') EndIf
Done
/* now u already holds the subckt name if all is ok ? */
idef = findsubckt( dic, buf2[k], u);
/* line buf2[idef] contains: .subckt name < formal list > */
If idef>0 Then
scopy(t, buf2[idef])
Else
ws("Subckt call error: "); ws(s); wln();
EndIf
j=0; ls= length(t);
j= getnextword(t,u,j);
j= getnextword(t,u,j);
While j<ls Do
j= getnextword(t,u,j);
sadd(form,u); cadd(form,' ');
Done
EndProc
Proc nupa_test(Pchar fname, char mode)
/* debugging circuit expansion run. mode='w': write ouput file */
/* bugs in nupa_eval(), and for nested subckt definitions !?! */
Begin
Pfile tf, fout;
tdico * dic; /* dictionary data pointer */
Strbig(Llen,s);
Str(80, prefix);
/* Strbig(Llen, formals); Strbig(Llen,actuals); */
Darray(formals, Pchar, 10)
Darray(actuals, Pchar, 10)
short i, j, k, nline, parstack;
For i=0; i<Maxline; Inc(i) Do /* allocate string storage */
buff[i]= newstring(80);
buf2[i]= Null;
pxbuf[i]= Null
Done
For i=0; i<10; Inc(i) Do
formals[i]= newstring(250);
actuals[i]= newstring(250);
Done
i=0; parstack=0;
tf=fopen( fname, "r");
If tf != Null Then
While (Not feof(tf)) And ((i+1) < Maxline) Do
Inc(i);
freadln(tf, buff[i], 80); /* original data */
Done
fclose(tf);
Else
ws("Cannot find "); ws(fname); wln();
EndIf
/* continuation lines are glued at this stage, so they can be ignored
in all the subsequent manipulations.
*/
gluepluslines(i); /* must re-allocate certain buff[i] */
nupa_signal(NUPADECKCOPY, fname);
dic= nupa_fetchinstance(); /* bug: should have a task handle as arg */
For j=1; j<=i; Inc(j) Do
buf2[j]= nupa_copy(buff[j], j); /* transformed data */
Done
nupa_signal(NUPASUBDONE, Null);
nline= runscript(dic, "", 1,i, 20); /* our own subckt expansion */
/* putlogfile(' ',nline," expanded lines"); */
If mode=='w' Then
i= cpos('.', fname);
pscopy(s, fname, 1, i);
sadd(s,"out");
fout= fopen(s, "w");
Else
fout= Null
EndIf
For j=0; j<irunbuf; Inc(j) Do
k= runbuf[j];
If buf2[k] != Null Then
scopy(s, buf2[k]);
nupa_eval(s, k);
scopy(prefix,pxbuf[pindex[j]]);
If NotZ(prefix[0]) Then cadd(prefix, pfxsep) EndIf
prefixing(s, prefix, formals[parstack], actuals[parstack],
dic->category[k], dic);
If dic->category[k] == 'X' Then
If parstack< (10-1) Then Inc(parstack) EndIf
getnodelist(formals[parstack], actuals[parstack], s, dic,k);
/*dbg: ws("Form: "); ws(formals[parstack] ); wln(); */
/*dbg: ws("Actu: "); ws(actuals[parstack]); wln(); */
ElsIf dic->category[k]=='U' Then /* return from subckt */
If parstack>0 Then Dec(parstack) EndIf
EndIf
If fout != Null Then
fwrites(fout, s); fwriteln(fout)
EndIf
EndIf
Done
If fout != Null Then fclose(fout) EndIf
nupa_signal(NUPAEVALDONE, Null); /* frees the buff[i] */
For i= 10-1; i>=0; Dec(i) Do
Dispose(actuals[i]);
Dispose(formals[i]);
Done
For i= Maxline -1; i>=0; Dec(i) Do
Dispose(pxbuf[i]);
Dispose(buf2[i]);
/* Dispose(buff[i]) done elsewhere */
Done
EndProc
Func int main(int argc, Pchar argv[])
Begin
Str(80,fname);
If argc>1 Then
scopy(fname, argv[1])
Else
scopy(fname,"testfile.nup")
EndIf
nupa_test(fname, 'w');
return 0
EndFunc

View File

@ -0,0 +1,674 @@
********************************************************
README.TXT the minimal Numparam documentation
********************************************************
Numparam: an add-on library for electronic circuit analysis front-ends
Copyright (C) 2002 Georg Post
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
CONTENTS
A. The Numparam library
B. Circuit description with Numparam (in lieu of a tutorial)
C. Reference section
D. Installation
E. Theory of operation
F. Files in this package
G. Known bugs
A. The Numparam library:
The spice-3f(x) front end lacks some features of commercial derivatives,
such as the ability to define numerical attributes of devices by symbols
or by constant (at circuit-expansion time) numerical expressions.
Numerical parameters - other than node names - for subcircuits are also
commonly available in these non-free Spices.
This library provides a retrofit to the Spice circuit description language
to add these features. By design, the new code is organized as an independent
library which does not import any Spice header files and whose only interface
to Spice is a set of three function headers. The only place where these
functions are called - if a new compile-time option for Spice is set - is
the code file src/lib/fte/subckt.c. There are no patches anywhere else.
The purpose of this minimal coupling was to freely license the additional code.
It is distributed under the GNU-LGPL and thus can be linked to the original
Spice which is open-source software but maintains a special license.
(As I read somewhere, Berkeley Spice is reserved to people friendly to the USA).
Due to GPL-type requirements, I cannot merge any lines from Spice with
the new code, and I cannot avoid redundancies, such as one more symbol table
manager and the umpteenth arithmetic expression parser.
Coding style of my add-on is a bit personal. Using a set of keyword-hiding
macros, it is closer to Pascal and/or Basic than to authentic C programs.
Most of it originated from my initial Turbo Pascal preprocessors that have been
translated to C. After all, I'm definitely not "friendly to the C language".
Even in disguise, the code is pure Ansi-C and compiles without a warning
under the severest settings of gcc (under GNU/Linux) or Turbo C++ (under
MS-DOS). For C hardliners, I include the 'washprog' utility which downgrades
the source code to the common C look-&-feel. Extreme purists might apply
some appropriate "indent" utility, in addition.
B. Circuit description with Numparam (in lieu of a tutorial).
As we now know, all the text entry to Spice comes in two separate languages:
- a circuit description language (CDL) which defines the electronic hardware.
- an analysis job and data management language (JDML) which may be used
as an interactive shell or in batch files.
In the circuit description "CDL" file, the design is typically organized
as a hierarchical set of subcircuits which are connected together in
the 'main' circuit (they are "called", like procedures in a general-purpose
programming language). CDL is line-oriented, with a recognizer role assigned
to the first non-space character of a line.
(In the ancient times of data processing, a line was called a "card".)
For example, '*' introduces comment lines. 'C' places a capacitor
device in the circuit, 'R' a resistor, 'L' an inductor, and so on.
'X' signals the "call" of a subcircuit. Character '+' introduces a continuation
line (the way to split exceedingly long lines into pieces).
A special class of lines that start with a dot '.' have control functions
inside CDL: they do not add physical circuit elements.
For instance, the control pair '.subckt' and '.ends' brackets a subcircuit
definition section in CDL.
In the old days of Spice-2, some of the functions now assigned to JDML were
also inserted as dot cards. You can still insert pieces of JDML inside
a CDL file, as a section enclosed within lines '.control' and '.endc' .
Example CDL file, a netlist of some double T RC-filter:
* First-example
.subckt myfilter in out
Ra in p1 2k
Rb p1 out 2k
C1 p1 0 2nF
Ca in p2 1nF
Cb p2 out 1nF
R1 p2 0 1k
.ends myfilter
X1 input output myfilter
V1 input 0 AC 1V
.end
Let us recall what the Spice "front-end" essentially does to your
circuit-description (CDL) file whenever it is submitted, either at program
start-up or after some interactive JDML commands like 'edit' or 'source'.
First, all the JDML sections in the file are sorted out and kept for
later use (unless the file is pure JDML and thus immediately executed).
Next, the hierarchy of subcircuits is expanded and an internal representation
of the flattened circuit is stored, i.e. a set of CDL lines without any more
'X' and '.subckt' lines. This flat circuit is also known as the "netlist".
Then, the netlist is translated into the internal data structures of Spice,
essentially a sparse matrix of elements indexed by pairs of circuit nodes.
Finally, the mathematical analysis is carried out under the control of JDML,
and output data may be stored, printed, plotted, compared, and so on.
Analyses may be repeated under varying bias/frequency/time... conditions.
But to change the circuit topology, the CDL must be edited and re-compiled.
Numparam-specific features of CDL :
The Numparam library is an enhancement of the Spice front-end which adds
clarity and arithmetic functionality to the circuit description language.
The most wanted feature of a language is to have word-like symbols that
take the place of specific values or objects. The dot-line
.param <identifier> = <expression>
defines such symbols. For example, to describe a triple RC filter
with identical values of components, we do not need to explicitly
repeat constant numbers. The CDL code may go like this:
.param res= 1kohm // numparam allows comment tails like in C++
.param tau= 10ns // we want a time constant
.param cap= tau/res // tau= RC, of course
.subckt triplerc in out
R1 in p1 {res}
C1 p1 0 {cap}
R2 p1 p2 {res}
C2 p2 0 {cap}
R3 p2 out {res}
C3 out 0 {cap}
.ends
As you can see, the use of symbols anywhere in the circuit description
requires the curly braces :
{ <expression> }
This coding style is even more interesting if circuit elements have known
fixed ratios (Butterworth filters and the like) and we only need to
touch one value (a time constant) to tune the circuit.
Only numerical constants such as '30pF' may be used without enclosing
braces. It is the braces that tell our CDL front-end to look up
symbols and to crunch arithmetic expressions inside.
Obviously, it was restrictive that subcircuit definitions could only
accept interface node names as symbolic parameters. With the following
syntax of the .subckt line, we add numerical parameters:
.subckt <ckt-ident> <node> ... params: <id>=<value> <id>=<value> ...
Example, a parameterized filter:
.subckt triplerc2 in out params: res=1kohm cap=50pF
* all the following lines as above.
* the specified default values are always overridden with X lines.
To call variants of such a subcircuit later on, we may write:
X1 in out1 triplerc2 {r1} {c1}
X2 in out2 triplerc2 {2*r1} {c1/2}
X3 in out3 triplerc2 {3*r1} {c1/3}
where the r1 and c1 symbols are defined in .param lines.
So, we can use subcircuits with one or more parameters, the same way
as Spice2 already allowed an area parameter for diodes and transistors.
Here is the first example, rewritten with parameters:
* Param-example
.param amplitude= 1V
.subckt myfilter in out
+ params: rval=100k cval= 100nF
Ra in p1 {2*rval}
Rb p1 out {2*rval}
C1 p1 0 {2*cval}
Ca in p2 {cval}
Cb p2 out {cval}
R1 p2 0 {rval}
.ends myfilter
X1 input output myfilter 1k 1nF
V1 input 0 AC {amplitude}
.end
Note:
Now, there is some possible confusion in Spice because of multiple numerical
expression features. The .param lines and the braces expressions are
evaluated in the front-end, that is, just after the subcircuit expansion.
(Technically, the X lines are kept as comments in the expanded circuit
so that the actual parameters can correctly be substituted ).
So, after the netlist expansion and before the internal data setup, all
number attributes in the circuit are known constants.
However, there are some circuit elements in Spice which accept arithmetic
expressions that are NOT evaluated at this point, but only later during
circuit analysis. These are the arbitrary current and voltage sources.
The syntactic difference is that "compile-time" expressions are
within braces, but "run-time" expressions have no braces.
To make things more complicated, the backend language JDML also accepts
arithmetic/logic expressions that operate on its own scalar or vector data sets.
It would be desirable to have the same expression syntax, operator and function
set, and precedence rules, for the three contexts mentioned above.
In the current Numparam implementation, that goal is not yet achieved...
C. Reference section:
The Numparam add-on supports the following elements in the circuit description
language.
1. '.param' control lines to define symbolic numbers
2. arithmetic expressions in place of any numeric constant
3. formal and actual numeric parameters for subcircuit definition and 'call'.
NOT YET IMPLEMENTED:
To activate the additional functions, put a line near the top of the CDL file:
.option numparam
In the syntax description,
<ident> means an alphanumeric identifier (<20 chars, starting with a letter)
<expr> means an expression, composed of <ident>s, Spice numbers, and operators.
1. The .param line:
Syntax: .param <ident> = <expr> ; <ident> = <expr> ....
This line assigns numerical values to identifiers. More than one assignment
per line is possible using the ';' separator.
The .param lines inside subcircuits are copied per call, like any other line.
All assignments are executed sequentially through the expanded circuit.
Before its first use, a name must have been assigned a value.
2. Brace expressions in cicuit elements:
Syntax: { <expr> }
These are allowed in .model lines and in device lines, wherever only constant
Spice numbers could be used in spice2/3. A Spice number is a floating
point number with an optional scaling suffix, immediately glued to the
numeric tokens (see below).
Warning: {..} cannot be used to 'parameterize' node names or parts of names.
( We are not into obfuscated shell scripting ...)
All identifiers used within an <expr> must have known values at the time
when the line is evaluated, else an error is flagged.
3. Subcircuit parameters:
The syntax of a subcircuit definition header is:
.subckt <ident> node node ... params: <ident>= <value> <ident>=<value>...
node is an integer number or an identifier, for one of the external nodes.
The 'params:' keyword introduces an optional section of the line.
Each <ident> is a formal parameter, and each <value> is either a Spice
number or a brace expression.
Inside the '.subckt' ... '.ends' context, each formal parameter may be
used like any identifier that was defined on a .param control line.
The <value> parts are supposed to be default values of the parameters.
However, in the current version of Numparam, they are not used and each
invocation of the subcircuit must supply the _exact_ number of actual
parameters.
The syntax of a subcircuit call (invocation) is:
X<name> node node ... <ident> <value> <value> ....
Here <name> is the symbolic name given to that instance of the subcircuit,
<ident> is the name of a subcircuit defined beforehand. node node ... is
the list of actual nodes where the subcircuit is connected.
<value> is either a Spice number or a brace expression { <expr> } .
The sequence of <value> items on the X line must exactly match the number
and the order of formal parameters of the subcircuit.
4. Symbol scope
All Subcircuit and Model names are considered global and must be unique.
The .param symbols that are defined outside of any '.subckt' ... '.ends'
section are global. Inside such a section, the pertaining 'params:'
symbols and any .param assignments are considered local: they mask any
global identical names, until the .ends line is encountered.
You cannot reassign to a global number inside a .subckt, a local copy is
created instead. Scope nesting works up to a level of 10. For example,
if the main circuit calls A which has a formal parameter xx, A calls B
which has a param. xx, and B calls C which also has a formal param. xx,
there will be three versions of 'xx' in the symbol table but only the most
local one - belonging to C - is visible.
5. Syntax of expressions <expr> ( optional parts within [ ...] ):
An expression may be one of:
<atom> where <atom> is either a Spice number or an identifier
<unary-operator> <atom>
<function-name> ( <expr> [ , <expr> ...] )
<atom> <binary-operator> <expr>
( <expr> )
As expected, atoms, builtin function calls and stuff within parentheses
are evaluated before the other operators. The operators are evaluated
following a list of precedence close to the one of the C language.
For equal precedence binary ops, evaluation goes left to right.
Operators: Alias Internal symb. Precedence
- - 1 (unary -)
not ! ! 1 (unary not)
** ^ ^ 2 (power)
* * 3 (multiply)
/ / 3 (divide)
mod % % 3 (modulo)
div \ \ 3 (integer divide)
+ + 4 (add)
- - 4 (subtract)
== = 5 (equality)
<> != # 5 (un-equal)
<= L 5 (less or equal)
>= G 5 (greater or equal)
< < 5 (less than)
> > 5 (greater than)
and && & 6 (and)
or || | 7 (or)
The result of logical operators is 1 or 0 , for True or False.
Builtin functions: Internal ref.
defined 0 (returns 1 if symbol is defined, else 0)
sqr 1
sqrt 2
sin 3
cos 4
exp 5
ln 6
arctan 7
abs 8
pwr 9
Scaling suffixes (any decorative alphanum. string may follow ...)
g 1e9
meg 1e6
k 1e3
m 1e-3
u 1e-6
n 1e-9
p 1e-12
f 1e-15
Note: there are intentional redundancies in expression syntax, e.g.
x^y , x**y and pwr(x,y) all have nearly the same result.
6. Reserved words
In addition to the above function names and to the verbose operators
( not and or div mod ), other words are reserved and cannot be used
as parameter names. Historically, they come from a version of Numparam
that was a full-blown macro language. I won't link that one to Spice,
not before somebody proves to me that such a thing could be useful...
and or not div mod if else end while macro funct defined
include for to downto is var
sqr sqrt sin cos exp ln arctan abs pwr
7. Alternative syntax
the & sign is tolerated to provide some 'historical' parameter notation:
& as the first character of a line is equivalent to: .param
Inside a line, the notation &(....) is equivalent to {....}, and
&identifier means the same thing as {identifier} .
This notation exists a bit for the same reason as my macros which wipe
the curly braces out of the C language: entering those signs is a pain in
the neck on IBM French-type keyboards. You hit, among others, a vanishingly
small AltGr key which is squeezed by superfluous buttons that show ugly
office-software logos...
Comments in the style of C++ line trailers (//) are detected and erased.
Warning: this is NOT possible in embedded .control parts of a source
file, these JDML lines are outside of Numparam's scope. DOS-style
carriage returns at line ends are difficult for JDML, too.
D. Installation
There are two versions of Spice on which this library has been tried:
a. a 1997 version spice3f5 that was arranged for Red Hat Linux
b. the version 14 of ngspice (will now be privileged for development)
On my system, the size of libnupa.a is about 47k, so this is the additional
bloat that the spice3 and nutmeg binary programs will accumulate.
( The numparam source tarball weighs in for some 70k )
The common part to build the Numparam library is this:
0. choose any directory you like for Numparam, let's call it $HACK.
1. un-tar the .c and .h files and the rest, in Numparam's directory :
tar xzvf numparam.tgz
2. compile the lib sources with gcc -c -Wall:
gcc -c -ansi -pedantic -Wall spicenum.c nupatest.c xpressn.c mystring.c
3. pre-link together the library part to numparam.o and libnupa.a:
ld -r -o numparam.o spicenum.o xpressn.o mystring.o
ar -rcs libnupa.a spicenum.o xpressn.o mystring.o
4. make the test executable nupatest:
gcc -o nupatest nupatest.o spicenum.o xpressn.o mystring.o -lm
The script file 'mknumpar.sh' does all this (2-4).
5a. Link with the "third version of Spice3f5 for RedHat Linux 2.6" (1997)
do the following in the spice3f5 top-level directory:
1. patch the file src/lib/fte/subckt.c :
cp -biv $HACK/rhsubckt.c src/lib/fte/subckt.c
2. edit src/bin/makeops , to add $HACK/libnupa.a to LIBS and LIBN.
3. ./util/build linux
4. ./util/build linux install
5b. Link procedure for ngspice version 14
I haven't yet a working knowledge of the 'automake/autoconf' system, so I'll
describe the pedestrian hacks to get Numparam in. That's evil; the right way
would need a configuration flag that chooses to make and to link the library.
Only the top level files 'configure.in' and 'Makefile.am' should be revised
to process the numparam option. (?)
Help!
1. replace the file src/frontend/subckt.c with Numparam's patched version :
cp -biv $HACK/ngsubckt.c src/frontend/subckt.c
2. run ./configure with a "LIBS prefix" to include numparam (see below)
3. make
4. make install
Here is one "prefixed" ngspice configure script that works on my system:
#!/bin/sh
# ngconfig.sh
# configure options for ngspice with numparam add-on
# run this in ngspice's top-level directory
# specify your Numparam directory
HACK=/home/post/spice3f5/hack
# over-write the original subckt.c
cp -biv $HACK/ngsubckt.c src/frontend/subckt.c
# my box needs CFLAGS on 1st run, else 'terminal.c' wont find 'termcap.h' ?
CFLAGS=-I/usr/include/ncurses \
LIBS=$HACK/libnupa.a \
./configure --without-x --prefix=/usr/local/ngsp
#### end of sample script ####
E. Theory of operation
Spice's front end does a lot of malloc/free type memory gymnastics and does not
seem to care much about small leaks here and there. Numparam will do some
malloc'ing in place of Spice (essentially the translated strings of the input
deck) and rely on Spice to clean it up - or not - later on. My library will
clean up its private space only (the symbol tables) and will make some
assumptions about the interface function calls coming from Spice.
Here is the scenario supposed to be followed by Spice and Numparam:
0. the patched codefile subckt.c imports the following header lines:
#define NUPADECKCOPY 0
#define NUPASUBSTART 1
#define NUPASUBDONE 2
#define NUPAEVALDONE 3
extern char * nupa_copy(char *s, int linenum);
extern int nupa_eval(char *s, int linenum);
extern int nupa_signal(int sig);
These are the three library functions called, i.e.
- nupa_copy by inp_subcktexpand to preprocess all extended-syntax lines.
- nupa_eval by inp_subcktexpand to do the parameter substitutions
- nupa_signal with one of the 4 signals, from various places to
send state information to the Numparam library.
The only places with numparam patches are the functions
inp_subcktexpand() and its recursive subroutine doit(), in the
file subckt.c . At this stage, we suppose that:
- any .control sections are filtered out
- any .include are expanded
- any + continuation line chunks are glued together
1. In the first phase, Numparam runs through the deck (whose .control sections
have already been removed by Spice) to create copies of the lines
without the extended syntax. Pointers to the original deck lines are kept
and the copies are traditional Spice, with placeholders for
symbols and expressions. Spice loses the originals and gets the bleached-out
copies.
2. The "doit()" circuit expansions are modified to keep more information.
Contrary to the initial Spice code, now the subcircuit invocation
lines are preserved as comments, which allows Numparam to update
symbolic subcircuit parameters a bit later. Subcircuit exit lines are also
copied and out-commented, to keep track of identifier scopes during
the final pass.
If this seems waste of storage, just consider all those sloppy memory
leaks in the circuit expansion code...
3. The final wash-up is a sequential call to the library (nupa_eval())
line-by-line through the expanded circuit. By using its pointers
to the original lines, Numparam recovers the added syntax features.
It triggers all the symbol value computations and inserts constant
numbers into the circuit definition lines, whose length must not change!
This option is a kludge to avoid memory reallocation [ my intuitive
fear is that these free() malloc() realloc() and friends swallow a lot of
CPU time ? ].
4. The termination signal at the end of inp_subcktexpand() tells the Numparam
library to clean up its mess, release its pointers to the original
Spice circuit description text, and to get prepared for another run.
Note: Numparam frees the storage related to the original lines
whose pointers have been stolen in phase 1.
In a future release, Numparam will be re-entrant, all its 'global' data being
referenced via a handle which the client program should keep around.
F. Files in this package
The following Ansi C code files belong to Numparam:
general.h header file with macros to disguise the C language.
stuff for an 'overflow-safe' string library ( whose biggest bug
is that it indexes strings from 1 like Pascal).
numparam.h header file for numparam-specific symbols and functions
mystring.c collection of 'safer' character string (and misc.) functions.
beware of the nasty Turbo Pascal conventions.
xpressn.c the interpreter of arithmetic/logical expressions
spicenum.c the interface part, functions that are called by Spice.
nupatest.c a stand-alone subcircuit expander, for test purpose.
washprog.c a program that washes all the above C files, including itself,
to recover the crude syntax of the True Language (see below).
Patched versions of spice's subckt.c file incorporate the library calls
and maybe try to repair some memory leaks (in rhsubckt.c, not yet tested).
rhsubckt.c for spice3f5 1997 Red Hat (src/lib/fte/subckt.c)
ngsubckt.c for ngspice version 14 (src/frontend/subckt.c)
subckt.dif 'diff' between ngsubckt.c and ngspice frontend/subckt.c
The following text, data and script files are also included:
readme.txt this documentation file
downgrad.txt the substitution rules required for washprog.c
mknumpar.sh script to make the library binaries
ngconfig.sh sample script to run ./configure for ngspice
configure.in crappy ?
Makefile.am crappy ?
testfile.nup a test text (nonsense circuit) for Numparam ?
So, if you are a Real Programmer, think that the Pascal amateurs confound
programming with writing novels, and find those Basic greenhorns' style
too childish, then execute the following two-liner first of all
(should work on GNU/Linux, but it's not a speed monster) :
gcc -o washprog washprog.c mystring.c
./washprog *.c
You get all the *.c files in a version where the first character becomes an
underbar, and the interior resembles to _code_. (although it lacks such
powerful features as continue, break, goto, ?:-expressions, gets(), ... )
G. Known Bugs
First of all, lots of size limits - incompatible with the Spirit of the
Gnu, who wants that everything may grow as much as malloc() can grab ...
- circuit source code line length: 80 chars
- circuit '+' extended code lines: 250 chars
- number of source lines: 1000
- number of lines in expanded circuit: 5000
- length of numparam identifiers: 20 chars
- number of numparam identifiers: 200
- length of file names: 80 chars
- significant digits in param results: 5
- nesting depth of parentheses 9
- nesting of subckt calls 10
All these constants should be in the header file but aren't.
After each circuit expansion, numparam asks a silly question
of the "Abort/Continue" type. A debugging feature, to be killed soon.
The Numparam symbol table accumulates the following sets of names:
subcircuits, models, global parameters, subcircuit arguments.
Node names, however, are completely ignored.
Call the following "bugs" or "features":
- A model/subckt name cannot be defined twice, even if local to a subcircuit.
- The same name cannot design a model here, and a parameter elsewhere.
- A subcircuit argument masks any global parameter of same name,
anytime the subckt is invoked. Inside a .subckt context, .param assignments
also have local scope and override global identical names.
It is wise to always use unique names for everything.
While Numparam is in 'early beta stage', I strongly suggest to use
'nupatest' first, on any 'parameterized' Spice circuit file,
before starting the enhanced circuit analyser.
The command
nupatest foobar.cir
produces an output file 'foobar.out' which is the expanded and
parameter-reduced flat netlist.
By the way, it produces error messages whenever it chokes on the source file.
If nupatest succeeds, the spice+numparam combo should swallow it, too.
Big bug: Nupatest does not yet prefix and infix things inside v() and i().
Numparam comes with two very experimental files 'configure.in' and
'Makefile.am' as an exercise of the automake/autoconf mechanisms.
I certainly got a lot of things wrong and had to do _eight_ steps to
have it kind of work:
1. edit/create configure.in
2. edit/create Makefile.am
3. run autoheader --> config.h.in
4. run automake --foreign --add-missing --verbose --> Makefile.in
5. run aclocal --> aclocal.m4
6. run autoconf --> configure
7. run ./configure --> Makefile config.h
8. run make
Do we need all this, and -worse- do we need to repeat it whenever we touch
'configure.in' and/or 'Makefile.am' ? Help!
Please send your bug reports, improvements, flames etc. to the author:
georg.post @ wanadoo.fr

View File

@ -0,0 +1,581 @@
/* spicenum.c Copyright (C) 2002 Georg Post
*
* This file is part of Numparam, see: readme.txt
* Free software under the terms of the GNU Lesser General Public License
*/
/* number parameter add-on for Spice.
to link with mystring.o, xpressn.o (math formula interpreter),
and with Spice frontend src/lib/fte.a .
Interface function nupa_signal to tell us about automaton states.
Buglist (some are 'features'):
blank lines get category '*'
inserts conditional blanks before or after braces
between .control and .endc, flags all lines as 'category C', dont touch.
there are reserved magic numbers (1e9 + n) as placeholders
control lines must not contain {} .
ignores the '.option numparam' line planned to trigger the actions
operation of .include certainly doesnt work
there are frozen maxima for source and expanded circuit size.
Todo:
add support for nested .if .elsif .else .endif controls.
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef __TURBOC__
#include <process.h> /* exit() */
#endif
#include "general.h"
#include "numparam.h"
/* Uncomment this line to allow debug tracing */
/* #define TRACE_NUMPARAMS */
/* the nupa_signal arguments sent from Spice:
sig=1: Start of the subckt expansion.
sig=2: Stop of the subckt expansion.
sig=3: Stop of the evaluation phase.
sig=0: Start of a deck copy operation
After sig=1 until sig=2, nupa_copy does no transformations.
At sig=2, we prepare for nupa_eval loop.
After sig=3, we assume the initial state (clean).
In Clean state, a lot of deckcopy operations come in and we
overwrite any line pointers, or we start a new set after each sig=0 ?
Anyway, we neutralize all & and .param lines (category[] array!)
and we substitute all {} &() and &id placeholders by dummy numbers.
The placeholders are long integers 1000000000+n (10 digits, n small).
*/
/********** string handling ***********/
#define PlaceHold 1000000000L
Intern long placeholder= 0;
#ifdef NOT_REQUIRED /* SJB - not required as front-end now does stripping */
Intern
Func short stripcomment( Pchar s)
/* allow end-of-line comments in Spice, like C++ */
Begin
short i,ls;
char c,d;
Bool stop;
ls=length(s);
c=' '; i=0; stop=False;
While (i<ls) And Not stop Do
d=c;
Inc(i); c=s[i-1];
stop=(c==d) And ((c=='/')Or(c=='-')); /* comments after // or -- */
Done
If stop Then
i=i-2; /*last valid character before Comment */
While (i>0)And (s[i-1]<=' ') Do Dec(i) Done; /*strip blank space*/
If i<=0 Then
scopy(s,"")
Else
pscopy(s,s,1,i)
EndIf
Else
i= -1
EndIf
return i /* i>=0 if comment stripped at that position */
EndFunc
#endif /* NOT_REQUIRED */
Intern
Proc stripsomespace(Pchar s, Bool incontrol)
Begin
/* iff s starts with one of some markers, strip leading space */
Str(12,markers);
short i,ls;
scopy(markers,"*.&+#$");
If Not incontrol Then
sadd(markers,"xX")
EndIf
ls=length(s); i=0;
While (i<ls) And (s[i]<=' ') Do Inc(i) Done
If (i>0) And (i<ls) And (cpos(s[i],markers) >0) Then
pscopy(s,s,i+1,ls)
EndIf
EndProc
#if 0 /* unused? */
Proc partition(Pchar t)
/* t is a list val=expr val=expr .... Insert Lf-& before any val= */
/* the Basic preprocessor doesnt understand multiple cmd/line */
/* bug: strip trailing spaces */
Begin
Strbig(Llen,u);
short i,lt,state;
char c;
cadd(u,Intro);
state=0; /* a trivial 3-state machine */
lt=length(t);
While t[lt-1] <= ' ' Do Dec(lt) Done
For i=0; i<lt; Inc(i) Do
c=t[i];
If c=='=' Then
state=1
ElsIf (state==1) And (c==' ') Then
state=2
EndIf
If state==2 Then
cadd(u,Lf); cadd(u,Intro);
state=0
EndIf
cadd(u,c)
Done
scopy(t,u);
For i=0; i<length(t); Inc(i) Do /* kill braces inside */
If (t[i]=='{') Or (t[i]=='}') Then
t[i]=' '
EndIf
Done
EndProc
#endif
Intern
Func short stripbraces( Pchar s)
/* puts the funny placeholders. returns the number of {...} substitutions */
Begin
short n,i,nest,ls,j;
Strbig(Llen,t);
n=0; ls=length(s);
i=0;
While i<ls Do
If s[i]=='{' Then /* something to strip */
j= i+1; nest=1;
Inc(n);
While (nest>0) And (j<ls) Do
If s[j]=='{' Then
Inc(nest)
ElsIf s[j]=='}' Then
Dec(nest)
EndIf
Inc(j)
Done
pscopy(t,s,1,i);
Inc(placeholder);
If t[i-1]>' ' Then cadd(t,' ') EndIf
nadd(t, PlaceHold + placeholder);
If s[j]>=' ' Then cadd(t,' ') EndIf
i=length(t);
pscopy(s,s, j+1, ls);
sadd(t,s);
scopy(s,t);
Else
Inc(i)
EndIf
ls=length(s)
Done
return n
EndFunc
Intern
Func short findsubname(tdico * dico, Pchar s)
/* truncate the parameterized subckt call to regular old Spice */
/* scan a string from the end, skipping non-idents and {expressions} */
/* then truncate s after the last subckt(?) identifier */
Begin
Str(80, name);
short h,j,k,nest,ls;
Bool found;
h=0;
ls=length(s);
k=ls; found=False;
While (k>=0) And (Not found) Do /* skip space, then non-space */
While (k>=0) And (s[k]<=' ') Do Dec(k) Done;
h=k+1; /* at h: space */
While (k>=0) And (s[k]>' ') Do
If s[k]=='}' Then
nest=1;
Dec(k);
While (nest>0) And (k>=0) Do
If s[k]=='{' Then
Dec(nest)
ElsIf s[k]=='}' Then
Inc(nest)
EndIf
Dec(k)
Done
h=k+1; /* h points to '{' */
Else
Dec(k)
EndIf;
Done
found = (k>=0) And alfa(s[k+1]); /* suppose an identifier */
If found Then /* check for known subckt name */
scopy(name,""); j= k+1;
While alfanum(s[j]) Do
cadd(name, upcase(s[j])); Inc(j)
Done
found= (getidtype(dico, name) == 'U');
EndIf
Done
If found And (h<ls) Then
pscopy(s,s,1,h)
EndIf
return h;
EndFunc
Intern
Proc modernizeex( Pchar s)
/* old style expressions &(..) and &id --> new style with braces. */
Begin
Strbig(Llen,t);
short i,state, ls;
char c,d;
i=0; state=0;
ls= length(s);
While i<ls Do
c= s[i]; d=s[i+1];
If Zero(state) And (c==Intro) And (i>0) Then
If d=='(' Then
state=1; Inc(i); c='{'
ElsIf alfa(d) Then
cadd(t,'{'); Inc(i);
While alfanum(s[i]) Do
cadd(t,s[i]); Inc(i)
Done
c='}'; Dec(i);
EndIf
ElsIf NotZ(state) Then
If c=='(' Then
Inc(state)
ElsIf c==')' Then
Dec(state)
EndIf
If Zero(state) Then /* replace ) by terminator */
c='}';
EndIf
EndIf
cadd(t,c);
Inc(i)
Done
scopy(s,t);
EndProc
Intern
Func char transform(tdico * dico, Pchar s, Bool nostripping, Pchar u)
/* line s is categorized and crippled down to basic Spice
* returns in u control word following dot, if any
*
* any + line is copied as-is.
* any & or .param line is commented-out.
* any .subckt line has params section stripped off
* any X line loses its arguments after sub-circuit name
* any &id or &() or {} inside line gets a 10-digit substitute.
*
* strip the new syntax off the codeline s, and
* return the line category as follows:
* '*' comment line
* '+' continuation line
* ' ' other untouched netlist or command line
* 'P' parameter line, commented-out; (name,linenr)-> symbol table.
* 'S' subckt entry line, stripped; (name,linenr)-> symbol table.
* 'U' subckt exit line
* 'X' subckt call line, stripped
* 'C' control entry line
* 'E' control exit line
* '.' any other dot line
* 'B' netlist (or .model ?) line that had Braces killed
*/
Begin
Strbig(Llen,t);
char category;
short i,k, a,n;
/* i=stripcomment(s); sjb - not required now that front-end does stripping */
stripsomespace(s, nostripping);
modernizeex(s); /* required for stripbraces count */
scopy(u,"");
If s[0]=='.' Then /* check Pspice parameter format */
scopy(t,s);
stupcase(t);
k=1;
While t[k]>' ' Do
cadd(u, t[k]); Inc(k)
Done
If spos(".PARAM",t) ==1 Then /* comment it out */
s[0]='*';
category='P';
ElsIf spos(".SUBCKT",t) ==1 Then /* split off any "params" tail */
a= spos("PARAMS:",t);
If a>0 Then
pscopy(s,s,1,a-1);
EndIf
category='S';
ElsIf spos(".CONTROL",t) ==1 Then
category='C'
ElsIf spos(".ENDC",t) ==1 Then
category='E'
ElsIf spos(".ENDS",t) ==1 Then
category='U'
Else
category='.';
n= stripbraces(s);
If n>0 Then category='B' EndIf /* priority category ! */
EndIf
ElsIf s[0]==Intro Then /* private style preprocessor line */
s[0]='*';
category='P';
ElsIf upcase(s[0])=='X' Then /* strip actual parameters */
i=findsubname(dico, s); /* i= index following last identifier in s */
/* pscopy(s,s,1,i); sjb - this is already done by findsubname() */
category='X'
ElsIf s[0]=='+' Then /* continuation line */
category='+'
ElsIf cpos(s[0],"*$#")<=0 Then /* not a comment line! */
n= stripbraces(s);
If n>0 Then
category='B' /* line that uses braces */
Else
category=' '
EndIf; /* ordinary code line*/
Else
category='*'
EndIf
return category
EndFunc
/************ core of numparam **************/
/* some day, all these nasty globals will go into the tdico structure
and everything will get hidden behind some "handle" ...
*/
Intern int linecount= 0; /* global: number of lines received via nupa_copy */
Intern int evalcount= 0; /* number of lines through nupa_eval() */
Intern int nblog=0; /* serial number of (debug) logfile */
Intern Bool inexpansion= False; /* flag subckt expansion phase */
Intern Bool incontrol= False; /* flag control code sections */
Intern Bool dologfile= True; /* for debugging */
Intern Bool firstsignal=True;
Intern Pfile logfile= Null;
Intern tdico * dico=Null;
/* already part of dico : */
/* Str(80, srcfile); source file */
/* Darray(refptr, Pchar, Maxline) pointers to source code lines */
/* Darray(category, char, Maxline) category of each line */
/*
Open ouput to a log file.
takes no action if logging is disabled.
Open the log if not already open.
*/
Intern
Proc putlogfile(char c, int num, Pchar t)
Begin
Strbig(Llen, u);
Str(20,fname);
If dologfile Then
If(logfile == Null) Then
scopy(fname,"logfile.");
Inc(nblog); nadd(fname,nblog);
logfile=fopen(fname, "w");
EndIf
If(logfile != Null) Then
cadd(u,c); nadd(u,num);
cadd(u,':'); cadd(u,' ');
sadd(u,t); cadd(u,'\n');
fputs(u,logfile);
EndIf
EndIf
EndProc
Intern
Proc nupa_init( Pchar srcfile)
Begin
short i;
/* init the symbol table and so on, before the first nupa_copy. */
evalcount=0;
linecount= 0;
incontrol=False;
placeholder= 0;
dico= New(tdico);
initdico(dico);
For i=0; i<Maxline; Inc(i) Do
dico->refptr[i]= Null;
dico->category[i]='?';
Done
Sini(dico->srcfile);
If srcfile != Null Then scopy(dico->srcfile, srcfile) EndIf
EndProc
Intern
Proc nupa_done(void)
Begin
short i;
Str(80,rep);
short dictsize, nerrors;
If logfile != Null Then
fclose(logfile);
logfile=Null;
EndIf
nerrors= dico->errcount;
dictsize= donedico(dico);
For i=Maxline-1; i>=0; Dec(i) Do
Dispose( dico->refptr[i])
Done
Dispose(dico);
dico= Null;
If NotZ(nerrors) Then
/* debug: ask if spice run really wanted */
scopy(rep," Copies="); nadd(rep,linecount);
sadd(rep," Evals="); nadd(rep,evalcount);
sadd(rep," Placeholders="); nadd(rep,placeholder);
sadd(rep," Symbols="); nadd(rep,dictsize);
sadd(rep," Errors="); nadd(rep,nerrors);
cadd(rep,'\n'); ws(rep);
ws("Numparam expansion errors: Run Spice anyway? y/n ? \n");
rs(rep);
If upcase(rep[0]) != 'Y' Then exit(-1) EndIf
EndIf
linecount= 0;
evalcount= 0;
placeholder= 0;
/* release symbol table data */
EndProc
/* SJB - Scan the line for subcircuits */
Proc nupa_scan(Pchar s, int linenum)
Begin
If spos(".SUBCKT",s) ==1 Then
defsubckt( dico, s, linenum, 'U' );
EndIf
EndProc
Func Pchar nupa_copy(Pchar s, int linenum)
/* returns a copy (not quite) of s in freshly allocated memory.
linenum, for info only, is the source line number.
origin pointer s is kept, memory is freed later in nupa_done.
must abort all Spice if malloc() fails.
Is called for the first time sequentially for all spice deck lines.
Is then called again for all X invocation lines, top-down for
subckts defined at the outer level, but bottom-up for local
subcircuit expansion, but has no effect in that phase.
we steal a copy of the source line pointer.
- comment-out a .param or & line
- substitute placeholders for all {..} --> 10-digit numeric values.
*/
Begin
Strbig(Llen,u);
Strbig(Llen,keywd);
Pchar t;
short i,ls;
char c,d;
ls= length(s);
While (ls>0) And (s[ls-1]<=' ') Do Dec(ls) Done
pscopy(u,s, 1,ls); /* strip trailing space, CrLf and so on */
dico->srcline= linenum;
If (Not inexpansion) And (linenum >=0) And (linenum<Maxline) Then
Inc(linecount);
dico->refptr[linenum]= s;
c= transform(dico, u, incontrol, keywd);
If c=='C' Then
incontrol=True
ElsIf c=='E' Then
incontrol=False
EndIf
If incontrol Then c='C' EndIf /* force it */
d= dico->category[linenum]; /* warning if already some strategic line! */
If (d=='P') Or (d=='S') Or (d=='X') Then
fputs(" Numparam warning: overwriting P,S or X line.\n",stderr);
EndIf
If c=='S' Then
defsubckt( dico, s, linenum, 'U' )
ElsIf steq(keywd,"MODEL") Then
defsubckt( dico, s, linenum, 'O' )
EndIf; /* feed symbol table */
dico->category[linenum]= c;
EndIf /* keep a local copy and mangle the string */
ls=length(u);
t= NewArr( char, ls+1); /* == (Pchar)malloc(ls+1); */
If t==NULL Then
fputs("Fatal: String malloc crash in nupa_copy()\n", stderr);
exit(-1)
Else
For i=0;i<=ls; Inc(i) Do
t[i]=u[i]
Done
If Not inexpansion Then
putlogfile(dico->category[linenum],linenum,t)
EndIf;
EndIf
return t
EndFunc
Func int nupa_eval(Pchar s, int linenum)
/* s points to a partially transformed line.
compute variables if linenum points to a & or .param line.
If the original is an X line, compute actual params.
Else substitute any &(expr) with the current values.
All the X lines are preserved (commented out) in the expanded circuit.
*/
Begin
short idef; /* subckt definition line */
char c;
Str(80,subname);
dico->srcline= linenum;
c= dico->category[linenum];
#ifdef TRACE_NUMPARAMS
printf("** SJB - in nupa_eval()\n");
printf("** SJB - processing line %3d: %s\n",linenum,s);
printf("** SJB - category '%c'\n",c);
#endif /* TRACE_NUMPARAMS */
If c=='P' Then /* evaluate parameters */
nupa_assignment( dico, dico->refptr[linenum] , 'N');
ElsIf c=='B' Then /* substitute braces line */
nupa_substitute( dico, dico->refptr[linenum], s, False);
ElsIf c=='X' Then /* compute args of subcircuit, if required */
idef = findsubckt( dico, s, subname);
If idef>0 Then
nupa_subcktcall( dico,
dico->refptr[idef], dico->refptr[linenum], False);
Else
putlogfile('?',linenum, " illegal subckt call.");
EndIf
ElsIf c=='U' Then /* release local symbols = parameters */
nupa_subcktexit( dico);
EndIf
putlogfile('e',linenum,s);
Inc(evalcount);
#ifdef TRACE_NUMPARAMS
ws("** SJB - --> "); ws(s); wln();
ws("** SJB - leaving nupa_eval()"); wln(); wln();
#endif /* TRACE_NUMPARAMS */
return 1
EndFunc
Func int nupa_signal(int sig, Pchar info)
/* warning: deckcopy may come inside a recursion ! substart no! */
/* info is context-dependent string data */
Begin
putlogfile('!',sig, " Nupa Signal");
If sig == NUPADECKCOPY Then
If firstsignal Then
nupa_init(info);
firstsignal=False;
EndIf
ElsIf sig == NUPASUBSTART Then
inexpansion=True
ElsIf sig == NUPASUBDONE Then
inexpansion=False
ElsIf sig == NUPAEVALDONE Then
nupa_done();
firstsignal=True
EndIf
return 1
EndFunc
#ifdef USING_NUPATEST
/* This is use only by the nupatest program */
Func tdico * nupa_fetchinstance(void)
Begin
return dico
EndFunc
#endif /* USING_NUPATEST */

View File

@ -0,0 +1,996 @@
/* washprog.c Copyright (C) 2002 Georg Post
*
* This file is part of Numparam, see: readme.txt
* Free software under the terms of the GNU Lesser General Public License
*/
/**** washprog: trivial text substitution utility. ****/
/* history: this was an exercise to make an 'intersection' language
of C and Java, that would look like Basic. A complete failure, of course.
Now only used to clean my Basic/Pascal-contaminated C code.
With the rules file below, it destroys all those macros of mine for
quiche eaters, which seem offensive to C aficionados.
Standard rules file needed : downgrad.txt
Typical command line: ./washprog -r downgrad washprog.c
There is no printf. Console Output/Input primitives are as follows:
wc ws wr wn wi wln rln
The bare-bones string(=Pchar) manipulation library is this:
pscopy streq str length upcase scopy sadd saddn cadd pos
Format of substitution rules:
s <string> <string> substitute. use "" around string if spaces inside.
w <string> <string> first string must be a whole word only
m <macro1> <macro2> macro substitution with args 1 2 3 ...
u <macro1> <macro2> macro with atomic args, no punctuation "(;,:)" inside.
x <strng1> <strng2> exclude text section from strng1 to strng2.
a <mac1> <mac2> dynamically add a new macro rule, if table space left.
string: may contain special chars: ^A ... ^Z \n \"
macro1: string with "placeholders" 1 2 ... 9, in this order
macro2: may contain the "arguments" anywhere
non-arg digits in macro2 are prefixed 0
Heavy use of 3 string operations:
- pscopy() substring extraction.
- comparison: match().
- spos() substring search
added : special postprocessing for C to place the ; and } :
1. any ';' following a ';' or '}' is wiped out.
2. any ';' preceding a '}' is wiped out.
3. any remaining ';' on start of line is shifted to end of preceding one.
*/
#include <stdio.h> /* NULL FILE fopen feof fgets fclose fputs fputc gets */
#include "general.h"
Cconst(nsub, 100+1) /*max nbr of substitution rules */
Cconst(nargs, 11) /*max number of macro args + 1*/
Cconst(wild,'æ') /* wildcard character in patterns */
Cconst(joker,1) /* one-character placeholder */
Cconst( Recursion, True) /* 20 % slower, re-substitute inside macro args */
Tarray(macargs, string, nargs) /* 0..9 macro copy args, 10: a wildcard */
/* global vars */
short isr; /* nb of substitution rules */
Bool cMode; /* a scanning options: c language mode */
short lookmax; /* input lookahead max size */
Pfile fout; /* file filled by: echoOut macroOut translate traduire */
Tarray(str40, char, 44)
Tarray(str80, char, 84)
Darray(search, str40, nsub)
Darray(replace, str80, nsub)
Str(nsub, srule);
Str(nsub, wildcard);
/********* trivial io ***/
Proc wsf( Pchar s, short fmt)
Begin
short k;
For k=1; k<=fmt-length(s); Inc(k) Do
wc(' ')
Done
ws(s)
EndProc
Proc wcf(char c, short fmt)
Begin
short k;
For k=1; k<=fmt-1; Inc(k) Do
wc(' ')
Done
wc(c)
EndProc
Proc wif(long i, short fmt)
Begin /*default fmt=1*/
Str(30, s);
nadd(s,i);
wsf(s,fmt)
EndProc
Proc rln(Pchar s) /* 78 column limit */
Begin
short i; Bool done; char c;
short max=maxlen(s);
If max>78 Then max=78 EndIf
i=0; done=False;
scopy(s,"");
While Not done Do
c=fgetc(stdin);
If (c>=' ') And (c<='~') And (i<max) Then
cadd(s,c); Inc(i)
EndIf
done= (c=='\n') Or (c==Cr)
Done
EndProc
/*****************/
Proc saddn( Pchar s, Pchar t, short n)
Begin
Strbig(Llen,u);
short lt= length(t);
If lt<= n Then
sadd(s,t)
Else
pscopy(u,t,1,n);
sadd(s,u)
EndIf
EndProc
Proc allocdata(void)
Begin /* prevent any string overflow */
short i;
For i=0; i<nsub; Inc(i) Do
Sini(search[i]);
Sini(replace[i])
Done
EndProc
Proc setOptions(Pchar s)
/* command-line options c-mode and/or lookahead buffer size */
Begin
short j,k;
Bool num;
short z;
char c;
/*-StartProc-*/
ws("Options: ");
For j=1; j<length(s); Inc(j) Do /*scan for option setting chars */
If s[j]=='C' Then
cMode=True; ws("cMode ")
EndIf
If s[j]=='L' Then /*redefine max lookahead length */
z=0;
k= (short)(j+1);
Repeat
Inc(k); c=s[k];
num= (c>='0') And (c<='9');
If num Then z= (short)( 10*z+ c - '0') EndIf
Until Not num EndRep
If (z>lookmax) And (z<255) Then
lookmax= z
EndIf
ws("Lookahead="); wi(lookmax);
EndIf
Done
wln();
EndProc
/******** matching routines *******/
Proc copySpace(Pchar s, Pchar t, short a, short b) /* a,b>0 ! Pascal indexing */
Begin
/*echo any "nontrivial" whitespace t-->s */
short lt,i,k, comment;
Bool leader;
char c;
/*-StartProc-*/
scopy(s,"");
leader=False; /*leader space on new line...*/
k=0;
comment=0; /* for C type whitespaces 1 And 2*/
lt= length(t);
If b>lt Then b=lt EndIf
For i=(short)(a-1); i<b; Inc(i) Do
c=t[i];
If (c>0) And (c<' ') Then leader=True EndIf
If cMode And (c=='/') And (t[i+1]=='*') Then comment=1 EndIf
If ((c>0) And (c<' ')) Or (leader And (c==' ')) Or (comment>0) Then
cadd(s,c); Inc(k);
EndIf
If (comment==1) And (c=='/') And (t[i-1]=='*') Then comment=0 EndIf
Done
EndProc
Func short skipCwhite(Pchar t, short j, short lt) /* assume C indexing */
Begin
/* skip any C And C++ type whitespace in t, from j to lt */
/* returns j-1 If current char is no white at all! */
char c;
short comment; /*types 1 And 2! */
/*t[j] may already be '/' ? */ comment=0;
c=t[j]; /*If c>' ', we are done! */
If (c>0) And (c<=' ') Then
Repeat
If (comment==0) And (c=='/') Then
If t[j+1]=='*' Then
comment=1
ElsIf t[j+1]=='/' Then
comment=2
EndIf
ElsIf (comment==1) And (c=='/') And (t[j-1]=='*') Then
comment=0
ElsIf (comment==2) And (c==Lf) Then
comment=0
EndIf
Inc(j); c=t[j];
Until (j>lt) Or ((comment==0) And (c>' ')) EndRep
EndIf
return (short)(j-1); /* return last white-matching char position */
EndProc
Func Bool simple(Pchar s)
Begin /* check if no strange punctuations inside s */
char c;
short i,ls;
Bool found;
/*-StartProc-*/
ls=length(s);
i=0;
Repeat c=s[i];
found=(c=='(') Or (c==')') Or (c==',') Or (c==';') Or (c==':');
Inc(i);
Until found Or (i>=ls) EndRep
return Not found;
EndFunc
Func Bool match(Pchar s, Pchar t, short n, short tstart)
Begin
/* test if t starts with substring s.
returns 0 If tstart is out of range. But n may be 0 ?
options: Singlechar wildcards "?"
*/
short i,j,lt;
Bool ok;
/*-StartProc-*/
i=0; j=tstart;
lt= length(t);
ok=(tstart<lt);
While ok And (i<n) Do
ok= (j<lt) And ((s[i]==t[j]) Or (s[i]==joker));
Inc(i); Inc(j);
Done
return ok
EndFunc
Func short posi(Pchar sub, Pchar s)
Begin /*re-defines Turbo Pos, result Pascal compatible */
short a,b,k;
Bool ok;
/*-StartProc-*/
ok=False;
a=length(sub);
b=(short)(length(s)-a);
k=0;
If a>0 Then /*Else return 0*/
While (k<=b) And (Not ok) Do
ok=match(sub,s, a,k); /*remark we must start at k=0 ! */
Inc(k);
Done
EndIf
If ok Then
return k
Else
return 0
EndIf
EndFunc
Func short matchwhite(Pchar s, Pchar t, short n, short tstart)
Begin
/* like match, but any whitespace in t matches space in s*/
short i,j,lt; Bool ok;
/*-StartProc-*/
i=0; j=tstart;
lt= length(t);
ok=(tstart<lt);
While ok And (i<n) Do
If s[i]==' ' Then /* always Ok, skip space in t */
If cMode Then
j=skipCwhite(t,j,lt)
Else
While (j<=lt) And (t[j]<=' ') And (t[j]>0) Do Inc(j) Done
Dec(j);
EndIf
Repeat
Inc(j)
Until (j>=lt) Or (t[j]>' ') EndRep /*skip space in t*/
Dec(j);
Else
ok= (j<=lt) And ((s[i]==t[j]) Or (s[i]==joker));
EndIf
Inc(i); Inc(j);
Done
If ok Then
return (short)(j-tstart)
Else
return (short)0
EndIf
EndFunc
Func short posizero(Pchar sub, Pchar s)
Begin /*another Pos */
/* substring search. like posi, but reject quotes & bracketed stuff */
short a,b,k;
Bool ok;
short blevel;
char c;
/*-StartProc-*/
ok=False;
a=length(sub);
b=(short)(length(s)-a);
k=0; blevel=0;
If a>0 Then /*Else return 0*/
While (k<=b) And (Not ok) Do
ok= (matchwhite(sub,s, a,k)>0);
If (k<=b) And (Not ok) Then
c=s[k];
If (c==')') Or (c==']') Or (c=='}') Then
If c!=sub[0] Then Dec(blevel) EndIf /*negative level: fail!*/
If blevel<0 Then k=b EndIf
ElsIf (c=='\'') Or (c=='\"') Then /*skip quote */
Repeat Inc(k)
Until (k>=b) Or (s[k]==c) EndRep
ElsIf (c=='(') Or (c=='[') Or (c=='{') Then /*skip block*/
Inc(blevel); /*counts the bracketing level */
Repeat
Inc(k); c=s[k];
If (c=='(') Or (c=='[') Or (c=='{') Then
Inc(blevel)
ElsIf (c==')') Or (c==']') Or (c=='}') Then
Dec(blevel)
EndIf
Until (k>=b) Or (blevel==0) EndRep
EndIf
EndIf
Inc(k);
Done
EndIf
If ok Then
return k
Else
return 0
EndIf
EndFunc
Func short isMacro(Pchar s, char option, Pchar t, short tstart,
string maccopy[] )
/* s= macro template, t=buffer, maccopy = arg Array
return value: number of characters matched,
restrictive option: 'u'
macro substitution args 1 2 3 ...9.
sample: bla1tra2gla3vla matches "bla ME tra YOU gla HIM vla"
substitute 1 by maccopy[1] etc
*/
Begin
Darray(ps, short, nargs+1)
Word j,k,dk,ls, lst, lmt, jmax, pj;
Bool ok;
char arg;
Strbig(Llen,u);
Str(40,st);
/* returns >0 If comparison Ok == length of compared Pchar */
/*-StartProc-*/ k=0;
ok= (s[0]==t[tstart]); /* shortcut: how much does it accelerate ? some % */
If ok Then
ps[0]=0;
ps[nargs]=0; /*only 1..9 are valid data, 10 filler templates*/
j=0;
Repeat
Inc(j); arg= (char)(j+'0');
ps[j]= cpos(arg,s);
Until (j>=nargs) Or (ps[j]==0) EndRep
ls= length(s);
ps[j]=(short)(ls+1); /*For last template chunk*/
jmax=j; j=1;
k=0; lmt=0;
Repeat
pscopy(st,s, (Word)(ps[j-1]+1), (Word)(ps[j]-ps[j-1]-1) );
/*j-th template Pchar*/ lst=length(st);
If j==1 Then
If option=='u' Then
lmt= matchwhite(st,t,lst,tstart);
ok=(lmt>0) /*length of match in t*/
Else
ok= match(st,t,lst,tstart)
EndIf
If ok Then
pscopy(u,t, (Word)(tstart+1), (Word)255);
pj=1
Else
pj=0
EndIf
Else
If option=='u' Then
pj= posizero(st,u);
If pj>0 Then lmt= matchwhite(st,u, lst, (short)(pj-1)) EndIf
Else
pj= posi(st,u)
EndIf /* qs[j]= k+pj; is position in t*/
ok=(pj>0);
EndIf
If ok Then
If option=='u' Then
If j==1 Then scopy(maccopy[0],"") EndIf
saddn(maccopy[j-1],u, (Word)(pj-1));
dk= (Word)(pj+lmt);
copySpace(maccopy[j], t,
(Word)(tstart+k+pj), (Word)(tstart+k+dk));
/* space in t[k+pj...k+dk] goes into maccopy[j] as a prefix. */
Else
pscopy(maccopy[j-1],u, (Word)1, (Word)(pj-1));
/*the stuff preceding the marker*/
dk= (Word)(pj+lst); /* start of unexplored part */
EndIf
pscopy(u,u, (Word)dk, (Word)length(u)); /*shift in the rest*/
k= (Word)(k+dk-1);
EndIf
Inc(j)
Until (j>jmax) Or (Not ok) EndRep
EndIf
If Not ok Then k=0 EndIf
return k
EndFunc
Func short similar(Pchar s, char wilds, Pchar t,
short tstart, string maccopy[] )
/* try to match s with t, then save the wildcard parts ins maccopy[] */
/* s=template, t=buffer, wilds= number of wildcards, maccopy=substitute */
/* return value: number of characters matched */
Begin
Word j,k,ps,ls;
Bool ok;
char endc;
Strbig(Llen,u);
/* returns >0 if comparison Ok = length of compared string */
/* char comparison, s may have wildcard regions with "æ" BUT 1 valid End */
/*-StartProc-*/
ls=length(s);
k=0;
If wilds==wild Then
ps= cpos(wild,s)
Else
ps=0
EndIf
If ps==0 Then
If match(s,t,ls,tstart) Then
k=ls;
ps= cpos(joker,s); /*save joker's substitute*/
If ps>0 Then
maccopy[nargs][0]=t[ps-1+tstart]
EndIf
Else
k=0
EndIf
Else
k= (Word)(ps-1);
While s[k]==wild Do Inc(k) Done
endc=s[k]; /*End char to detect, at length */
ok= match(s,t, (short)(ps-1), tstart);
If ok Then
pscopy(u,t, (Word)(ps+tstart), (Word)255);
j= cpos(endc, u);
ok=(j>0);
If ok Then
k= (Word)(ps+j-1);
pscopy(maccopy[nargs],t, (Word)(ps+tstart), (Word)(j-1));
EndIf
EndIf
If Not ok Then k=0 EndIf
EndIf
return k
EndProc
Func short addSubList(Pchar s, short isr)
/* add the rule s to the Rule list at isr */
Begin
short j,ls;
char c,d,endc;
Bool start,stop;
/*-StartProc-*/
ls=length(s); /* must kill the Newline */
endc=' ';
While (ls>0) And (s[ls]<' ') Do Dec(ls) Done;
s[ls+1]=' ';
s[ls+2]=0; /* add a space */
If s[0]=='o' Then
setOptions(s)
ElsIf (isr<nsub) And (cpos(s[0],"swmuxa") >0) Then
j=1;
Inc(isr);
scopy(search[isr],""); scopy(replace[isr],"");
srule[isr]=(s[0]);
wildcard[isr]=0;
/*init search*/
start=True; stop=False;
d=0;
While Not stop Do
Inc(j); c=s[j];
If start Then
If c !=' ' Then
start=False;
If c=='\"' Then endc=c Else endc=' ' EndIf
EndIf
Else
stop=(c==endc)
EndIf
If Not (start Or (c==endc)) Then
If c=='?' Then
c=joker
ElsIf (c=='^') And (s[j+1]>= ' ') Then
Inc(j); c=s[j];
If (c>='@') And (c<='_') Then
c= (char)(c-'@')
EndIf
ElsIf (c=='\\') And (s[j+1]>= ' ') Then
Inc(j); c=s[j];
If c=='n' Then c= Cr; d=Lf EndIf
EndIf
cadd(search[isr],c);
If (c==wild) Or (c==joker) Then
wildcard[isr]=c
EndIf
If d!=0 Then
cadd(search[isr],d);
d=0
EndIf
EndIf
Done
If endc!=' ' Then Inc(j) EndIf
/*init replace*/
start=True; stop=False;
d=0;
While Not stop Do
Inc(j); c=s[j];
If start Then
If c!=' ' Then
start=False;
If c=='\"' Then endc=c Else endc=' ' EndIf
EndIf
Else
stop=(c==endc)
EndIf
If Not (start Or (c==endc)) Then
If c=='?' Then
c=joker
ElsIf (c=='^') And (s[j+1]>= ' ') Then
Inc(j); c=s[j];
If (c>='@') And (c<='Z') Then c= (char)(c-'@') EndIf
ElsIf (c=='\\') And (s[j+1]>= ' ') Then
Inc(j); c=s[j]; /*echo next char */
If c=='n' Then c=Cr; d=Lf EndIf
EndIf
cadd(replace[isr],c);
If d!=0 Then
cadd(replace[isr],d);
d=0
EndIf
EndIf
Done
If endc !=' ' Then Inc(j) EndIf
EndIf
If isr>=nsub Then
ws("No more room for rules."); wln()
EndIf
return isr
EndFunc
Func Bool getSubList(Pchar slist)
/* read the search and substitution rule list */
Begin
Strbig(Llen,s);
Pfile f;
Bool done, ok;
/*-StartProc-*/
cMode=False;
lookmax= 80; /* or 250: handle 4 full lines maximum ? */
If Zero(slist[0]) Then
scopy(slist, "slist.txt")
EndIf
f=fopen(slist,"rb");
isr=0;
done= (f == Null);
ok= Not done;
While Not done Do
fgets(s,(short)80,f);
isr=addSubList(s,isr);
done= feof(f)
Done
If f != Null Then fclose(f) EndIf
ws("Number of rules: ");
wi(isr); wln();
return ok
EndFunc
Func Bool nonAlfa(char c)
Begin
return ((c<'a') Or (c>'z')) And ((c<'A') Or (c>'Z'))
EndFunc
/********** optional output postprocessor **************/
/* the main translator calls these:
washinit to reset the postprocessor
washchar to output a char
washstring to output a string
washflush to terminate
*/
/* C reformatter, keeping an eye on the following (modulo whitespace):
; } Lf.
This is just a state machine, handling 3 rules using an output buffer obf.
<white> means space excluding \n, and <white2>, space including newlines.
Wanted: regular-expression scripts or tricks to do the same or better...
Rule1: <white>Lf<white>; --> ;<white>Lf<white> states 2 3
Rule2: ;<white2>; --> ;<white2> state 1
Rule3: }<white2>; --> }<white2> state 1
*/
Bool washmore= True; /* flag that activates the postprocessor */
Strbig(Llen,obf); /* output buffer */
short iobf=0; /* its index */
short wstate=0; /* output state machine */
Proc washinit(void)
Begin
iobf=0;
wstate=0
EndProc
Proc washchar(char c)
Begin /* state machine receives one character */
short i;
If Not washmore Then /* never leave state 0 */
fputc(c, fout)
ElsIf wstate==0 Then /* buffer empty */
If (c==';') Or (c=='}') Then
iobf=0; obf[iobf]=c;
Inc(iobf); wstate=1
ElsIf c<=' ' Then
iobf=0; obf[iobf]=c;
Inc(iobf);
If c==Lf Then wstate=3 Else wstate=2 EndIf
Else
fputc(c, fout)
EndIf
ElsIf wstate==1 Then
If c <= ' ' Then
obf[iobf]=c; Inc(iobf)
Else
If c != ';' Then
obf[iobf]=c; Inc(iobf)
EndIf
For i=0; i<iobf; Inc(i) Do
fputc(obf[i], fout)
Done
iobf=0;
wstate=0
EndIf
ElsIf wstate==2 Then
obf[iobf]=c; Inc(iobf);
If c==Lf Then
wstate=3
ElsIf c<=' ' Then /* keep state */
Else
For i=0; i<iobf; Inc(i) Do
fputc(obf[i], fout)
Done
iobf=0;
wstate=0
EndIf
ElsIf wstate==3 Then
obf[iobf]=c; Inc(iobf);
If c<=' ' Then /* keep state */
Else
If c==';' Then
Dec(iobf); fputc(c, fout)
EndIf
For i=0; i<iobf; Inc(i) Do
fputc(obf[i], fout)
Done
iobf=0;
wstate=0
EndIf
EndIf
EndProc
Proc washflush(void)
Begin
short i;
If NotZ(wstate) Then
For i=0; i<iobf; Inc(i) Do
fputc(obf[i], fout)
Done
iobf=0;
wstate=0
EndIf
EndProc
Proc washstring( Pchar s)
Begin
short i;
For i=0; i<length(s); Inc(i) Do
washchar(s[i])
Done
EndProc
/************* main part of translation filter ***********/
Proc translate(Pchar bf); /* recursion */
Proc echoOut(Pchar r, char isWild, string mac[] )
Begin
short u;
Strbig(Llen,s);
/*-StartProc-*/
If isWild !=0 Then
u= cpos(isWild,r)
Else
u=0
EndIf
If u==0 Then
washstring(r)
Else /*substitute with wildcard*/
pscopy(s,r, (Word)1, (Word)(u-1)); washstring(s);
If isWild==joker Then
washchar(mac[nargs][0])
ElsIf Recursion Then
translate(mac[nargs])
Else
washstring(mac[nargs])
EndIf
scopy(mac[nargs], "");
pscopy(s,r, (Word)(u+1), (Word)40);
washstring(s);
EndIf
EndProc
Proc macroOut(Pchar r, string mac[] )
Begin
/* substitutes "1"..."9", uses "0" as escape character*/
char c;
short i,j;
Bool escape;
/*-StartProc-*/
escape=False;
For i=0; i<length(r); Inc(i) Do
c=r[i];
j= (short)(c-'0');
If j==0 Then
escape=True /*And skip*/
ElsIf ((j>0) And (j<nargs)) And (Not escape) Then
If Recursion Then
translate(mac[j])
Else
washstring(mac[j])
EndIf
Else
washchar(c);
escape=False
EndIf
Done
EndProc
Proc makeNewRule(Pchar r, string mac[] )
Begin
/* substitutes "1"..."9", uses "0" as escape character*/
char c;
short i,j;
Bool escape;
Strbig(Llen,s);
/*-StartProc-*/
escape=False;
For i=0; i<length(r); Inc(i) Do
c=r[i];
j= (short)(c-'0');
If j==0 Then
escape=True /*And skip*/
ElsIf ((j>0) And (j<nargs)) And (Not escape) Then
sadd(s,mac[j])
Else
cadd(s,c); escape=False
EndIf
Done
isr= addSubList(s,isr)
EndProc
Proc translate(Pchar bff)
Begin /*light version, inside recursion only */
Bool done;
Strbig(Llen,bf);
Darray(mac, string, nargs)
Bool ok;
short i,sm;
char lastBf1;
Word nbrep;
/*-StartProc-*/
For i=0; i<nargs; Inc(i) Do
Sini(mac[i])
Done
nbrep=0;
done= Zero(bff[0]);
lastBf1=' ';
If Not done Then scopy(bf,bff) EndIf
While Not done Do
i=1;
ok=False; sm=0;
While (i<=isr) And (Not ok) Do /*search For 1st match*/
If (srule[i]=='m') Or (srule[i]=='u') Then
If alfa(lastBf1) And (alfa(search[i][0])) Then
sm=0 /*inside word*/
Else
sm= isMacro(search[i], srule[i], bf, (short)0,mac)
EndIf
Else
sm=similar(search[i],wildcard[i],bf, (short)0, mac)
EndIf
ok=sm>0;
If ok And (srule[i]=='w') Then
ok=nonAlfa(lastBf1) And nonAlfa(bf[sm])
EndIf
If Not ok Then Inc(i) EndIf
Done
If ok Then
If (srule[i]=='m') Or (srule[i]=='u') Then
macroOut(replace[i], mac)
Else
echoOut(replace[i],wildcard[i], mac)
EndIf
lastBf1=bf[sm-1]; pscopy(bf,bf, (Word)(sm+1), (Word)255);
Inc(nbrep);
Else
lastBf1=bf[0];
washchar(lastBf1);
pscopy(bf,bf, (Word)2, (Word)255);
EndIf
done= Zero(bf[0])
Done
EndProc
Proc translator( Pchar fname)
/* checks list of possible substitution rules sequentially.
Does the first that matches. Option: recursion.
BUG: is very slow.
*/
Begin
Strbig(Llen, outname); Strbig(Llen,bf);
Bool done;
Darray( mac, string, nargs)
Pfile fin;
Bool ok;
short i,sm, exclusion, idot;
char c,lastBf1;
Word nbrep,nline;
/*-StartProc-*/
For i=0; i<nargs; Inc(i) Do
Sini(mac[i])
Done
nbrep=0;
nline=0;
exclusion=0; /* will be >0 if an exclusion rule is active */
fin=fopen( fname, "rb");
scopy(outname, fname);
idot= cpos('.',outname);
If idot <= 8 Then /* room for underbar prefix, even in Ms-dos */
cins(outname,'_')
ElsIf NotZ(outname[0]) Then /* just erase first char */
outname[0] = '_'
Else
scopy(outname,"washprog.out")
EndIf
fout=fopen( outname,"wb");
washinit();
done= (fin == Null) Or (fout == Null);
scopy(bf,"");
lastBf1=' ';
/* lookmax=80; handle a line maximum ! */
While Not done Do
c=' ';
While (c !=0) And (length(bf)<lookmax) Do /*refill buffer*/
If Not feof(fin) Then
c=fgetc(fin);
If (c== Cr) Or (c== Lf) Then
Inc(nline);
If odd(nline) Then wc('.') EndIf
If (nline Mod 150)==0 Then wln() EndIf
EndIf
If (c==0) Or feof(fin) Then c=' ' EndIf /*== space*/
Else
c=0
EndIf
If NotZ(c) Then cadd(bf,c) EndIf
Done
ok=False;
sm=0; i=0;
If exclusion>0 Then
i=exclusion;
sm=similar(replace[i], (char)0, bf, (short)0, mac);
ok= sm>0
EndIf
If Zero(exclusion) Then
i=1;
While (i<=isr) And (Not ok) Do /*search for 1st match*/
If (srule[i]=='m') Or (srule[i]=='u') Or (srule[i]=='a') Then
If alfa(lastBf1) And (alfa(search[i][0])) Then
sm=0 /*inside word*/
Else
sm= isMacro(search[i], srule[i], bf, (short)0,mac)
EndIf
Else
sm=similar(search[i],wildcard[i],bf, (short)0, mac)
EndIf
ok=sm>0;
If ok And (srule[i]=='w') Then
ok=nonAlfa(lastBf1) And nonAlfa(bf[sm])
EndIf
If Not ok Then Inc(i) EndIf
Done
EndIf
If ok Then
If (srule[i]=='m') Or (srule[i]=='u') Then
macroOut(replace[i], mac)
ElsIf srule[i]=='x' Then
If Zero(exclusion) Then
exclusion=i
Else
exclusion=0
EndIf
ElsIf srule[i]=='a' Then
makeNewRule(replace[i],mac)
Else
echoOut(replace[i],wildcard[i],mac)
EndIf
lastBf1=bf[sm-1]; pscopy(bf,bf, (Word)(sm+1), (Word)lookmax);
Inc(nbrep);
Else
lastBf1=bf[0];
If Zero(exclusion) Then washchar(lastBf1) EndIf;
pscopy(bf,bf, (Word)2, (Word)lookmax);
/*avoid this time-consuming buffer shuffling ?*/
EndIf
done= Zero(bf[0]);
Done
If fout !=Null Then
washflush();
fputc('\n', fout);
fclose(fout)
EndIf
If fin !=Null Then fclose(fin) EndIf
ws("Lines: "); wi(nline);
ws(" Replacements: ");
wi(nbrep); wln();
EndProc
Func int main( int argc, Pchar argv[])
Begin
Str(80,dico);
short istart= 1;
Bool ok= True;
/*-StartProc-*/
allocdata();
scopy(dico,"downgrad"); /* default rules file */
ws(" washprog: A text substitution utility"); wln();
If (argc>2) And steq(argv[1],"-r") Then
scopy(dico,argv[2]);
istart= 3;
/*
Else
ws("Dictionary file (.TXT automatic): ");
rln(dico);
*/
EndIf
If spos(".txt",dico) <=0 Then
sadd(dico,".txt")
EndIf
ok= getSubList(dico); /*list of substitution rules */
While ok And (istart< argc) Do
If argv[istart][0] != '_' Then /* leading underbar not accepted */
translator( argv[istart])
EndIf
Inc(istart)
Done
return 0
EndFunc

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@
struct line * inp_subcktexpand(struct line *deck);
struct line * inp_deckcopy(struct line *deck);
int inp_numnodes(char c);

View File

@ -454,7 +454,6 @@ extern struct variable *if_getstat();
extern struct line *inp_deckcopy();
extern struct line *inp_subcktexpand();
extern int inp_numnodes(char);
/* types.c */

View File

@ -196,6 +196,7 @@ DCtran(CKTcircuit *ckt,
i++;
} */
} else {
if(SMPmatSize(ckt->CKTmatrix) < 10) {
fprintf(stdout,"\nInitial Transient Solution\n");
fprintf(stdout,"--------------------------\n\n");
fprintf(stdout,"%-30s %15s\n", "Node", "Voltage");
@ -205,6 +206,7 @@ DCtran(CKTcircuit *ckt,
fprintf(stdout,"%-30s %15g\n", node->name,
*(ckt->CKTrhsOld+node->number));
};
}
};
fprintf(stdout,"\n");
fflush(stdout);

View File

@ -0,0 +1,6 @@
Makefile.in
Makefile
.deps
.libs
*.lo
*.la

View File

@ -0,0 +1,33 @@
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.
Chenming Hu, and Weidong Liu
Mar. 2000

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libbsim4.a
pkglib_LIBRARIES = libbsim4.a
libbsim4_a_SOURCES = \
b4.c \

View File

@ -1,17 +1,20 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "devdefs.h"
#include "bsim4def.h"
#include "suffix.h"
@ -19,7 +22,15 @@
IFparm BSIM4pTable[] = { /* parameters */
IOP( "l", BSIM4_L, IF_REAL , "Length"),
IOP( "w", BSIM4_W, IF_REAL , "Width"),
IOP( "m", BSIM4_M, IF_REAL , "Separate Parallel multiplier"),
IOP( "nf", BSIM4_NF, IF_REAL , "Number of fingers"),
IOP( "sa", BSIM4_SA, IF_REAL , "distance between OD edge to poly of one side "),
IOP( "sb", BSIM4_SB, IF_REAL , "distance between OD edge to poly of the other side"),
IOP( "sd", BSIM4_SD, IF_REAL , "distance between neighbour fingers"),
IOP( "sca", BSIM4_SCA, IF_REAL , "Integral of the first distribution function for scattered well dopant"),
IOP( "scb", BSIM4_SCB, IF_REAL , "Integral of the second distribution function for scattered well dopant"),
IOP( "scc", BSIM4_SCC, IF_REAL , "Integral of the third distribution function for scattered well dopant"),
IOP( "sc", BSIM4_SCA, IF_REAL , "Distance to a single well edge "),
IOP( "min", BSIM4_MIN, IF_INTEGER , "Minimize either D or S"),
IOP( "ad", BSIM4_AD, IF_REAL , "Drain area"),
IOP( "as", BSIM4_AS, IF_REAL , "Source area"),
@ -33,6 +44,10 @@ IOP( "rbsb", BSIM4_RBSB, IF_REAL , "Body resistance"),
IOP( "rbpb", BSIM4_RBPB, IF_REAL , "Body resistance"),
IOP( "rbps", BSIM4_RBPS, IF_REAL , "Body resistance"),
IOP( "rbpd", BSIM4_RBPD, IF_REAL , "Body resistance"),
IOP( "delvto", BSIM4_DELVTO, IF_REAL , "Zero bias threshold voltage variation"),
IOP( "xgw", BSIM4_XGW, IF_REAL, "Distance from gate contact center to device edge"),
IOP( "ngcon", BSIM4_NGCON, IF_REAL, "Number of gate contacts"),
IOP( "trnqsmod", BSIM4_TRNQSMOD, IF_INTEGER, "Transient NQS model selector"),
IOP( "acnqsmod", BSIM4_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
@ -49,6 +64,8 @@ OP( "vth", BSIM4_VON, IF_REAL, "Vth"),
OP( "id", BSIM4_CD, IF_REAL, "Ids"),
OP( "ibd", BSIM4_CBD, IF_REAL, "Ibd"),
OP( "ibs", BSIM4_CBS, IF_REAL, "Ibs"),
OP( "gbd", BSIM4_GBD, IF_REAL, "gbd"),
OP( "gbs", BSIM4_GBS, IF_REAL, "gbs"),
OP( "isub", BSIM4_CSUB, IF_REAL, "Isub"),
OP( "igidl", BSIM4_IGIDL, IF_REAL, "Igidl"),
OP( "igisl", BSIM4_IGISL, IF_REAL, "Igisl"),
@ -83,6 +100,9 @@ OP( "qb", BSIM4_QB, IF_REAL, "Qbulk"),
OP( "qd", BSIM4_QD, IF_REAL, "Qdrain"),
OP( "qs", BSIM4_QS, IF_REAL, "Qsource"),
OP( "qinv", BSIM4_QINV, IF_REAL, "Qinversion"),
OP( "qdef", BSIM4_QDEF, IF_REAL, "Qdef"),
OP( "gcrg", BSIM4_GCRG, IF_REAL, "Gcrg"),
OP( "gtau", BSIM4_GTAU, IF_REAL, "Gtau"),
};
IFparm BSIM4mPTable[] = { /* model parameters */
@ -100,6 +120,7 @@ IOP( "fnoimod", BSIM4_MOD_FNOIMOD, IF_INTEGER, "Flicker noise model selector"),
IOP( "tnoimod", BSIM4_MOD_TNOIMOD, IF_INTEGER, "Thermal noise model selector"),
IOP( "igcmod", BSIM4_MOD_IGCMOD, IF_INTEGER, "Gate-to-channel Ig model selector"),
IOP( "igbmod", BSIM4_MOD_IGBMOD, IF_INTEGER, "Gate-to-body Ig model selector"),
IOP( "tempmod", BSIM4_MOD_TEMPMOD, IF_INTEGER, "Temperature model selector"),
IOP( "paramchk", BSIM4_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
IOP( "binunit", BSIM4_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
IOP( "version", BSIM4_MOD_VERSION, IF_STRING, "parameter for model version"),
@ -161,6 +182,10 @@ IOP( "ub", BSIM4_MOD_UB, IF_REAL, "Quadratic gate dependence of mobility"),
IOP( "ub1", BSIM4_MOD_UB1, IF_REAL, "Temperature coefficient of ub"),
IOP( "uc", BSIM4_MOD_UC, IF_REAL, "Body-bias dependence of mobility"),
IOP( "uc1", BSIM4_MOD_UC1, IF_REAL, "Temperature coefficient of uc"),
IOP( "ud", BSIM4_MOD_UD, IF_REAL, "Coulomb scattering factor of mobility"),
IOP( "ud1", BSIM4_MOD_UD1, IF_REAL, "Temperature coefficient of ud"),
IOP( "up", BSIM4_MOD_UP, IF_REAL, "Channel length linear factor of mobility"),
IOP( "lp", BSIM4_MOD_LP, IF_REAL, "Channel length exponential factor of mobility"),
IOP( "u0", BSIM4_MOD_U0, IF_REAL, "Low-field mobility at Tnom"),
IOP( "eu", BSIM4_MOD_EU, IF_REAL, "Mobility exponent"),
IOP( "ute", BSIM4_MOD_UTE, IF_REAL, "Temperature coefficient of mobility"),
@ -251,6 +276,15 @@ IOP( "rshg", BSIM4_MOD_RSHG, IF_REAL, "Gate sheet resistance"),
IOP( "ngcon", BSIM4_MOD_NGCON, IF_REAL, "Number of gate contacts"),
IOP( "xrcrg1", BSIM4_MOD_XRCRG1, IF_REAL, "First fitting parameter the bias-dependent Rg"),
IOP( "xrcrg2", BSIM4_MOD_XRCRG2, IF_REAL, "Second fitting parameter the bias-dependent Rg"),
IOP( "lambda", BSIM4_MOD_LAMBDA, IF_REAL, " Velocity overshoot parameter"),
IOP( "vtl", BSIM4_MOD_VTL, IF_REAL, " thermal velocity"),
IOP( "lc", BSIM4_MOD_LC, IF_REAL, " back scattering parameter"),
IOP( "xn", BSIM4_MOD_XN, IF_REAL, " back scattering parameter"),
IOP( "vfbsdoff", BSIM4_MOD_VFBSDOFF, IF_REAL, "S/D flatband voltage offset"),
IOP( "tvfbsdoff", BSIM4_MOD_TVFBSDOFF, IF_REAL, "Temperature parameter for vfbsdoff"),
IOP( "tvoff", BSIM4_MOD_TVOFF, IF_REAL, "Temperature parameter for voff"),
IOP( "lintnoi", BSIM4_MOD_LINTNOI, IF_REAL, "lint offset for noise calculation"),
IOP( "lint", BSIM4_MOD_LINT, IF_REAL, "Length reduction parameter"),
IOP( "ll", BSIM4_MOD_LL, IF_REAL, "Length reduction parameter"),
IOP( "llc", BSIM4_MOD_LLC, IF_REAL, "Length reduction parameter for CV"),
@ -299,6 +333,7 @@ IOP( "dwj", BSIM4_MOD_DWJ, IF_REAL, "Delta W for S/D junctions"),
IOP( "alpha0", BSIM4_MOD_ALPHA0, IF_REAL, "substrate current model parameter"),
IOP( "alpha1", BSIM4_MOD_ALPHA1, IF_REAL, "substrate current model parameter"),
IOP( "beta0", BSIM4_MOD_BETA0, IF_REAL, "substrate current model parameter"),
IOP( "agidl", BSIM4_MOD_AGIDL, IF_REAL, "Pre-exponential constant for GIDL"),
IOP( "bgidl", BSIM4_MOD_BGIDL, IF_REAL, "Exponential constant for GIDL"),
IOP( "cgidl", BSIM4_MOD_CGIDL, IF_REAL, "Parameter for body-bias dependence of GIDL"),
@ -332,6 +367,31 @@ IOP( "xjbvs", BSIM4_MOD_XJBVS, IF_REAL, "Fitting parameter for source diode brea
IOP( "bvd", BSIM4_MOD_BVD, IF_REAL, "Drain diode breakdown voltage"),
IOP( "bvs", BSIM4_MOD_BVS, IF_REAL, "Source diode breakdown voltage"),
IOP( "jtss", BSIM4_MOD_JTSS, IF_REAL, "Source bottom trap-assisted saturation current density"),
IOP( "jtsd", BSIM4_MOD_JTSD, IF_REAL, "Drain bottom trap-assisted saturation current density"),
IOP( "jtssws", BSIM4_MOD_JTSSWS, IF_REAL, "Source STI sidewall trap-assisted saturation current density"),
IOP( "jtsswd", BSIM4_MOD_JTSSWD, IF_REAL, "Drain STI sidewall trap-assisted saturation current density"),
IOP( "jtsswgs", BSIM4_MOD_JTSSWGS, IF_REAL, "Source gate-edge sidewall trap-assisted saturation current density"),
IOP( "jtsswgd", BSIM4_MOD_JTSSWGD, IF_REAL, "Drain gate-edge sidewall trap-assisted saturation current density"),
IOP( "njts", BSIM4_MOD_NJTS, IF_REAL, "Non-ideality factor for bottom junction"),
IOP( "njtssw", BSIM4_MOD_NJTSSW, IF_REAL, "Non-ideality factor for STI sidewall junction"),
IOP( "njtsswg", BSIM4_MOD_NJTSSWG, IF_REAL, "Non-ideality factor for gate-edge sidewall junction"),
IOP( "xtss", BSIM4_MOD_XTSS, IF_REAL, "Power dependence of JTSS on temperature"),
IOP( "xtsd", BSIM4_MOD_XTSD, IF_REAL, "Power dependence of JTSD on temperature"),
IOP( "xtssws", BSIM4_MOD_XTSSWS, IF_REAL, "Power dependence of JTSSWS on temperature"),
IOP( "xtsswd", BSIM4_MOD_XTSSWD, IF_REAL, "Power dependence of JTSSWD on temperature"),
IOP( "xtsswgs", BSIM4_MOD_XTSSWGS, IF_REAL, "Power dependence of JTSSWGS on temperature"),
IOP( "xtsswgd", BSIM4_MOD_XTSSWGD, IF_REAL, "Power dependence of JTSSWGD on temperature"),
IOP( "tnjts", BSIM4_MOD_TNJTS, IF_REAL, "Temperature coefficient for NJTS"),
IOP( "tnjtssw", BSIM4_MOD_TNJTSSW, IF_REAL, "Temperature coefficient for NJTSSW"),
IOP( "tnjtsswg", BSIM4_MOD_TNJTSSWG, IF_REAL, "Temperature coefficient for NJTSSWG"),
IOP( "vtss", BSIM4_MOD_VTSS, IF_REAL, "Source bottom trap-assisted voltage dependent parameter"),
IOP( "vtsd", BSIM4_MOD_VTSD, IF_REAL, "Drain bottom trap-assisted voltage dependent parameter"),
IOP( "vtssws", BSIM4_MOD_VTSSWS, IF_REAL, "Source STI sidewall trap-assisted voltage dependent parameter"),
IOP( "vtsswd", BSIM4_MOD_VTSSWD, IF_REAL, "Drain STI sidewall trap-assisted voltage dependent parameter"),
IOP( "vtsswgs", BSIM4_MOD_VTSSWGS, IF_REAL, "Source gate-edge sidewall trap-assisted voltage dependent parameter"),
IOP( "vtsswgd", BSIM4_MOD_VTSSWGD, IF_REAL, "Drain gate-edge sidewall trap-assisted voltage dependent parameter"),
IOP( "gbmin", BSIM4_MOD_GBMIN, IF_REAL, "Minimum body conductance"),
IOP( "rbdb", BSIM4_MOD_RBDB, IF_REAL, "Resistance between bNode and dbNode"),
IOP( "rbpb", BSIM4_MOD_RBPB, IF_REAL, "Resistance between bNodePrime and bNode"),
@ -339,6 +399,37 @@ IOP( "rbsb", BSIM4_MOD_RBSB, IF_REAL, "Resistance between bNode and sbNode"),
IOP( "rbps", BSIM4_MOD_RBPS, IF_REAL, "Resistance between bNodePrime and sbNode"),
IOP( "rbpd", BSIM4_MOD_RBPD, IF_REAL, "Resistance between bNodePrime and bNode"),
IOP( "rbps0", BSIM4_MOD_RBPS0, IF_REAL , "Body resistance RBPS scaling"),
IOP( "rbpsl", BSIM4_MOD_RBPSL, IF_REAL , "Body resistance RBPS L scaling"),
IOP( "rbpsw", BSIM4_MOD_RBPSW, IF_REAL , "Body resistance RBPS W scaling"),
IOP( "rbpsnf", BSIM4_MOD_RBPSNF, IF_REAL , "Body resistance RBPS NF scaling"),
IOP( "rbpd0", BSIM4_MOD_RBPD0, IF_REAL , "Body resistance RBPD scaling"),
IOP( "rbpdl", BSIM4_MOD_RBPDL, IF_REAL , "Body resistance RBPD L scaling"),
IOP( "rbpdw", BSIM4_MOD_RBPDW, IF_REAL , "Body resistance RBPD W scaling"),
IOP( "rbpdnf", BSIM4_MOD_RBPDNF, IF_REAL , "Body resistance RBPD NF scaling"),
IOP( "rbpbx0", BSIM4_MOD_RBPBX0, IF_REAL , "Body resistance RBPBX scaling"),
IOP( "rbpbxl", BSIM4_MOD_RBPBXL, IF_REAL , "Body resistance RBPBX L scaling"),
IOP( "rbpbxw", BSIM4_MOD_RBPBXW, IF_REAL , "Body resistance RBPBX W scaling"),
IOP( "rbpbxnf", BSIM4_MOD_RBPBXNF, IF_REAL , "Body resistance RBPBX NF scaling"),
IOP( "rbpby0", BSIM4_MOD_RBPBY0, IF_REAL , "Body resistance RBPBY scaling"),
IOP( "rbpbyl", BSIM4_MOD_RBPBYL, IF_REAL , "Body resistance RBPBY L scaling"),
IOP( "rbpbyw", BSIM4_MOD_RBPBYW, IF_REAL , "Body resistance RBPBY W scaling"),
IOP( "rbpbynf", BSIM4_MOD_RBPBYNF, IF_REAL , "Body resistance RBPBY NF scaling"),
IOP( "rbsbx0", BSIM4_MOD_RBSBX0, IF_REAL , "Body resistance RBSBX scaling"),
IOP( "rbsby0", BSIM4_MOD_RBSBY0, IF_REAL , "Body resistance RBSBY scaling"),
IOP( "rbdbx0", BSIM4_MOD_RBDBX0, IF_REAL , "Body resistance RBDBX scaling"),
IOP( "rbdby0", BSIM4_MOD_RBDBY0, IF_REAL , "Body resistance RBDBY scaling"),
IOP( "rbsdbxl", BSIM4_MOD_RBSDBXL, IF_REAL , "Body resistance RBSDBX L scaling"),
IOP( "rbsdbxw", BSIM4_MOD_RBSDBXW, IF_REAL , "Body resistance RBSDBX W scaling"),
IOP( "rbsdbxnf", BSIM4_MOD_RBSDBXNF, IF_REAL , "Body resistance RBSDBX NF scaling"),
IOP( "rbsdbyl", BSIM4_MOD_RBSDBYL, IF_REAL , "Body resistance RBSDBY L scaling"),
IOP( "rbsdbyw", BSIM4_MOD_RBSDBYW, IF_REAL , "Body resistance RBSDBY W scaling"),
IOP( "rbsdbynf", BSIM4_MOD_RBSDBYNF, IF_REAL , "Body resistance RBSDBY NF scaling"),
IOP( "lcdsc", BSIM4_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"),
IOP( "lcdscb", BSIM4_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"),
IOP( "lcdscd", BSIM4_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"),
@ -390,6 +481,10 @@ IOP( "lub", BSIM4_MOD_LUB, IF_REAL, "Length dependence of ub"),
IOP( "lub1", BSIM4_MOD_LUB1, IF_REAL, "Length dependence of ub1"),
IOP( "luc", BSIM4_MOD_LUC, IF_REAL, "Length dependence of uc"),
IOP( "luc1", BSIM4_MOD_LUC1, IF_REAL, "Length dependence of uc1"),
IOP( "lud", BSIM4_MOD_LUD, IF_REAL, "Length dependence of ud"),
IOP( "lud1", BSIM4_MOD_LUD1, IF_REAL, "Length dependence of ud1"),
IOP( "lup", BSIM4_MOD_LUP, IF_REAL, "Length dependence of up"),
IOP( "llp", BSIM4_MOD_LLP, IF_REAL, "Length dependence of lp"),
IOP( "lu0", BSIM4_MOD_LU0, IF_REAL, "Length dependence of u0"),
IOP( "lute", BSIM4_MOD_LUTE, IF_REAL, "Length dependence of ute"),
IOP( "lvoff", BSIM4_MOD_LVOFF, IF_REAL, "Length dependence of voff"),
@ -430,6 +525,7 @@ IOP( "lcle", BSIM4_MOD_LCLE, IF_REAL, "Length dependence of cle"),
IOP( "lalpha0", BSIM4_MOD_LALPHA0, IF_REAL, "Length dependence of alpha0"),
IOP( "lalpha1", BSIM4_MOD_LALPHA1, IF_REAL, "Length dependence of alpha1"),
IOP( "lbeta0", BSIM4_MOD_LBETA0, IF_REAL, "Length dependence of beta0"),
IOP( "lagidl", BSIM4_MOD_LAGIDL, IF_REAL, "Length dependence of agidl"),
IOP( "lbgidl", BSIM4_MOD_LBGIDL, IF_REAL, "Length dependence of bgidl"),
IOP( "lcgidl", BSIM4_MOD_LCGIDL, IF_REAL, "Length dependence of cgidl"),
@ -462,7 +558,14 @@ IOP( "lnoff", BSIM4_MOD_LNOFF, IF_REAL, "Length dependence of noff"),
IOP( "lvoffcv", BSIM4_MOD_LVOFFCV, IF_REAL, "Length dependence of voffcv"),
IOP( "lxrcrg1", BSIM4_MOD_LXRCRG1, IF_REAL, "Length dependence of xrcrg1"),
IOP( "lxrcrg2", BSIM4_MOD_LXRCRG2, IF_REAL, "Length dependence of xrcrg2"),
IOP( "leu", BSIM4_MOD_LEU, IF_REAL, "Length dependence of eu"),
IOP( "llambda", BSIM4_MOD_LLAMBDA, IF_REAL, "Length dependence of lambda"),
IOP( "lvtl", BSIM4_MOD_LVTL, IF_REAL, " Length dependence of vtl"),
IOP( "lxn", BSIM4_MOD_LXN, IF_REAL, " Length dependence of xn"),
IOP( "leu", BSIM4_MOD_LEU, IF_REAL, " Length dependence of eu"),
IOP( "lvfbsdoff", BSIM4_MOD_LVFBSDOFF, IF_REAL, "Length dependence of vfbsdoff"),
IOP( "ltvfbsdoff", BSIM4_MOD_LTVFBSDOFF, IF_REAL, "Length dependence of tvfbsdoff"),
IOP( "ltvoff", BSIM4_MOD_LTVOFF, IF_REAL, "Length dependence of tvoff"),
IOP( "wcdsc", BSIM4_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"),
IOP( "wcdscb", BSIM4_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"),
IOP( "wcdscd", BSIM4_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"),
@ -514,6 +617,10 @@ IOP( "wub", BSIM4_MOD_WUB, IF_REAL, "Width dependence of ub"),
IOP( "wub1", BSIM4_MOD_WUB1, IF_REAL, "Width dependence of ub1"),
IOP( "wuc", BSIM4_MOD_WUC, IF_REAL, "Width dependence of uc"),
IOP( "wuc1", BSIM4_MOD_WUC1, IF_REAL, "Width dependence of uc1"),
IOP( "wud", BSIM4_MOD_WUD, IF_REAL, "Width dependence of ud"),
IOP( "wud1", BSIM4_MOD_WUD1, IF_REAL, "Width dependence of ud1"),
IOP( "wup", BSIM4_MOD_WUP, IF_REAL, "Width dependence of up"),
IOP( "wlp", BSIM4_MOD_WLP, IF_REAL, "Width dependence of lp"),
IOP( "wu0", BSIM4_MOD_WU0, IF_REAL, "Width dependence of u0"),
IOP( "wute", BSIM4_MOD_WUTE, IF_REAL, "Width dependence of ute"),
IOP( "wvoff", BSIM4_MOD_WVOFF, IF_REAL, "Width dependence of voff"),
@ -554,6 +661,7 @@ IOP( "wcle", BSIM4_MOD_WCLE, IF_REAL, "Width dependence of cle"),
IOP( "walpha0", BSIM4_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"),
IOP( "walpha1", BSIM4_MOD_WALPHA1, IF_REAL, "Width dependence of alpha1"),
IOP( "wbeta0", BSIM4_MOD_WBETA0, IF_REAL, "Width dependence of beta0"),
IOP( "wagidl", BSIM4_MOD_WAGIDL, IF_REAL, "Width dependence of agidl"),
IOP( "wbgidl", BSIM4_MOD_WBGIDL, IF_REAL, "Width dependence of bgidl"),
IOP( "wcgidl", BSIM4_MOD_WCGIDL, IF_REAL, "Width dependence of cgidl"),
@ -585,7 +693,13 @@ IOP( "wnoff", BSIM4_MOD_WNOFF, IF_REAL, "Width dependence of noff"),
IOP( "wvoffcv", BSIM4_MOD_WVOFFCV, IF_REAL, "Width dependence of voffcv"),
IOP( "wxrcrg1", BSIM4_MOD_WXRCRG1, IF_REAL, "Width dependence of xrcrg1"),
IOP( "wxrcrg2", BSIM4_MOD_WXRCRG2, IF_REAL, "Width dependence of xrcrg2"),
IOP( "wlambda", BSIM4_MOD_WLAMBDA, IF_REAL, "Width dependence of lambda"),
IOP( "wvtl", BSIM4_MOD_WVTL, IF_REAL, "Width dependence of vtl"),
IOP( "wxn", BSIM4_MOD_WXN, IF_REAL, "Width dependence of xn"),
IOP( "weu", BSIM4_MOD_WEU, IF_REAL, "Width dependence of eu"),
IOP( "wvfbsdoff", BSIM4_MOD_WVFBSDOFF, IF_REAL, "Width dependence of vfbsdoff"),
IOP( "wtvfbsdoff", BSIM4_MOD_WTVFBSDOFF, IF_REAL, "Width dependence of tvfbsdoff"),
IOP( "wtvoff", BSIM4_MOD_WTVOFF, IF_REAL, "Width dependence of tvoff"),
IOP( "pcdsc", BSIM4_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"),
IOP( "pcdscb", BSIM4_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"),
@ -638,6 +752,10 @@ IOP( "pub", BSIM4_MOD_PUB, IF_REAL, "Cross-term dependence of ub"),
IOP( "pub1", BSIM4_MOD_PUB1, IF_REAL, "Cross-term dependence of ub1"),
IOP( "puc", BSIM4_MOD_PUC, IF_REAL, "Cross-term dependence of uc"),
IOP( "puc1", BSIM4_MOD_PUC1, IF_REAL, "Cross-term dependence of uc1"),
IOP( "pud", BSIM4_MOD_PUD, IF_REAL, "Cross-term dependence of ud"),
IOP( "pud1", BSIM4_MOD_PUD1, IF_REAL, "Cross-term dependence of ud1"),
IOP( "pup", BSIM4_MOD_PUP, IF_REAL, "Cross-term dependence of up"),
IOP( "plp", BSIM4_MOD_PLP, IF_REAL, "Cross-term dependence of lp"),
IOP( "pu0", BSIM4_MOD_PU0, IF_REAL, "Cross-term dependence of u0"),
IOP( "pute", BSIM4_MOD_PUTE, IF_REAL, "Cross-term dependence of ute"),
IOP( "pvoff", BSIM4_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"),
@ -678,6 +796,7 @@ IOP( "pcle", BSIM4_MOD_PCLE, IF_REAL, "Cross-term dependence of cle"),
IOP( "palpha0", BSIM4_MOD_PALPHA0, IF_REAL, "Cross-term dependence of alpha0"),
IOP( "palpha1", BSIM4_MOD_PALPHA1, IF_REAL, "Cross-term dependence of alpha1"),
IOP( "pbeta0", BSIM4_MOD_PBETA0, IF_REAL, "Cross-term dependence of beta0"),
IOP( "pagidl", BSIM4_MOD_PAGIDL, IF_REAL, "Cross-term dependence of agidl"),
IOP( "pbgidl", BSIM4_MOD_PBGIDL, IF_REAL, "Cross-term dependence of bgidl"),
IOP( "pcgidl", BSIM4_MOD_PCGIDL, IF_REAL, "Cross-term dependence of cgidl"),
@ -709,13 +828,61 @@ IOP( "pnoff", BSIM4_MOD_PNOFF, IF_REAL, "Cross-term dependence of noff"),
IOP( "pvoffcv", BSIM4_MOD_PVOFFCV, IF_REAL, "Cross-term dependence of voffcv"),
IOP( "pxrcrg1", BSIM4_MOD_PXRCRG1, IF_REAL, "Cross-term dependence of xrcrg1"),
IOP( "pxrcrg2", BSIM4_MOD_PXRCRG2, IF_REAL, "Cross-term dependence of xrcrg2"),
IOP( "plambda", BSIM4_MOD_PLAMBDA, IF_REAL, "Cross-term dependence of lambda"),
IOP( "pvtl", BSIM4_MOD_PVTL, IF_REAL, "Cross-term dependence of vtl"),
IOP( "pxn", BSIM4_MOD_PXN, IF_REAL, "Cross-term dependence of xn"),
IOP( "peu", BSIM4_MOD_PEU, IF_REAL, "Cross-term dependence of eu"),
IOP( "pvfbsdoff", BSIM4_MOD_PVFBSDOFF, IF_REAL, "Cross-term dependence of vfbsdoff"),
IOP( "ptvfbsdoff", BSIM4_MOD_PTVFBSDOFF, IF_REAL, "Cross-term dependence of tvfbsdoff"),
IOP( "ptvoff", BSIM4_MOD_PTVOFF, IF_REAL, "Cross-term dependence of tvoff"),
/* stress effect*/
IOP( "saref", BSIM4_MOD_SAREF, IF_REAL, "Reference distance between OD edge to poly of one side"),
IOP( "sbref", BSIM4_MOD_SBREF, IF_REAL, "Reference distance between OD edge to poly of the other side"),
IOP( "wlod", BSIM4_MOD_WLOD, IF_REAL, "Width parameter for stress effect"),
IOP( "ku0", BSIM4_MOD_KU0, IF_REAL, "Mobility degradation/enhancement coefficient for LOD"),
IOP( "kvsat", BSIM4_MOD_KVSAT, IF_REAL, "Saturation velocity degradation/enhancement parameter for LOD"),
IOP( "kvth0", BSIM4_MOD_KVTH0, IF_REAL, "Threshold degradation/enhancement parameter for LOD"),
IOP( "tku0", BSIM4_MOD_TKU0, IF_REAL, "Temperature coefficient of KU0"),
IOP( "llodku0", BSIM4_MOD_LLODKU0, IF_REAL, "Length parameter for u0 LOD effect"),
IOP( "wlodku0", BSIM4_MOD_WLODKU0, IF_REAL, "Width parameter for u0 LOD effect"),
IOP( "llodvth", BSIM4_MOD_LLODVTH, IF_REAL, "Length parameter for vth LOD effect"),
IOP( "wlodvth", BSIM4_MOD_WLODVTH, IF_REAL, "Width parameter for vth LOD effect"),
IOP( "lku0", BSIM4_MOD_LKU0, IF_REAL, "Length dependence of ku0"),
IOP( "wku0", BSIM4_MOD_WKU0, IF_REAL, "Width dependence of ku0"),
IOP( "pku0", BSIM4_MOD_PKU0, IF_REAL, "Cross-term dependence of ku0"),
IOP( "lkvth0", BSIM4_MOD_LKVTH0, IF_REAL, "Length dependence of kvth0"),
IOP( "wkvth0", BSIM4_MOD_WKVTH0, IF_REAL, "Width dependence of kvth0"),
IOP( "pkvth0", BSIM4_MOD_PKVTH0, IF_REAL, "Cross-term dependence of kvth0"),
IOP( "stk2", BSIM4_MOD_STK2, IF_REAL, "K2 shift factor related to stress effect on vth"),
IOP( "lodk2", BSIM4_MOD_LODK2, IF_REAL, "K2 shift modification factor for stress effect"),
IOP( "steta0", BSIM4_MOD_STETA0, IF_REAL, "eta0 shift factor related to stress effect on vth"),
IOP( "lodeta0", BSIM4_MOD_LODETA0, IF_REAL, "eta0 shift modification factor for stress effect"),
/* Well Proximity Effect */
IOP( "web", BSIM4_MOD_WEB, IF_REAL, "Coefficient for SCB"),
IOP( "wec", BSIM4_MOD_WEC, IF_REAL, "Coefficient for SCC"),
IOP( "kvth0we", BSIM4_MOD_KVTH0WE, IF_REAL, "Threshold shift factor for well proximity effect"),
IOP( "k2we", BSIM4_MOD_K2WE, IF_REAL, " K2 shift factor for well proximity effect "),
IOP( "ku0we", BSIM4_MOD_KU0WE, IF_REAL, " Mobility degradation factor for well proximity effect "),
IOP( "scref", BSIM4_MOD_SCREF, IF_REAL, " Reference distance to calculate SCA, SCB and SCC"),
IOP( "wpemod", BSIM4_MOD_WPEMOD, IF_REAL, " Flag for WPE model (WPEMOD=1 to activate this model) "),
IOP( "lkvth0we", BSIM4_MOD_LKVTH0WE, IF_REAL, "Length dependence of kvth0we"),
IOP( "lk2we", BSIM4_MOD_LK2WE, IF_REAL, " Length dependence of k2we "),
IOP( "lku0we", BSIM4_MOD_LKU0WE, IF_REAL, " Length dependence of ku0we "),
IOP( "wkvth0we", BSIM4_MOD_WKVTH0WE, IF_REAL, "Width dependence of kvth0we"),
IOP( "wk2we", BSIM4_MOD_WK2WE, IF_REAL, " Width dependence of k2we "),
IOP( "wku0we", BSIM4_MOD_WKU0WE, IF_REAL, " Width dependence of ku0we "),
IOP( "pkvth0we", BSIM4_MOD_PKVTH0WE, IF_REAL, "Cross-term dependence of kvth0we"),
IOP( "pk2we", BSIM4_MOD_PK2WE, IF_REAL, " Cross-term dependence of k2we "),
IOP( "pku0we", BSIM4_MOD_PKU0WE, IF_REAL, " Cross-term dependence of ku0we "),
IOP( "noia", BSIM4_MOD_NOIA, IF_REAL, "Flicker noise parameter"),
IOP( "noib", BSIM4_MOD_NOIB, IF_REAL, "Flicker noise parameter"),
IOP( "noic", BSIM4_MOD_NOIC, IF_REAL, "Flicker noise parameter"),
IOP( "tnoia", BSIM4_MOD_TNOIA, IF_REAL, "Thermal noise parameter"),
IOP( "tnoib", BSIM4_MOD_TNOIB, IF_REAL, "Thermal noise parameter"),
IOP( "rnoia", BSIM4_MOD_RNOIA, IF_REAL, "Thermal noise coefficient"),
IOP( "rnoib", BSIM4_MOD_RNOIB, IF_REAL, "Thermal noise coefficient"),
IOP( "ntnoi", BSIM4_MOD_NTNOI, IF_REAL, "Thermal noise parameter"),
IOP( "em", BSIM4_MOD_EM, IF_REAL, "Flicker noise parameter"),
IOP( "ef", BSIM4_MOD_EF, IF_REAL, "Flicker noise frequency exponent"),
@ -739,6 +906,3 @@ int BSIM4pTSize = NUMELEMS(BSIM4pTable);
int BSIM4mPTSize = NUMELEMS(BSIM4mPTable);
int BSIM4iSize = sizeof(BSIM4instance);
int BSIM4mSize = sizeof(BSIM4model);

View File

@ -1,21 +1,19 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4acld.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4acld.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi 10/05/2001
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
@ -32,8 +30,8 @@ double xcggbr, xcgdbr, xcgsbr, xcgbbr, xcggbi, xcgdbi, xcgsbi, xcgbbi;
double Cggr, Cgdr, Cgsr, Cgbr, Cggi, Cgdi, Cgsi, Cgbi;
double xcddbr, xcdgbr, xcdsbr, xcdbbr, xcsdbr, xcsgbr, xcssbr, xcsbbr;
double xcddbi, xcdgbi, xcdsbi, xcdbbi, xcsdbi, xcsgbi, xcssbi, xcsbbi;
double xcdbdb, xcsbsb, xcgmgmb, xcgmdb, xcgmsb, xcdgmb, xcsgmb;
double xcgmbb, xcbgmb;
double xcdbdb, xcsbsb=0.0, xcgmgmb=0.0, xcgmdb=0.0, xcgmsb=0.0, xcdgmb, xcsgmb;
double xcgmbb=0.0, xcbgmb;
double capbd, capbs, omega;
double gstot, gstotd, gstotg, gstots, gstotb, gspr;
double gdtot, gdtotd, gdtotg, gdtots, gdtotb, gdpr;
@ -44,22 +42,24 @@ double gIgtotg, gIgtotd, gIgtots, gIgtotb;
double cgso, cgdo, cgbo;
double gbspsp, gbbdp, gbbsp, gbspg, gbspb;
double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11;
double Csg, Csd, Css, Csb;
double T0=0.0, T1, T2, T3;
double Csg, Csd, Css;
double Cdgr, Cddr, Cdsr, Cdbr, Csgr, Csdr, Cssr, Csbr;
double Cdgi, Cddi, Cdsi, Cdbi, Csgi, Csdi, Cssi, Csbi;
double gmr, gmi, gmbsr, gmbsi, gdsr, gdsi;
double FwdSumr, RevSumr, Gmr, Gmbsr, Gdsr;
double FwdSumi, RevSumi, Gmi, Gmbsi, Gdsi;
double FwdSumr, RevSumr, Gmr, Gmbsr;
double FwdSumi, RevSumi, Gmi, Gmbsi;
struct bsim4SizeDependParam *pParam;
double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls;
double m;
omega = ckt->CKTomega;
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here!= NULL;
here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
pParam = here->pParam;
pParam = here->pParam;
capbd = here->BSIM4capbd;
capbs = here->BSIM4capbs;
cgso = here->BSIM4cgso;
@ -450,6 +450,7 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
/*
* Loading AC matrix
*/
m = here->BSIM4m;
if (!model->BSIM4rdsMod)
{ gdpr = here->BSIM4drainConductance;
@ -468,122 +469,122 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
geltd = here->BSIM4grgeltd;
if (here->BSIM4rgateMod == 1)
{ *(here->BSIM4GEgePtr) += geltd;
*(here->BSIM4GPgePtr) -= geltd;
*(here->BSIM4GEgpPtr) -= geltd;
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GPgePtr) -= m * geltd;
*(here->BSIM4GEgpPtr) -= m * geltd;
*(here->BSIM4GPgpPtr +1) += xcggbr;
*(here->BSIM4GPgpPtr) += geltd + xcggbi + gIgtotg;
*(here->BSIM4GPdpPtr +1) += xcgdbr;
*(here->BSIM4GPdpPtr) += xcgdbi + gIgtotd;
*(here->BSIM4GPspPtr +1) += xcgsbr;
*(here->BSIM4GPspPtr) += xcgsbi + gIgtots;
*(here->BSIM4GPbpPtr +1) += xcgbbr;
*(here->BSIM4GPbpPtr) += xcgbbi + gIgtotb;
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) += m * (geltd + xcggbi + gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb);
} /* WDLiu: gcrg already subtracted from all gcrgg below */
else if (here->BSIM4rgateMod == 2)
{ *(here->BSIM4GEgePtr) += gcrg;
*(here->BSIM4GEgpPtr) += gcrgg;
*(here->BSIM4GEdpPtr) += gcrgd;
*(here->BSIM4GEspPtr) += gcrgs;
*(here->BSIM4GEbpPtr) += gcrgb;
{ *(here->BSIM4GEgePtr) += m * gcrg;
*(here->BSIM4GEgpPtr) += m * gcrgg;
*(here->BSIM4GEdpPtr) += m * gcrgd;
*(here->BSIM4GEspPtr) += m * gcrgs;
*(here->BSIM4GEbpPtr) += m * gcrgb;
*(here->BSIM4GPgePtr) -= gcrg;
*(here->BSIM4GPgpPtr +1) += xcggbr;
*(here->BSIM4GPgpPtr) -= gcrgg - xcggbi - gIgtotg;
*(here->BSIM4GPdpPtr +1) += xcgdbr;
*(here->BSIM4GPdpPtr) -= gcrgd - xcgdbi - gIgtotd;
*(here->BSIM4GPspPtr +1) += xcgsbr;
*(here->BSIM4GPspPtr) -= gcrgs - xcgsbi - gIgtots;
*(here->BSIM4GPbpPtr +1) += xcgbbr;
*(here->BSIM4GPbpPtr) -= gcrgb - xcgbbi - gIgtotb;
*(here->BSIM4GPgePtr) -= m * gcrg;
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb);
}
else if (here->BSIM4rgateMod == 3)
{ *(here->BSIM4GEgePtr) += geltd;
*(here->BSIM4GEgmPtr) -= geltd;
*(here->BSIM4GMgePtr) -= geltd;
*(here->BSIM4GMgmPtr) += geltd + gcrg;
*(here->BSIM4GMgmPtr +1) += xcgmgmb;
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GEgmPtr) -= m * geltd;
*(here->BSIM4GMgePtr) -= m * geltd;
*(here->BSIM4GMgmPtr) += m * (geltd + gcrg);
*(here->BSIM4GMgmPtr +1) += m * xcgmgmb;
*(here->BSIM4GMdpPtr) += gcrgd;
*(here->BSIM4GMdpPtr +1) += xcgmdb;
*(here->BSIM4GMgpPtr) += gcrgg;
*(here->BSIM4GMspPtr) += gcrgs;
*(here->BSIM4GMspPtr +1) += xcgmsb;
*(here->BSIM4GMbpPtr) += gcrgb;
*(here->BSIM4GMbpPtr +1) += xcgmbb;
*(here->BSIM4GMdpPtr) += m * gcrgd;
*(here->BSIM4GMdpPtr +1) += m * xcgmdb;
*(here->BSIM4GMgpPtr) += m * gcrgg;
*(here->BSIM4GMspPtr) += m * gcrgs;
*(here->BSIM4GMspPtr +1) += m * xcgmsb;
*(here->BSIM4GMbpPtr) += m * gcrgb;
*(here->BSIM4GMbpPtr +1) += m * xcgmbb;
*(here->BSIM4DPgmPtr +1) += xcdgmb;
*(here->BSIM4GPgmPtr) -= gcrg;
*(here->BSIM4SPgmPtr +1) += xcsgmb;
*(here->BSIM4BPgmPtr +1) += xcbgmb;
*(here->BSIM4DPgmPtr +1) += m * xcdgmb;
*(here->BSIM4GPgmPtr) -= m * gcrg;
*(here->BSIM4SPgmPtr +1) += m * xcsgmb;
*(here->BSIM4BPgmPtr +1) += m * xcbgmb;
*(here->BSIM4GPgpPtr) -= gcrgg - xcggbi - gIgtotg;
*(here->BSIM4GPgpPtr +1) += xcggbr;
*(here->BSIM4GPdpPtr) -= gcrgd - xcgdbi - gIgtotd;
*(here->BSIM4GPdpPtr +1) += xcgdbr;
*(here->BSIM4GPspPtr) -= gcrgs - xcgsbi - gIgtots;
*(here->BSIM4GPspPtr +1) += xcgsbr;
*(here->BSIM4GPbpPtr) -= gcrgb - xcgbbi - gIgtotb;
*(here->BSIM4GPbpPtr +1) += xcgbbr;
*(here->BSIM4GPgpPtr) -= m * (gcrgg - xcggbi - gIgtotg);
*(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPdpPtr) -= m * (gcrgd - xcgdbi - gIgtotd);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPspPtr) -= m * (gcrgs - xcgsbi - gIgtots);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPbpPtr) -= m * (gcrgb - xcgbbi - gIgtotb);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
}
else
{ *(here->BSIM4GPgpPtr +1) += xcggbr;
*(here->BSIM4GPgpPtr) += xcggbi + gIgtotg;
*(here->BSIM4GPdpPtr +1) += xcgdbr;
*(here->BSIM4GPdpPtr) += xcgdbi + gIgtotd;
*(here->BSIM4GPspPtr +1) += xcgsbr;
*(here->BSIM4GPspPtr) += xcgsbi + gIgtots;
*(here->BSIM4GPbpPtr +1) += xcgbbr;
*(here->BSIM4GPbpPtr) += xcgbbi + gIgtotb;
{ *(here->BSIM4GPgpPtr +1) += m * xcggbr;
*(here->BSIM4GPgpPtr) += m * (xcggbi + gIgtotg);
*(here->BSIM4GPdpPtr +1) += m * xcgdbr;
*(here->BSIM4GPdpPtr) += m * (xcgdbi + gIgtotd);
*(here->BSIM4GPspPtr +1) += m * xcgsbr;
*(here->BSIM4GPspPtr) += m * (xcgsbi + gIgtots);
*(here->BSIM4GPbpPtr +1) += m * xcgbbr;
*(here->BSIM4GPbpPtr) += m * (xcgbbi + gIgtotb);
}
if (model->BSIM4rdsMod)
{ (*(here->BSIM4DgpPtr) += gdtotg);
(*(here->BSIM4DspPtr) += gdtots);
(*(here->BSIM4DbpPtr) += gdtotb);
(*(here->BSIM4SdpPtr) += gstotd);
(*(here->BSIM4SgpPtr) += gstotg);
(*(here->BSIM4SbpPtr) += gstotb);
{ (*(here->BSIM4DgpPtr) += m * gdtotg);
(*(here->BSIM4DspPtr) += m * gdtots);
(*(here->BSIM4DbpPtr) += m * gdtotb);
(*(here->BSIM4SdpPtr) += m * gstotd);
(*(here->BSIM4SgpPtr) += m * gstotg);
(*(here->BSIM4SbpPtr) += m * gstotb);
}
*(here->BSIM4DPdpPtr +1) += xcddbr + gdsi + RevSumi;
*(here->BSIM4DPdpPtr) += gdpr + xcddbi + gdsr + here->BSIM4gbd
- gdtotd + RevSumr + gbdpdp - gIdtotd;
*(here->BSIM4DPdPtr) -= gdpr + gdtot;
*(here->BSIM4DPgpPtr +1) += xcdgbr + Gmi;
*(here->BSIM4DPgpPtr) += Gmr + xcdgbi - gdtotg + gbdpg - gIdtotg;
*(here->BSIM4DPspPtr +1) += xcdsbr - gdsi - FwdSumi;
*(here->BSIM4DPspPtr) -= gdsr - xcdsbi + FwdSumr + gdtots - gbdpsp + gIdtots;
*(here->BSIM4DPbpPtr +1) += xcdbbr + Gmbsi;
*(here->BSIM4DPbpPtr) -= gjbd + gdtotb - xcdbbi - Gmbsr - gbdpb + gIdtotb;
*(here->BSIM4DPdpPtr +1) += m * (xcddbr + gdsi + RevSumi);
*(here->BSIM4DPdpPtr) += m * (gdpr + xcddbi + gdsr + here->BSIM4gbd
- gdtotd + RevSumr + gbdpdp - gIdtotd);
*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot);
*(here->BSIM4DPgpPtr +1) += m * (xcdgbr + Gmi);
*(here->BSIM4DPgpPtr) += m * (Gmr + xcdgbi - gdtotg + gbdpg - gIdtotg);
*(here->BSIM4DPspPtr +1) += m * (xcdsbr - gdsi - FwdSumi);
*(here->BSIM4DPspPtr) -= m * (gdsr - xcdsbi + FwdSumr + gdtots - gbdpsp + gIdtots);
*(here->BSIM4DPbpPtr +1) += m * (xcdbbr + Gmbsi);
*(here->BSIM4DPbpPtr) -= m * (gjbd + gdtotb - xcdbbi - Gmbsr - gbdpb + gIdtotb);
*(here->BSIM4DdpPtr) -= gdpr - gdtotd;
*(here->BSIM4DdPtr) += gdpr + gdtot;
*(here->BSIM4DdpPtr) -= m * (gdpr - gdtotd);
*(here->BSIM4DdPtr) += m * (gdpr + gdtot);
*(here->BSIM4SPdpPtr +1) += xcsdbr - gdsi - RevSumi;
*(here->BSIM4SPdpPtr) -= gdsr - xcsdbi + gstotd + RevSumr - gbspdp + gIstotd;
*(here->BSIM4SPgpPtr +1) += xcsgbr - Gmi;
*(here->BSIM4SPgpPtr) -= Gmr - xcsgbi + gstotg - gbspg + gIstotg;
*(here->BSIM4SPspPtr +1) += xcssbr + gdsi + FwdSumi;
*(here->BSIM4SPspPtr) += gspr + xcssbi + gdsr + here->BSIM4gbs
- gstots + FwdSumr + gbspsp - gIstots;
*(here->BSIM4SPsPtr) -= gspr + gstot;
*(here->BSIM4SPbpPtr +1) += xcsbbr - Gmbsi;
*(here->BSIM4SPbpPtr) -= gjbs + gstotb - xcsbbi + Gmbsr - gbspb + gIstotb;
*(here->BSIM4SPdpPtr +1) += m * (xcsdbr - gdsi - RevSumi);
*(here->BSIM4SPdpPtr) -= m * (gdsr - xcsdbi + gstotd + RevSumr - gbspdp + gIstotd);
*(here->BSIM4SPgpPtr +1) += m * (xcsgbr - Gmi);
*(here->BSIM4SPgpPtr) -= m * (Gmr - xcsgbi + gstotg - gbspg + gIstotg);
*(here->BSIM4SPspPtr +1) += m * (xcssbr + gdsi + FwdSumi);
*(here->BSIM4SPspPtr) += m * (gspr + xcssbi + gdsr + here->BSIM4gbs
- gstots + FwdSumr + gbspsp - gIstots);
*(here->BSIM4SPsPtr) -= m * (gspr + gstot);
*(here->BSIM4SPbpPtr +1) += m * (xcsbbr - Gmbsi);
*(here->BSIM4SPbpPtr) -= m * (gjbs + gstotb - xcsbbi + Gmbsr - gbspb + gIstotb);
*(here->BSIM4SspPtr) -= gspr - gstots;
*(here->BSIM4SsPtr) += gspr + gstot;
*(here->BSIM4SspPtr) -= m * (gspr - gstots);
*(here->BSIM4SsPtr) += m * (gspr + gstot);
*(here->BSIM4BPdpPtr +1) += xcbdb;
*(here->BSIM4BPdpPtr) -= gjbd - gbbdp + gIbtotd;
*(here->BSIM4BPgpPtr +1) += xcbgb;
*(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + gIbtotg;
*(here->BSIM4BPspPtr +1) += xcbsb;
*(here->BSIM4BPspPtr) -= gjbs - gbbsp + gIbtots;
*(here->BSIM4BPbpPtr +1) += xcbbb;
*(here->BSIM4BPbpPtr) += gjbd + gjbs - here->BSIM4gbbs
- gIbtotb;
*(here->BSIM4BPdpPtr +1) += m * xcbdb;
*(here->BSIM4BPdpPtr) -= m * (gjbd - gbbdp + gIbtotd);
*(here->BSIM4BPgpPtr +1) += m * xcbgb;
*(here->BSIM4BPgpPtr) -= m * (here->BSIM4gbgs + gIbtotg);
*(here->BSIM4BPspPtr +1) += m * xcbsb;
*(here->BSIM4BPspPtr) -= m * (gjbs - gbbsp + gIbtots);
*(here->BSIM4BPbpPtr +1) += m * xcbbb;
*(here->BSIM4BPbpPtr) += m * (gjbd + gjbs - here->BSIM4gbbs
- gIbtotb);
ggidld = here->BSIM4ggidld;
ggidlg = here->BSIM4ggidlg;
ggidlb = here->BSIM4ggidlb;
@ -592,58 +593,58 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
ggislb = here->BSIM4ggislb;
/* stamp gidl */
(*(here->BSIM4DPdpPtr) += ggidld);
(*(here->BSIM4DPgpPtr) += ggidlg);
(*(here->BSIM4DPspPtr) -= (ggidlg + ggidld) + ggidlb);
(*(here->BSIM4DPbpPtr) += ggidlb);
(*(here->BSIM4BPdpPtr) -= ggidld);
(*(here->BSIM4BPgpPtr) -= ggidlg);
(*(here->BSIM4BPspPtr) += (ggidlg + ggidld) + ggidlb);
(*(here->BSIM4BPbpPtr) -= ggidlb);
(*(here->BSIM4DPdpPtr) += m * ggidld);
(*(here->BSIM4DPgpPtr) += m * ggidlg);
(*(here->BSIM4DPspPtr) -= m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4DPbpPtr) += m * ggidlb);
(*(here->BSIM4BPdpPtr) -= m * ggidld);
(*(here->BSIM4BPgpPtr) -= m * ggidlg);
(*(here->BSIM4BPspPtr) += m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4BPbpPtr) -= m * ggidlb);
/* stamp gisl */
(*(here->BSIM4SPdpPtr) -= (ggisls + ggislg) + ggislb);
(*(here->BSIM4SPgpPtr) += ggislg);
(*(here->BSIM4SPspPtr) += ggisls);
(*(here->BSIM4SPbpPtr) += ggislb);
(*(here->BSIM4BPdpPtr) += (ggislg + ggisls) + ggislb);
(*(here->BSIM4BPgpPtr) -= ggislg);
(*(here->BSIM4BPspPtr) -= ggisls);
(*(here->BSIM4BPbpPtr) -= ggislb);
(*(here->BSIM4SPdpPtr) -= m * ((ggisls + ggislg) + ggislb));
(*(here->BSIM4SPgpPtr) += m * ggislg);
(*(here->BSIM4SPspPtr) += m * ggisls);
(*(here->BSIM4SPbpPtr) += m * ggislb);
(*(here->BSIM4BPdpPtr) += m * ((ggislg + ggisls) + ggislb));
(*(here->BSIM4BPgpPtr) -= m * ggislg);
(*(here->BSIM4BPspPtr) -= m * ggisls);
(*(here->BSIM4BPbpPtr) -= m * ggislb);
if (here->BSIM4rbodyMod)
{ (*(here->BSIM4DPdbPtr +1) += xcdbdb);
(*(here->BSIM4DPdbPtr) -= here->BSIM4gbd);
(*(here->BSIM4SPsbPtr +1) += xcsbsb);
(*(here->BSIM4SPsbPtr) -= here->BSIM4gbs);
{ (*(here->BSIM4DPdbPtr +1) += m * xcdbdb);
(*(here->BSIM4DPdbPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4SPsbPtr +1) += m * xcsbsb);
(*(here->BSIM4SPsbPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4DBdpPtr +1) += xcdbdb);
(*(here->BSIM4DBdpPtr) -= here->BSIM4gbd);
(*(here->BSIM4DBdbPtr +1) -= xcdbdb);
(*(here->BSIM4DBdbPtr) += here->BSIM4gbd + here->BSIM4grbpd
+ here->BSIM4grbdb);
(*(here->BSIM4DBbpPtr) -= here->BSIM4grbpd);
(*(here->BSIM4DBbPtr) -= here->BSIM4grbdb);
(*(here->BSIM4DBdpPtr +1) += m * xcdbdb);
(*(here->BSIM4DBdpPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4DBdbPtr +1) -= m * xcdbdb);
(*(here->BSIM4DBdbPtr) += m * (here->BSIM4gbd + here->BSIM4grbpd
+ here->BSIM4grbdb));
(*(here->BSIM4DBbpPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4DBbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BPdbPtr) -= here->BSIM4grbpd);
(*(here->BSIM4BPbPtr) -= here->BSIM4grbpb);
(*(here->BSIM4BPsbPtr) -= here->BSIM4grbps);
(*(here->BSIM4BPbpPtr) += here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb);
(*(here->BSIM4BPdbPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4BPbPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BPsbPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4BPbpPtr) += m * (here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb));
/* WDLiu: (-here->BSIM4gbbs) already added to BPbpPtr */
(*(here->BSIM4SBspPtr +1) += xcsbsb);
(*(here->BSIM4SBspPtr) -= here->BSIM4gbs);
(*(here->BSIM4SBbpPtr) -= here->BSIM4grbps);
(*(here->BSIM4SBbPtr) -= here->BSIM4grbsb);
(*(here->BSIM4SBsbPtr +1) -= xcsbsb);
(*(here->BSIM4SBsbPtr) += here->BSIM4gbs
+ here->BSIM4grbps + here->BSIM4grbsb);
(*(here->BSIM4SBspPtr +1) += m * xcsbsb);
(*(here->BSIM4SBspPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4SBbpPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4SBbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4SBsbPtr +1) -= m * xcsbsb);
(*(here->BSIM4SBsbPtr) += m * (here->BSIM4gbs
+ here->BSIM4grbps + here->BSIM4grbsb));
(*(here->BSIM4BdbPtr) -= here->BSIM4grbdb);
(*(here->BSIM4BbpPtr) -= here->BSIM4grbpb);
(*(here->BSIM4BsbPtr) -= here->BSIM4grbsb);
(*(here->BSIM4BbPtr) += here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb);
(*(here->BSIM4BdbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BbpPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BsbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4BbPtr) += m * (here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb));
}
@ -654,7 +655,7 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
* The charge node is isolated from the instance.
*/
if (here->BSIM4trnqsMod)
{ (*(here->BSIM4QqPtr) += 1.0);
{ (*(here->BSIM4QqPtr) += m * 1.0);
(*(here->BSIM4QgpPtr) += 0.0);
(*(here->BSIM4QdpPtr) += 0.0);
(*(here->BSIM4QspPtr) += 0.0);

View File

@ -1,24 +1,24 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/27/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4ask.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4ask.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4ask(ckt,inst,which,value,select)
@ -37,7 +37,10 @@ BSIM4instance *here = (BSIM4instance*)inst;
case BSIM4_W:
value->rValue = here->BSIM4w;
return(OK);
case BSIM4_NF:
case BSIM4_M:
value->rValue = here->BSIM4m;
return(OK);
case BSIM4_NF:
value->rValue = here->BSIM4nf;
return(OK);
case BSIM4_MIN:
@ -64,6 +67,28 @@ BSIM4instance *here = (BSIM4instance*)inst;
case BSIM4_OFF:
value->rValue = here->BSIM4off;
return(OK);
case BSIM4_SA:
value->rValue = here->BSIM4sa ;
return(OK);
case BSIM4_SB:
value->rValue = here->BSIM4sb ;
return(OK);
case BSIM4_SD:
value->rValue = here->BSIM4sd ;
return(OK);
case BSIM4_SCA:
value->rValue = here->BSIM4sca ;
return(OK);
case BSIM4_SCB:
value->rValue = here->BSIM4scb ;
return(OK);
case BSIM4_SCC:
value->rValue = here->BSIM4scc ;
return(OK);
case BSIM4_SC:
value->rValue = here->BSIM4sc ;
return(OK);
case BSIM4_RBSB:
value->rValue = here->BSIM4rbsb;
return(OK);
@ -79,6 +104,15 @@ BSIM4instance *here = (BSIM4instance*)inst;
case BSIM4_RBPD:
value->rValue = here->BSIM4rbpd;
return(OK);
case BSIM4_DELVTO:
value->rValue = here->BSIM4delvto;
return(OK);
case BSIM4_XGW:
value->rValue = here->BSIM4xgw;
return(OK);
case BSIM4_NGCON:
value->rValue = here->BSIM4ngcon;
return(OK);
case BSIM4_TRNQSMOD:
value->iValue = here->BSIM4trnqsMod;
return(OK);
@ -205,27 +239,48 @@ BSIM4instance *here = (BSIM4instance*)inst;
case BSIM4_GBS:
value->rValue = here->BSIM4gbs;
return(OK);
case BSIM4_QB:
/* case BSIM4_QB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qb);
return(OK);
return(OK); */
case BSIM4_CQB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqb);
return(OK);
case BSIM4_QG:
/* case BSIM4_QG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qg);
return(OK);
return(OK); */
case BSIM4_CQG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqg);
return(OK);
case BSIM4_QD:
/* case BSIM4_QD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qd);
return(OK);
return(OK); */
case BSIM4_CQD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqd);
return(OK);
case BSIM4_QS:
/* case BSIM4_QS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qs);
return(OK); */
case BSIM4_QB:
value->rValue = here->BSIM4qbulk;
return(OK);
case BSIM4_QG:
value->rValue = here->BSIM4qgate;
return(OK);
case BSIM4_QS:
value->rValue = here->BSIM4qsrc;
return(OK);
case BSIM4_QD:
value->rValue = here->BSIM4qdrn;
return(OK);
case BSIM4_QDEF:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qdef);
return(OK);
case BSIM4_GCRG:
value->rValue = here->BSIM4gcrg;
return(OK);
case BSIM4_GTAU:
value->rValue = here->BSIM4gtau;
return(OK);
case BSIM4_CGGB:
value->rValue = here->BSIM4cggb;
return(OK);

View File

@ -1,24 +1,27 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4check.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4check.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "trandefs.h"
#include "const.h"
#include "sperror.h"
#include "devdefs.h"
#include "suffix.h"
int
BSIM4checkModel(model, here, ckt)
@ -33,13 +36,13 @@ FILE *fplog;
if ((fplog = fopen("bsim4.out", "w")) != NULL)
{ pParam = here->pParam;
fprintf(fplog, "BSIM4: Berkeley Short Channel IGFET Model-4\n");
fprintf(fplog, "Developed by Weidong Liu, Xuemei Xi , Xiaodong Jin, Kanyu M. Cao and Prof. Chenming Hu in 2001.\n");
fprintf(fplog, "Developed by Xuemei (Jane) Xi, Mohan Dunga, Prof. Ali Niknejad and Prof. Chenming Hu in 2003.\n");
fprintf(fplog, "\n");
fprintf(fplog, "++++++++++ BSIM4 PARAMETER CHECKING BELOW ++++++++++\n");
if (strcmp(model->BSIM4version, "4.2.1") != 0)
{ fprintf(fplog, "Warning: This model is BSIM4.2.1; you specified a wrong version number.\n");
printf("Warning: This model is BSIM4.2.1; you specified a wrong version number.\n");
if (strcmp(model->BSIM4version, "4.5.0") != 0)
{ fprintf(fplog, "Warning: This model is BSIM4.5.0; you specified a wrong version number.\n");
printf("Warning: This model is BSIM4.5.0; you specified a wrong version number.\n");
}
fprintf(fplog, "Model = %s\n", model->BSIM4modName);
@ -51,7 +54,6 @@ FILE *fplog;
}
}
if (model->BSIM4toxe <= 0.0)
{ fprintf(fplog, "Fatal: Toxe = %g is not positive.\n",
model->BSIM4toxe);
@ -86,6 +88,13 @@ FILE *fplog;
pParam->BSIM4lpe0);
Fatal_Flag = 1;
}
if (model->BSIM4lintnoi > pParam->BSIM4leff/2)
{ fprintf(fplog, "Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n",
model->BSIM4lintnoi);
printf("Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n",
model->BSIM4lintnoi);
Fatal_Flag = 1;
}
if (pParam->BSIM4lpeb < -pParam->BSIM4leff)
{ fprintf(fplog, "Fatal: Lpeb = %g is less than -Leff.\n",
pParam->BSIM4lpeb);
@ -93,14 +102,6 @@ FILE *fplog;
pParam->BSIM4lpeb);
Fatal_Flag = 1;
}
if (pParam->BSIM4phin < -0.4)
{ fprintf(fplog, "Fatal: Phin = %g is less than -0.4.\n",
pParam->BSIM4phin);
printf("Fatal: Phin = %g is less than -0.4.\n",
pParam->BSIM4phin);
Fatal_Flag = 1;
}
if (pParam->BSIM4ndep <= 0.0)
{ fprintf(fplog, "Fatal: Ndep = %g is not positive.\n",
pParam->BSIM4ndep);
@ -108,6 +109,17 @@ FILE *fplog;
pParam->BSIM4ndep);
Fatal_Flag = 1;
}
if (pParam->BSIM4phi <= 0.0)
{ fprintf(fplog, "Fatal: Phi = %g is not positive. Please check Phin and Ndep\n",
pParam->BSIM4phi);
fprintf(fplog, " Phin = %g Ndep = %g \n",
pParam->BSIM4phin, pParam->BSIM4ndep);
printf("Fatal: Phi = %g is not positive. Please check Phin and Ndep\n",
pParam->BSIM4phi);
printf(" Phin = %g Ndep = %g \n",
pParam->BSIM4phin, pParam->BSIM4ndep);
Fatal_Flag = 1;
}
if (pParam->BSIM4nsub <= 0.0)
{ fprintf(fplog, "Fatal: Nsub = %g is not positive.\n",
pParam->BSIM4nsub);
@ -166,10 +178,10 @@ FILE *fplog;
printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n");
Fatal_Flag = 1;
}
if (pParam->BSIM4u0temp <= 0.0)
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM4u0temp);
if (here->BSIM4u0temp <= 0.0)
{ fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", here->BSIM4u0temp);
printf("Fatal: u0 at current temperature = %g is not positive.\n",
pParam->BSIM4u0temp);
here->BSIM4u0temp);
Fatal_Flag = 1;
}
@ -180,10 +192,10 @@ FILE *fplog;
Fatal_Flag = 1;
}
if (pParam->BSIM4vsattemp <= 0.0)
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM4vsattemp);
if (here->BSIM4vsattemp <= 0.0)
{ fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", here->BSIM4vsattemp);
printf("Fatal: Vsat at current temperature = %g is not positive.\n",
pParam->BSIM4vsattemp);
here->BSIM4vsattemp);
Fatal_Flag = 1;
}
@ -198,12 +210,12 @@ FILE *fplog;
printf("Fatal: Drout = %g is negative.\n", pParam->BSIM4drout);
Fatal_Flag = 1;
}
if (pParam->BSIM4pscbe2 <= 0.0)
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
pParam->BSIM4pscbe2);
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4pscbe2);
}
/*if (here->BSIM4m < 1.0)
{ fprintf(fplog, "Fatal: Number of multiplier = %g is smaller than one.\n", here->BSIM4m);
printf("Fatal: Number of multiplier = %g is smaller than one.\n", here->BSIM4m);
Fatal_Flag = 1;
}*/
if (here->BSIM4nf < 1.0)
{ fprintf(fplog, "Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4nf);
@ -211,18 +223,32 @@ FILE *fplog;
Fatal_Flag = 1;
}
if((here->BSIM4sa > 0.0) && (here->BSIM4sb > 0.0) &&
((here->BSIM4nf == 1.0) || ((here->BSIM4nf > 1.0) && (here->BSIM4sd > 0.0))) )
{ if (model->BSIM4saref <= 0.0)
{ fprintf(fplog, "Fatal: SAref = %g is not positive.\n",model->BSIM4saref);
printf("Fatal: SAref = %g is not positive.\n",model->BSIM4saref);
Fatal_Flag = 1;
}
if (model->BSIM4sbref <= 0.0)
{ fprintf(fplog, "Fatal: SBref = %g is not positive.\n",model->BSIM4sbref);
printf("Fatal: SBref = %g is not positive.\n",model->BSIM4sbref);
Fatal_Flag = 1;
}
}
if ((here->BSIM4l + model->BSIM4xl) <= model->BSIM4xgl)
{ fprintf(fplog, "Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n");
printf("Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n");
Fatal_Flag = 1;
}
if (model->BSIM4ngcon < 1.0)
if (here->BSIM4ngcon < 1.0)
{ fprintf(fplog, "Fatal: The parameter ngcon cannot be smaller than one.\n");
printf("Fatal: The parameter ngcon cannot be smaller than one.\n");
Fatal_Flag = 1;
}
if ((model->BSIM4ngcon != 1.0) && (model->BSIM4ngcon != 2.0))
{ model->BSIM4ngcon = 1.0;
if ((here->BSIM4ngcon != 1.0) && (here->BSIM4ngcon != 2.0))
{ here->BSIM4ngcon = 1.0;
fprintf(fplog, "Warning: Ngcon must be equal to one or two; reset to 1.0.\n");
printf("Warning: Ngcon must be equal to one or two; reset to 1.0.\n");
}
@ -233,27 +259,61 @@ FILE *fplog;
printf("Warning: Gbmin = %g is too small.\n", model->BSIM4gbmin);
}
if (pParam->BSIM4noff < 0.1)
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
pParam->BSIM4noff);
printf("Warning: Noff = %g is too small.\n", pParam->BSIM4noff);
/* Check saturation parameters */
if (pParam->BSIM4fprout < 0.0)
{ fprintf(fplog, "Fatal: fprout = %g is negative.\n",
pParam->BSIM4fprout);
printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4fprout);
Fatal_Flag = 1;
}
if (pParam->BSIM4noff > 4.0)
{ fprintf(fplog, "Warning: Noff = %g is too large.\n",
pParam->BSIM4noff);
printf("Warning: Noff = %g is too large.\n", pParam->BSIM4noff);
if (pParam->BSIM4pdits < 0.0)
{ fprintf(fplog, "Fatal: pdits = %g is negative.\n",
pParam->BSIM4pdits);
printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4pdits);
Fatal_Flag = 1;
}
if (model->BSIM4pditsl < 0.0)
{ fprintf(fplog, "Fatal: pditsl = %g is negative.\n",
model->BSIM4pditsl);
printf("Fatal: pditsl = %g is negative.\n", model->BSIM4pditsl);
Fatal_Flag = 1;
}
if (pParam->BSIM4voffcv < -0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too small.\n",
pParam->BSIM4voffcv);
printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4voffcv);
/* Check gate current parameters */
if (model->BSIM4igbMod) {
if (pParam->BSIM4nigbinv <= 0.0)
{ fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n",
pParam->BSIM4nigbinv);
printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4nigbinv);
Fatal_Flag = 1;
}
if (pParam->BSIM4voffcv > 0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too large.\n",
pParam->BSIM4voffcv);
printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM4voffcv);
if (pParam->BSIM4nigbacc <= 0.0)
{ fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n",
pParam->BSIM4nigbacc);
printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4nigbacc);
Fatal_Flag = 1;
}
}
if (model->BSIM4igcMod) {
if (pParam->BSIM4nigc <= 0.0)
{ fprintf(fplog, "Fatal: nigc = %g is non-positive.\n",
pParam->BSIM4nigc);
printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4nigc);
Fatal_Flag = 1;
}
if (pParam->BSIM4poxedge <= 0.0)
{ fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n",
pParam->BSIM4poxedge);
printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4poxedge);
Fatal_Flag = 1;
}
if (pParam->BSIM4pigcd <= 0.0)
{ fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n",
pParam->BSIM4pigcd);
printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4pigcd);
Fatal_Flag = 1;
}
}
/* Check capacitance parameters */
if (pParam->BSIM4clc < 0.0)
@ -262,28 +322,63 @@ FILE *fplog;
Fatal_Flag = 1;
}
if (pParam->BSIM4moin < 5.0)
{ fprintf(fplog, "Warning: Moin = %g is too small.\n",
pParam->BSIM4moin);
printf("Warning: Moin = %g is too small.\n", pParam->BSIM4moin);
/* Check overlap capacitance parameters */
if (pParam->BSIM4ckappas < 0.02)
{ fprintf(fplog, "Warning: ckappas = %g is too small. Set to 0.02\n",
pParam->BSIM4ckappas);
printf("Warning: ckappas = %g is too small.\n", pParam->BSIM4ckappas);
pParam->BSIM4ckappas = 0.02;
}
if (pParam->BSIM4ckappad < 0.02)
{ fprintf(fplog, "Warning: ckappad = %g is too small. Set to 0.02\n",
pParam->BSIM4ckappad);
printf("Warning: ckappad = %g is too small.\n", pParam->BSIM4ckappad);
pParam->BSIM4ckappad = 0.02;
}
if (pParam->BSIM4moin > 25.0)
{ fprintf(fplog, "Warning: Moin = %g is too large.\n",
pParam->BSIM4moin);
printf("Warning: Moin = %g is too large.\n", pParam->BSIM4moin);
}
if(model->BSIM4capMod ==2) {
if (pParam->BSIM4acde < 0.4)
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
pParam->BSIM4acde);
printf("Warning: Acde = %g is too small.\n", pParam->BSIM4acde);
}
if (pParam->BSIM4acde > 1.6)
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
pParam->BSIM4acde);
printf("Warning: Acde = %g is too large.\n", pParam->BSIM4acde);
}
if (model->BSIM4vtss < 0.0)
{ fprintf(fplog, "Fatal: Vtss = %g is negative.\n",
model->BSIM4vtss);
printf("Fatal: Vtss = %g is negative.\n",
model->BSIM4vtss);
Fatal_Flag = 1;
}
if (model->BSIM4vtsd < 0.0)
{ fprintf(fplog, "Fatal: Vtsd = %g is negative.\n",
model->BSIM4vtsd);
printf("Fatal: Vtsd = %g is negative.\n",
model->BSIM4vtsd);
Fatal_Flag = 1;
}
if (model->BSIM4vtssws < 0.0)
{ fprintf(fplog, "Fatal: Vtssws = %g is negative.\n",
model->BSIM4vtssws);
printf("Fatal: Vtssws = %g is negative.\n",
model->BSIM4vtssws);
Fatal_Flag = 1;
}
if (model->BSIM4vtsswd < 0.0)
{ fprintf(fplog, "Fatal: Vtsswd = %g is negative.\n",
model->BSIM4vtsswd);
printf("Fatal: Vtsswd = %g is negative.\n",
model->BSIM4vtsswd);
Fatal_Flag = 1;
}
if (model->BSIM4vtsswgs < 0.0)
{ fprintf(fplog, "Fatal: Vtsswgs = %g is negative.\n",
model->BSIM4vtsswgs);
printf("Fatal: Vtsswgs = %g is negative.\n",
model->BSIM4vtsswgs);
Fatal_Flag = 1;
}
if (model->BSIM4vtsswgd < 0.0)
{ fprintf(fplog, "Fatal: Vtsswgd = %g is negative.\n",
model->BSIM4vtsswgd);
printf("Fatal: Vtsswgd = %g is negative.\n",
model->BSIM4vtsswgd);
Fatal_Flag = 1;
}
if (model->BSIM4paramChk ==1)
{
@ -373,7 +468,7 @@ FILE *fplog;
printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM4dvt0);
}
if (fabs(1.0e-6 / (pParam->BSIM4w0 + pParam->BSIM4weff)) > 10.0)
if (fabs(1.0e-8 / (pParam->BSIM4w0 + pParam->BSIM4weff)) > 10.0)
{ fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n");
printf("Warning: (W0 + Weff) may be too small.\n");
}
@ -395,14 +490,14 @@ FILE *fplog;
printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM4cdscd);
}
/* Check DIBL parameters */
if (pParam->BSIM4eta0 < 0.0)
if (here->BSIM4eta0 < 0.0)
{ fprintf(fplog, "Warning: Eta0 = %g is negative.\n",
pParam->BSIM4eta0);
printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM4eta0);
here->BSIM4eta0);
printf("Warning: Eta0 = %g is negative.\n", here->BSIM4eta0);
}
/* Check Abulk parameters */
if (fabs(1.0e-6 / (pParam->BSIM4b1 + pParam->BSIM4weff)) > 10.0)
if (fabs(1.0e-8 / (pParam->BSIM4b1 + pParam->BSIM4weff)) > 10.0)
{ fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n");
printf("Warning: (B1 + Weff) may be too small.\n");
}
@ -422,7 +517,6 @@ FILE *fplog;
pParam->BSIM4a2);
pParam->BSIM4a2 = 1.0;
pParam->BSIM4a1 = 0.0;
}
if (pParam->BSIM4prwg < 0.0)
@ -432,6 +526,7 @@ FILE *fplog;
pParam->BSIM4prwg);
pParam->BSIM4prwg = 0.0;
}
if (pParam->BSIM4rdsw < 0.0)
{ fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n",
pParam->BSIM4rdsw);
@ -440,6 +535,7 @@ FILE *fplog;
pParam->BSIM4rdsw = 0.0;
pParam->BSIM4rds0 = 0.0;
}
if (pParam->BSIM4rds0 < 0.0)
{ fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n",
pParam->BSIM4rds0);
@ -456,29 +552,44 @@ FILE *fplog;
pParam->BSIM4rdswmin = 0.0;
}
if (pParam->BSIM4pscbe2 <= 0.0)
{ fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n",
pParam->BSIM4pscbe2);
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4pscbe2);
}
if (pParam->BSIM4vsattemp < 1.0e3)
{ fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4vsattemp);
printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4vsattemp);
}
if (pParam->BSIM4fprout < 0.0)
{ fprintf(fplog, "Fatal: fprout = %g is negative.\n",
pParam->BSIM4fprout);
printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4fprout);
Fatal_Flag = 1;
}
if (pParam->BSIM4pdits < 0.0)
{ fprintf(fplog, "Fatal: pdits = %g is negative.\n",
pParam->BSIM4pdits);
printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4pdits);
Fatal_Flag = 1;
}
if (model->BSIM4pditsl < 0.0)
{ fprintf(fplog, "Fatal: pditsl = %g is negative.\n",
model->BSIM4pditsl);
printf("Fatal: pditsl = %g is negative.\n", model->BSIM4pditsl);
Fatal_Flag = 1;
}
if((model->BSIM4lambdaGiven) && (pParam->BSIM4lambda > 0.0) )
{
if (pParam->BSIM4lambda > 1.0e-9)
{ fprintf(fplog, "Warning: Lambda = %g may be too large.\n", pParam->BSIM4lambda);
printf("Warning: Lambda = %g may be too large.\n", pParam->BSIM4lambda);
}
}
if((model->BSIM4vtlGiven) && (pParam->BSIM4vtl > 0.0) )
{
if (pParam->BSIM4vtl < 6.0e4)
{ fprintf(fplog, "Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4vtl);
printf("Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4vtl);
}
if (pParam->BSIM4xn < 3.0)
{ fprintf(fplog, "Warning: back scattering coeff xn = %g is too small.\n", pParam->BSIM4xn);
printf("Warning: back scattering coeff xn = %g is too small. Reset to 3.0 \n", pParam->BSIM4xn);
pParam->BSIM4xn = 3.0;
}
if (model->BSIM4lc < 0.0)
{ fprintf(fplog, "Warning: back scattering coeff lc = %g is too small.\n", model->BSIM4lc);
printf("Warning: back scattering coeff lc = %g is too small. Reset to 0.0\n", model->BSIM4lc);
pParam->BSIM4lc = 0.0;
}
}
if (pParam->BSIM4pdibl1 < 0.0)
{ fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n",
@ -491,37 +602,72 @@ FILE *fplog;
printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM4pdibl2);
}
if (pParam->BSIM4nigbinv <= 0.0)
{ fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n",
pParam->BSIM4nigbinv);
printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4nigbinv);
Fatal_Flag = 1;
}
if (pParam->BSIM4nigbacc <= 0.0)
{ fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n",
pParam->BSIM4nigbacc);
printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4nigbacc);
Fatal_Flag = 1;
}
if (pParam->BSIM4nigc <= 0.0)
{ fprintf(fplog, "Fatal: nigc = %g is non-positive.\n",
pParam->BSIM4nigc);
printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4nigc);
Fatal_Flag = 1;
}
if (pParam->BSIM4poxedge <= 0.0)
{ fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n",
pParam->BSIM4poxedge);
printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4poxedge);
Fatal_Flag = 1;
}
if (pParam->BSIM4pigcd <= 0.0)
{ fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n",
pParam->BSIM4pigcd);
printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4pigcd);
Fatal_Flag = 1;
/* Check stress effect parameters */
if((here->BSIM4sa > 0.0) && (here->BSIM4sb > 0.0) &&
((here->BSIM4nf == 1.0) || ((here->BSIM4nf > 1.0) && (here->BSIM4sd > 0.0))) )
{ if (model->BSIM4lodk2 <= 0.0)
{ fprintf(fplog, "Warning: LODK2 = %g is not positive.\n",model->BSIM4lodk2);
printf("Warning: LODK2 = %g is not positive.\n",model->BSIM4lodk2);
}
if (model->BSIM4lodeta0 <= 0.0)
{ fprintf(fplog, "Warning: LODETA0 = %g is not positive.\n",model->BSIM4lodeta0);
printf("Warning: LODETA0 = %g is not positive.\n",model->BSIM4lodeta0);
}
}
/* Check gate resistance parameters */
if (here->BSIM4rgateMod == 1)
{ if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg should be positive for rgateMod = 1.\n");
}
else if (here->BSIM4rgateMod == 2)
{ if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg <= 0.0 for rgateMod = 2.\n");
else if (pParam->BSIM4xrcrg1 <= 0.0)
printf("Warning: xrcrg1 <= 0.0 for rgateMod = 2.\n");
}
if (here->BSIM4rgateMod == 3)
{ if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg should be positive for rgateMod = 3.\n");
else if (pParam->BSIM4xrcrg1 <= 0.0)
printf("Warning: xrcrg1 should be positive for rgateMod = 3.\n");
}
/* Check capacitance parameters */
if (pParam->BSIM4noff < 0.1)
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",
pParam->BSIM4noff);
printf("Warning: Noff = %g is too small.\n", pParam->BSIM4noff);
}
if (pParam->BSIM4voffcv < -0.5)
{ fprintf(fplog, "Warning: Voffcv = %g is too small.\n",
pParam->BSIM4voffcv);
printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4voffcv);
}
if (pParam->BSIM4moin < 5.0)
{ fprintf(fplog, "Warning: Moin = %g is too small.\n",
pParam->BSIM4moin);
printf("Warning: Moin = %g is too small.\n", pParam->BSIM4moin);
}
if (pParam->BSIM4moin > 25.0)
{ fprintf(fplog, "Warning: Moin = %g is too large.\n",
pParam->BSIM4moin);
printf("Warning: Moin = %g is too large.\n", pParam->BSIM4moin);
}
if(model->BSIM4capMod ==2) {
if (pParam->BSIM4acde < 0.1)
{ fprintf(fplog, "Warning: Acde = %g is too small.\n",
pParam->BSIM4acde);
printf("Warning: Acde = %g is too small.\n", pParam->BSIM4acde);
}
if (pParam->BSIM4acde > 1.6)
{ fprintf(fplog, "Warning: Acde = %g is too large.\n",
pParam->BSIM4acde);
printf("Warning: Acde = %g is too large.\n", pParam->BSIM4acde);
}
}
/* Check overlap capacitance parameters */
if (model->BSIM4cgdo < 0.0)
@ -534,7 +680,12 @@ FILE *fplog;
printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4cgso);
model->BSIM4cgso = 0.0;
}
if (model->BSIM4cgbo < 0.0)
{ fprintf(fplog, "Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM4cgbo);
printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM4cgbo);
model->BSIM4cgbo = 0.0;
}
if (model->BSIM4tnoiMod == 1) {
if (model->BSIM4tnoia < 0.0)
{ fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia);
printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia);
@ -546,12 +697,114 @@ FILE *fplog;
model->BSIM4tnoib = 0.0;
}
if (model->BSIM4ntnoi < 0.0)
if (model->BSIM4rnoia < 0.0)
{ fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia);
printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia);
model->BSIM4rnoia = 0.0;
}
if (model->BSIM4rnoib < 0.0)
{ fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib);
printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib);
model->BSIM4rnoib = 0.0;
}
}
if (model->BSIM4SjctEmissionCoeff < 0.0)
{ fprintf(fplog, "Warning: Njs = %g is negative.\n",
model->BSIM4SjctEmissionCoeff);
printf("Warning: Njs = %g is negative.\n",
model->BSIM4SjctEmissionCoeff);
}
if (model->BSIM4DjctEmissionCoeff < 0.0)
{ fprintf(fplog, "Warning: Njd = %g is negative.\n",
model->BSIM4DjctEmissionCoeff);
printf("Warning: Njd = %g is negative.\n",
model->BSIM4DjctEmissionCoeff);
}
if (model->BSIM4njtstemp < 0.0)
{ fprintf(fplog, "Warning: Njts = %g is negative at temperature = %g.\n",
model->BSIM4njtstemp, ckt->CKTtemp);
printf("Warning: Njts = %g is negative at temperature = %g.\n",
model->BSIM4njtstemp, ckt->CKTtemp);
}
if (model->BSIM4njtsswtemp < 0.0)
{ fprintf(fplog, "Warning: Njtssw = %g is negative at temperature = %g.\n",
model->BSIM4njtsswtemp, ckt->CKTtemp);
printf("Warning: Njtssw = %g is negative at temperature = %g.\n",
model->BSIM4njtsswtemp, ckt->CKTtemp);
}
if (model->BSIM4njtsswgtemp < 0.0)
{ fprintf(fplog, "Warning: Njtsswg = %g is negative at temperature = %g.\n",
model->BSIM4njtsswgtemp, ckt->CKTtemp);
printf("Warning: Njtsswg = %g is negative at temperature = %g.\n",
model->BSIM4njtsswgtemp, ckt->CKTtemp);
}
if (model->BSIM4ntnoi < 0.0)
{ fprintf(fplog, "Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4ntnoi);
printf("Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4ntnoi);
model->BSIM4ntnoi = 0.0;
}
/* diode model */
if (model->BSIM4SbulkJctBotGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctBotGradingCoeff);
printf("Warning: MJS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctBotGradingCoeff);
model->BSIM4SbulkJctBotGradingCoeff = 0.99;
}
if (model->BSIM4SbulkJctSideGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJSWS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctSideGradingCoeff);
printf("Warning: MJSWS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctSideGradingCoeff);
model->BSIM4SbulkJctSideGradingCoeff = 0.99;
}
if (model->BSIM4SbulkJctGateSideGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJSWGS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctGateSideGradingCoeff);
printf("Warning: MJSWGS = %g is too big. Set to 0.99.\n", model->BSIM4SbulkJctGateSideGradingCoeff);
model->BSIM4SbulkJctGateSideGradingCoeff = 0.99;
}
if (model->BSIM4DbulkJctBotGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctBotGradingCoeff);
printf("Warning: MJD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctBotGradingCoeff);
model->BSIM4DbulkJctBotGradingCoeff = 0.99;
}
if (model->BSIM4DbulkJctSideGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJSWD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctSideGradingCoeff);
printf("Warning: MJSWD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctSideGradingCoeff);
model->BSIM4DbulkJctSideGradingCoeff = 0.99;
}
if (model->BSIM4DbulkJctGateSideGradingCoeff >= 0.99)
{ fprintf(fplog, "Warning: MJSWGD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctGateSideGradingCoeff);
printf("Warning: MJSWGD = %g is too big. Set to 0.99.\n", model->BSIM4DbulkJctGateSideGradingCoeff);
model->BSIM4DbulkJctGateSideGradingCoeff = 0.99;
}
if (model->BSIM4wpemod == 1)
{
if (model->BSIM4scref <= 0.0)
{ fprintf(fplog, "Warning: SCREF = %g is not positive. Set to 1e-6.\n", model->BSIM4scref);
printf("Warning: SCREF = %g is not positive. Set to 1e-6.\n", model->BSIM4scref);
model->BSIM4scref = 1e-6;
}
if (here->BSIM4sca < 0.0)
{ fprintf(fplog, "Warning: SCA = %g is negative. Set to 0.0.\n", here->BSIM4sca);
printf("Warning: SCA = %g is negative. Set to 0.0.\n", here->BSIM4sca);
here->BSIM4sca = 0.0;
}
if (here->BSIM4scb < 0.0)
{ fprintf(fplog, "Warning: SCB = %g is negative. Set to 0.0.\n", here->BSIM4scb);
printf("Warning: SCB = %g is negative. Set to 0.0.\n", here->BSIM4scb);
here->BSIM4scb = 0.0;
}
if (here->BSIM4scc < 0.0)
{ fprintf(fplog, "Warning: SCC = %g is negative. Set to 0.0.\n", here->BSIM4scc);
printf("Warning: SCC = %g is negative. Set to 0.0.\n", here->BSIM4scc);
here->BSIM4scc = 0.0;
}
if (here->BSIM4sc < 0.0)
{ fprintf(fplog, "Warning: SC = %g is negative. Set to 0.0.\n", here->BSIM4sc);
printf("Warning: SC = %g is negative. Set to 0.0.\n", here->BSIM4sc);
here->BSIM4sc = 0.0;
}
}
}/* loop for the parameter check for warning messages */
fclose(fplog);
}

View File

@ -1,25 +1,24 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4cvtest.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4cvtest.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 05/09/2003.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "trandefs.h"
#include "const.h"
#include "devdefs.h"
#include "sperror.h"
#include "suffix.h"
int
@ -43,10 +42,8 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6;
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL ;
here=here->BSIM4nextInstance)
{
if (here->BSIM4owner != ARCHme) continue;
vds = model->BSIM4type
{ if (here->BSIM4owner != ARCHme) continue;
vds = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4dNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vgs = model->BSIM4type
@ -113,11 +110,11 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6;
* delvds + here->BSIM4gIgbb * delvbs;
}
else
{ Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igisl;
{ Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igidl; /* bugfix */
cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs
* delvbd + here->BSIM4gm * delvgd
- here->BSIM4gds * delvds - here->BSIM4ggislg * vgd
- here->BSIM4ggislb * vbd + here->BSIM4ggisls * vds;
- (here->BSIM4gds + here->BSIM4ggidls) * delvds
- here->BSIM4ggidlg * delvgs - here->BSIM4ggidlb * delvbs;
Igstot = here->BSIM4Igs + here->BSIM4Igcd;
cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd
@ -182,11 +179,11 @@ double tol0, tol1, tol2, tol3, tol4, tol5, tol6;
- here->BSIM4ggislg * delvgd - here->BSIM4ggislb* delvbd + here->BSIM4ggisls * delvds ;
}
else
{ cbhat = Ibtot + here->BSIM4gbs * delvbs_jct + here->BSIM4gbd
* delvbd_jct - (here->BSIM4gbbs + here->BSIM4ggidlb) * delvbd
- (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgd
+ (here->BSIM4gbds + here->BSIM4ggidld) * delvds
- here->BSIM4ggislg * delvgs - here->BSIM4ggislb * delvbs + here->BSIM4ggisls * delvds;
{ cbhat = Ibtot + here->BSIM4gbs * delvbs_jct + here->BSIM4gbd
* delvbd_jct - (here->BSIM4gbbs + here->BSIM4ggislb) * delvbd
- (here->BSIM4gbgs + here->BSIM4ggislg) * delvgd
+ (here->BSIM4gbds + here->BSIM4ggisld - here->BSIM4ggidls) * delvds
- here->BSIM4ggidlg * delvgs - here->BSIM4ggidlb * delvbs;
}
tol6 = ckt->CKTreltol * MAX(fabs(cbhat),
fabs(Ibtot)) + ckt->CKTabstol;

View File

@ -1,18 +1,18 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4del.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4del.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "sperror.h"
#include "gendefs.h"
#include "suffix.h"
int

View File

@ -1,16 +1,16 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4dest.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4dest.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "suffix.h"
void
BSIM4destroy(inModel)

View File

@ -1,16 +1,14 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4geo.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4geo.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
/*
* WDLiu:
@ -19,6 +17,11 @@
* for multi-fingers and varous GEO and RGEO options.
*/
int
BSIM4RdsEndIso(double, double, double, double, double, double, int, int, double *);
int
BSIM4RdsEndSha(double, double, double, double, double, double, int, int, double *);
int
BSIM4NumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS)
int minSD;
@ -154,7 +157,7 @@ int geo, rgeo, minSD, Type;
double nf, Weffcj, Rsh, DMCG, DMCI, DMDG;
double *Rtot;
{
double Rint, Rend = 0.0;
double Rint=0.0, Rend = 0.0;
double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0;
if (geo < 9) /* since geo = 9 and 10 only happen when nf = even */

View File

@ -1,18 +1,18 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4getic.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4getic.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
@ -25,8 +25,8 @@ BSIM4instance *here;
for (; model ; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
if (!here->BSIM4icVDSGiven)
{ if (here->BSIM4owner != ARCHme) continue;
if (!here->BSIM4icVDSGiven)
{ here->BSIM4icVDS = *(ckt->CKTrhs + here->BSIM4dNode)
- *(ckt->CKTrhs + here->BSIM4sNode);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,26 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4mask.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4mask.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4mAsk(ckt,inst,which,value)
@ -75,6 +79,10 @@ IFvalue *value;
case BSIM4_MOD_IGBMOD :
value->iValue = model->BSIM4igbMod;
return(OK);
case BSIM4_MOD_TEMPMOD :
value->iValue = model->BSIM4tempMod;
return(OK);
case BSIM4_MOD_VERSION :
value->sValue = model->BSIM4version;
return(OK);
@ -119,6 +127,18 @@ IFvalue *value;
case BSIM4_MOD_VSAT:
value->rValue = model->BSIM4vsat;
return(OK);
case BSIM4_MOD_VTL:
value->rValue = model->BSIM4vtl;
return(OK);
case BSIM4_MOD_XN:
value->rValue = model->BSIM4xn;
return(OK);
case BSIM4_MOD_LC:
value->rValue = model->BSIM4lc;
return(OK);
case BSIM4_MOD_LAMBDA:
value->rValue = model->BSIM4lambda;
return(OK);
case BSIM4_MOD_AT:
value->rValue = model->BSIM4at;
return(OK);
@ -250,6 +270,18 @@ IFvalue *value;
case BSIM4_MOD_UC1:
value->rValue = model->BSIM4uc1;
return(OK);
case BSIM4_MOD_UD:
value->rValue = model->BSIM4ud;
return(OK);
case BSIM4_MOD_UD1:
value->rValue = model->BSIM4ud1;
return(OK);
case BSIM4_MOD_UP:
value->rValue = model->BSIM4up;
return(OK);
case BSIM4_MOD_LP:
value->rValue = model->BSIM4lp;
return(OK);
case BSIM4_MOD_U0:
value->rValue = model->BSIM4u0;
return(OK);
@ -259,6 +291,15 @@ IFvalue *value;
case BSIM4_MOD_VOFF:
value->rValue = model->BSIM4voff;
return(OK);
case BSIM4_MOD_TVOFF:
value->rValue = model->BSIM4tvoff;
return(OK);
case BSIM4_MOD_VFBSDOFF:
value->rValue = model->BSIM4vfbsdoff;
return(OK);
case BSIM4_MOD_TVFBSDOFF:
value->rValue = model->BSIM4tvfbsdoff;
return(OK);
case BSIM4_MOD_VOFFL:
value->rValue = model->BSIM4voffl;
return(OK);
@ -442,6 +483,12 @@ IFvalue *value;
case BSIM4_MOD_TNOIB:
value->rValue = model->BSIM4tnoib;
return(OK);
case BSIM4_MOD_RNOIA:
value->rValue = model->BSIM4rnoia;
return(OK);
case BSIM4_MOD_RNOIB:
value->rValue = model->BSIM4rnoib;
return(OK);
case BSIM4_MOD_NTNOI:
value->rValue = model->BSIM4ntnoi;
return(OK);
@ -473,6 +520,79 @@ IFvalue *value;
value->rValue = model->BSIM4vfb;
return(OK);
case BSIM4_MOD_JTSS:
value->rValue = model->BSIM4jtss;
return(OK);
case BSIM4_MOD_JTSD:
value->rValue = model->BSIM4jtsd;
return(OK);
case BSIM4_MOD_JTSSWS:
value->rValue = model->BSIM4jtssws;
return(OK);
case BSIM4_MOD_JTSSWD:
value->rValue = model->BSIM4jtsswd;
return(OK);
case BSIM4_MOD_JTSSWGS:
value->rValue = model->BSIM4jtsswgs;
return(OK);
case BSIM4_MOD_JTSSWGD:
value->rValue = model->BSIM4jtsswgd;
return(OK);
case BSIM4_MOD_NJTS:
value->rValue = model->BSIM4njts;
return(OK);
case BSIM4_MOD_NJTSSW:
value->rValue = model->BSIM4njtssw;
return(OK);
case BSIM4_MOD_NJTSSWG:
value->rValue = model->BSIM4njtsswg;
return(OK);
case BSIM4_MOD_XTSS:
value->rValue = model->BSIM4xtss;
return(OK);
case BSIM4_MOD_XTSD:
value->rValue = model->BSIM4xtsd;
return(OK);
case BSIM4_MOD_XTSSWS:
value->rValue = model->BSIM4xtssws;
return(OK);
case BSIM4_MOD_XTSSWD:
value->rValue = model->BSIM4xtsswd;
return(OK);
case BSIM4_MOD_XTSSWGS:
value->rValue = model->BSIM4xtsswgs;
return(OK);
case BSIM4_MOD_XTSSWGD:
value->rValue = model->BSIM4xtsswgd;
return(OK);
case BSIM4_MOD_TNJTS:
value->rValue = model->BSIM4tnjts;
return(OK);
case BSIM4_MOD_TNJTSSW:
value->rValue = model->BSIM4tnjtssw;
return(OK);
case BSIM4_MOD_TNJTSSWG:
value->rValue = model->BSIM4tnjtsswg;
return(OK);
case BSIM4_MOD_VTSS:
value->rValue = model->BSIM4vtss;
return(OK);
case BSIM4_MOD_VTSD:
value->rValue = model->BSIM4vtsd;
return(OK);
case BSIM4_MOD_VTSSWS:
value->rValue = model->BSIM4vtssws;
return(OK);
case BSIM4_MOD_VTSSWD:
value->rValue = model->BSIM4vtsswd;
return(OK);
case BSIM4_MOD_VTSSWGS:
value->rValue = model->BSIM4vtsswgs;
return(OK);
case BSIM4_MOD_VTSSWGD:
value->rValue = model->BSIM4vtsswgd;
return(OK);
case BSIM4_MOD_GBMIN:
value->rValue = model->BSIM4gbmin;
return(OK);
@ -492,6 +612,87 @@ IFvalue *value;
value->rValue = model->BSIM4rbpd;
return(OK);
case BSIM4_MOD_RBPS0:
value->rValue = model->BSIM4rbps0;
return(OK);
case BSIM4_MOD_RBPSL:
value->rValue = model->BSIM4rbpsl;
return(OK);
case BSIM4_MOD_RBPSW:
value->rValue = model->BSIM4rbpsw;
return(OK);
case BSIM4_MOD_RBPSNF:
value->rValue = model->BSIM4rbpsnf;
return(OK);
case BSIM4_MOD_RBPD0:
value->rValue = model->BSIM4rbpd0;
return(OK);
case BSIM4_MOD_RBPDL:
value->rValue = model->BSIM4rbpdl;
return(OK);
case BSIM4_MOD_RBPDW:
value->rValue = model->BSIM4rbpdw;
return(OK);
case BSIM4_MOD_RBPDNF:
value->rValue = model->BSIM4rbpdnf;
return(OK);
case BSIM4_MOD_RBPBX0:
value->rValue = model->BSIM4rbpbx0;
return(OK);
case BSIM4_MOD_RBPBXL:
value->rValue = model->BSIM4rbpbxl;
return(OK);
case BSIM4_MOD_RBPBXW:
value->rValue = model->BSIM4rbpbxw;
return(OK);
case BSIM4_MOD_RBPBXNF:
value->rValue = model->BSIM4rbpbxnf;
return(OK);
case BSIM4_MOD_RBPBY0:
value->rValue = model->BSIM4rbpby0;
return(OK);
case BSIM4_MOD_RBPBYL:
value->rValue = model->BSIM4rbpbyl;
return(OK);
case BSIM4_MOD_RBPBYW:
value->rValue = model->BSIM4rbpbyw;
return(OK);
case BSIM4_MOD_RBPBYNF:
value->rValue = model->BSIM4rbpbynf;
return(OK);
case BSIM4_MOD_RBSBX0:
value->rValue = model->BSIM4rbsbx0;
return(OK);
case BSIM4_MOD_RBSBY0:
value->rValue = model->BSIM4rbsby0;
return(OK);
case BSIM4_MOD_RBDBX0:
value->rValue = model->BSIM4rbdbx0;
return(OK);
case BSIM4_MOD_RBDBY0:
value->rValue = model->BSIM4rbdby0;
return(OK);
case BSIM4_MOD_RBSDBXL:
value->rValue = model->BSIM4rbsdbxl;
return(OK);
case BSIM4_MOD_RBSDBXW:
value->rValue = model->BSIM4rbsdbxw;
return(OK);
case BSIM4_MOD_RBSDBXNF:
value->rValue = model->BSIM4rbsdbxnf;
return(OK);
case BSIM4_MOD_RBSDBYL:
value->rValue = model->BSIM4rbsdbyl;
return(OK);
case BSIM4_MOD_RBSDBYW:
value->rValue = model->BSIM4rbsdbyw;
return(OK);
case BSIM4_MOD_RBSDBYNF:
value->rValue = model->BSIM4rbsdbynf;
return(OK);
case BSIM4_MOD_CGSL:
value->rValue = model->BSIM4cgsl;
return(OK);
@ -567,9 +768,6 @@ IFvalue *value;
case BSIM4_MOD_RSHG:
value->rValue = model->BSIM4rshg;
return(OK);
case BSIM4_MOD_NGCON:
value->rValue = model->BSIM4ngcon;
return(OK);
case BSIM4_MOD_TCJ:
value->rValue = model->BSIM4tcj;
return(OK);
@ -737,6 +935,18 @@ IFvalue *value;
case BSIM4_MOD_LUC1:
value->rValue = model->BSIM4luc1;
return(OK);
case BSIM4_MOD_LUD:
value->rValue = model->BSIM4lud;
return(OK);
case BSIM4_MOD_LUD1:
value->rValue = model->BSIM4lud1;
return(OK);
case BSIM4_MOD_LUP:
value->rValue = model->BSIM4lup;
return(OK);
case BSIM4_MOD_LLP:
value->rValue = model->BSIM4llp;
return(OK);
case BSIM4_MOD_LU0:
value->rValue = model->BSIM4lu0;
return(OK);
@ -746,6 +956,9 @@ IFvalue *value;
case BSIM4_MOD_LVOFF:
value->rValue = model->BSIM4lvoff;
return(OK);
case BSIM4_MOD_LTVOFF:
value->rValue = model->BSIM4ltvoff;
return(OK);
case BSIM4_MOD_LMINV:
value->rValue = model->BSIM4lminv;
return(OK);
@ -951,6 +1164,12 @@ IFvalue *value;
case BSIM4_MOD_LVOFFCV:
value->rValue = model->BSIM4lvoffcv;
return(OK);
case BSIM4_MOD_LVFBSDOFF:
value->rValue = model->BSIM4lvfbsdoff;
return(OK);
case BSIM4_MOD_LTVFBSDOFF:
value->rValue = model->BSIM4ltvfbsdoff;
return(OK);
/* Width dependence */
case BSIM4_MOD_WCDSC :
@ -1100,6 +1319,18 @@ IFvalue *value;
case BSIM4_MOD_WUC1:
value->rValue = model->BSIM4wuc1;
return(OK);
case BSIM4_MOD_WUD:
value->rValue = model->BSIM4wud;
return(OK);
case BSIM4_MOD_WUD1:
value->rValue = model->BSIM4wud1;
return(OK);
case BSIM4_MOD_WUP:
value->rValue = model->BSIM4wup;
return(OK);
case BSIM4_MOD_WLP:
value->rValue = model->BSIM4wlp;
return(OK);
case BSIM4_MOD_WU0:
value->rValue = model->BSIM4wu0;
return(OK);
@ -1109,6 +1340,9 @@ IFvalue *value;
case BSIM4_MOD_WVOFF:
value->rValue = model->BSIM4wvoff;
return(OK);
case BSIM4_MOD_WTVOFF:
value->rValue = model->BSIM4wtvoff;
return(OK);
case BSIM4_MOD_WMINV:
value->rValue = model->BSIM4wminv;
return(OK);
@ -1314,6 +1548,12 @@ IFvalue *value;
case BSIM4_MOD_WVOFFCV:
value->rValue = model->BSIM4wvoffcv;
return(OK);
case BSIM4_MOD_WVFBSDOFF:
value->rValue = model->BSIM4wvfbsdoff;
return(OK);
case BSIM4_MOD_WTVFBSDOFF:
value->rValue = model->BSIM4wtvfbsdoff;
return(OK);
/* Cross-term dependence */
case BSIM4_MOD_PCDSC :
@ -1463,6 +1703,18 @@ IFvalue *value;
case BSIM4_MOD_PUC1:
value->rValue = model->BSIM4puc1;
return(OK);
case BSIM4_MOD_PUD:
value->rValue = model->BSIM4pud;
return(OK);
case BSIM4_MOD_PUD1:
value->rValue = model->BSIM4pud1;
return(OK);
case BSIM4_MOD_PUP:
value->rValue = model->BSIM4pup;
return(OK);
case BSIM4_MOD_PLP:
value->rValue = model->BSIM4plp;
return(OK);
case BSIM4_MOD_PU0:
value->rValue = model->BSIM4pu0;
return(OK);
@ -1472,6 +1724,9 @@ IFvalue *value;
case BSIM4_MOD_PVOFF:
value->rValue = model->BSIM4pvoff;
return(OK);
case BSIM4_MOD_PTVOFF:
value->rValue = model->BSIM4ptvoff;
return(OK);
case BSIM4_MOD_PMINV:
value->rValue = model->BSIM4pminv;
return(OK);
@ -1677,6 +1932,12 @@ IFvalue *value;
case BSIM4_MOD_PVOFFCV:
value->rValue = model->BSIM4pvoffcv;
return(OK);
case BSIM4_MOD_PVFBSDOFF:
value->rValue = model->BSIM4pvfbsdoff;
return(OK);
case BSIM4_MOD_PTVFBSDOFF:
value->rValue = model->BSIM4ptvfbsdoff;
return(OK);
case BSIM4_MOD_TNOM :
value->rValue = model->BSIM4tnom;
@ -1846,6 +2107,122 @@ IFvalue *value;
case BSIM4_MOD_WMAX:
value->rValue = model->BSIM4Wmax;
return(OK);
/* stress effect */
case BSIM4_MOD_SAREF:
value->rValue = model->BSIM4saref;
return(OK);
case BSIM4_MOD_SBREF:
value->rValue = model->BSIM4sbref;
return(OK);
case BSIM4_MOD_WLOD:
value->rValue = model->BSIM4wlod;
return(OK);
case BSIM4_MOD_KU0:
value->rValue = model->BSIM4ku0;
return(OK);
case BSIM4_MOD_KVSAT:
value->rValue = model->BSIM4kvsat;
return(OK);
case BSIM4_MOD_KVTH0:
value->rValue = model->BSIM4kvth0;
return(OK);
case BSIM4_MOD_TKU0:
value->rValue = model->BSIM4tku0;
return(OK);
case BSIM4_MOD_LLODKU0:
value->rValue = model->BSIM4llodku0;
return(OK);
case BSIM4_MOD_WLODKU0:
value->rValue = model->BSIM4wlodku0;
return(OK);
case BSIM4_MOD_LLODVTH:
value->rValue = model->BSIM4llodvth;
return(OK);
case BSIM4_MOD_WLODVTH:
value->rValue = model->BSIM4wlodvth;
return(OK);
case BSIM4_MOD_LKU0:
value->rValue = model->BSIM4lku0;
return(OK);
case BSIM4_MOD_WKU0:
value->rValue = model->BSIM4wku0;
return(OK);
case BSIM4_MOD_PKU0:
value->rValue = model->BSIM4pku0;
return(OK);
case BSIM4_MOD_LKVTH0:
value->rValue = model->BSIM4lkvth0;
return(OK);
case BSIM4_MOD_WKVTH0:
value->rValue = model->BSIM4wkvth0;
return(OK);
case BSIM4_MOD_PKVTH0:
value->rValue = model->BSIM4pkvth0;
return(OK);
case BSIM4_MOD_STK2:
value->rValue = model->BSIM4stk2;
return(OK);
case BSIM4_MOD_LODK2:
value->rValue = model->BSIM4lodk2;
return(OK);
case BSIM4_MOD_STETA0:
value->rValue = model->BSIM4steta0;
return(OK);
case BSIM4_MOD_LODETA0:
value->rValue = model->BSIM4lodeta0;
return(OK);
/* Well Proximity Effect */
case BSIM4_MOD_WEB:
value->rValue = model->BSIM4web;
return(OK);
case BSIM4_MOD_WEC:
value->rValue = model->BSIM4wec;
return(OK);
case BSIM4_MOD_KVTH0WE:
value->rValue = model->BSIM4kvth0we;
return(OK);
case BSIM4_MOD_K2WE:
value->rValue = model->BSIM4k2we;
return(OK);
case BSIM4_MOD_KU0WE:
value->rValue = model->BSIM4ku0we;
return(OK);
case BSIM4_MOD_SCREF:
value->rValue = model->BSIM4scref;
return(OK);
case BSIM4_MOD_WPEMOD:
value->rValue = model->BSIM4wpemod;
return(OK);
case BSIM4_MOD_LKVTH0WE:
value->rValue = model->BSIM4lkvth0we;
return(OK);
case BSIM4_MOD_LK2WE:
value->rValue = model->BSIM4lk2we;
return(OK);
case BSIM4_MOD_LKU0WE:
value->rValue = model->BSIM4lku0we;
return(OK);
case BSIM4_MOD_WKVTH0WE:
value->rValue = model->BSIM4wkvth0we;
return(OK);
case BSIM4_MOD_WK2WE:
value->rValue = model->BSIM4wk2we;
return(OK);
case BSIM4_MOD_WKU0WE:
value->rValue = model->BSIM4wku0we;
return(OK);
case BSIM4_MOD_PKVTH0WE:
value->rValue = model->BSIM4pkvth0we;
return(OK);
case BSIM4_MOD_PK2WE:
value->rValue = model->BSIM4pk2we;
return(OK);
case BSIM4_MOD_PKU0WE:
value->rValue = model->BSIM4pku0we;
return(OK);
case BSIM4_MOD_NOIA:
value->rValue = model->BSIM4oxideTrapDensityA;
return(OK);

View File

@ -1,18 +1,17 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4mdel.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4mdel.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4mDelete(inModel,modname,kill)

View File

@ -1,21 +1,24 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4mpar.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4mpar.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi 04/06/2001
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "ifsim.h"
#include "sperror.h"
#include "const.h"
#include "suffix.h"
int
BSIM4mParam(param,value,inMod)
@ -89,6 +92,11 @@ GENmodel *inMod;
mod->BSIM4igbMod = value->iValue;
mod->BSIM4igbModGiven = TRUE;
break;
case BSIM4_MOD_TEMPMOD :
mod->BSIM4tempMod = value->iValue;
mod->BSIM4tempModGiven = TRUE;
break;
case BSIM4_MOD_VERSION :
mod->BSIM4version = value->sValue;
mod->BSIM4versionGiven = TRUE;
@ -336,10 +344,81 @@ GENmodel *inMod;
mod->BSIM4ute = value->rValue;
mod->BSIM4uteGiven = TRUE;
break;
case BSIM4_MOD_UD:
mod->BSIM4ud = value->rValue;
mod->BSIM4udGiven = TRUE;
break;
case BSIM4_MOD_UD1:
mod->BSIM4ud1 = value->rValue;
mod->BSIM4ud1Given = TRUE;
break;
case BSIM4_MOD_UP:
mod->BSIM4up = value->rValue;
mod->BSIM4upGiven = TRUE;
break;
case BSIM4_MOD_LP:
mod->BSIM4lp = value->rValue;
mod->BSIM4lpGiven = TRUE;
break;
case BSIM4_MOD_LUD:
mod->BSIM4lud = value->rValue;
mod->BSIM4ludGiven = TRUE;
break;
case BSIM4_MOD_LUD1:
mod->BSIM4lud1 = value->rValue;
mod->BSIM4lud1Given = TRUE;
break;
case BSIM4_MOD_LUP:
mod->BSIM4lup = value->rValue;
mod->BSIM4lupGiven = TRUE;
break;
case BSIM4_MOD_LLP:
mod->BSIM4llp = value->rValue;
mod->BSIM4llpGiven = TRUE;
break;
case BSIM4_MOD_WUD:
mod->BSIM4wud = value->rValue;
mod->BSIM4wudGiven = TRUE;
break;
case BSIM4_MOD_WUD1:
mod->BSIM4wud1 = value->rValue;
mod->BSIM4wud1Given = TRUE;
break;
case BSIM4_MOD_WUP:
mod->BSIM4wup = value->rValue;
mod->BSIM4wupGiven = TRUE;
break;
case BSIM4_MOD_WLP:
mod->BSIM4wlp = value->rValue;
mod->BSIM4wlpGiven = TRUE;
break;
case BSIM4_MOD_PUD:
mod->BSIM4pud = value->rValue;
mod->BSIM4pudGiven = TRUE;
break;
case BSIM4_MOD_PUD1:
mod->BSIM4pud1 = value->rValue;
mod->BSIM4pud1Given = TRUE;
break;
case BSIM4_MOD_PUP:
mod->BSIM4pup = value->rValue;
mod->BSIM4pupGiven = TRUE;
break;
case BSIM4_MOD_PLP:
mod->BSIM4plp = value->rValue;
mod->BSIM4plpGiven = TRUE;
break;
case BSIM4_MOD_VOFF:
mod->BSIM4voff = value->rValue;
mod->BSIM4voffGiven = TRUE;
break;
case BSIM4_MOD_TVOFF:
mod->BSIM4tvoff = value->rValue;
mod->BSIM4tvoffGiven = TRUE;
break;
case BSIM4_MOD_VOFFL:
mod->BSIM4voffl = value->rValue;
mod->BSIM4vofflGiven = TRUE;
@ -568,6 +647,26 @@ GENmodel *inMod;
mod->BSIM4xrcrg1 = value->rValue;
mod->BSIM4xrcrg1Given = TRUE;
break;
case BSIM4_MOD_XRCRG2 :
mod->BSIM4xrcrg2 = value->rValue;
mod->BSIM4xrcrg2Given = TRUE;
break;
case BSIM4_MOD_LAMBDA :
mod->BSIM4lambda = value->rValue;
mod->BSIM4lambdaGiven = TRUE;
break;
case BSIM4_MOD_VTL :
mod->BSIM4vtl = value->rValue;
mod->BSIM4vtlGiven = TRUE;
break;
case BSIM4_MOD_XN:
mod->BSIM4xn = value->rValue;
mod->BSIM4xnGiven = TRUE;
break;
case BSIM4_MOD_LC:
mod->BSIM4lc = value->rValue;
mod->BSIM4lcGiven = TRUE;
break;
case BSIM4_MOD_TNOIA :
mod->BSIM4tnoia = value->rValue;
mod->BSIM4tnoiaGiven = TRUE;
@ -576,14 +675,182 @@ GENmodel *inMod;
mod->BSIM4tnoib = value->rValue;
mod->BSIM4tnoibGiven = TRUE;
break;
case BSIM4_MOD_RNOIA :
mod->BSIM4rnoia = value->rValue;
mod->BSIM4rnoiaGiven = TRUE;
break;
case BSIM4_MOD_RNOIB :
mod->BSIM4rnoib = value->rValue;
mod->BSIM4rnoibGiven = TRUE;
break;
case BSIM4_MOD_NTNOI :
mod->BSIM4ntnoi = value->rValue;
mod->BSIM4ntnoiGiven = TRUE;
break;
case BSIM4_MOD_XRCRG2 :
mod->BSIM4xrcrg2 = value->rValue;
mod->BSIM4xrcrg2Given = TRUE;
case BSIM4_MOD_VFBSDOFF:
mod->BSIM4vfbsdoff = value->rValue;
mod->BSIM4vfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_TVFBSDOFF:
mod->BSIM4tvfbsdoff = value->rValue;
mod->BSIM4tvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_LINTNOI:
mod->BSIM4lintnoi = value->rValue;
mod->BSIM4lintnoiGiven = TRUE;
break;
/* stress effect */
case BSIM4_MOD_SAREF :
mod->BSIM4saref = value->rValue;
mod->BSIM4sarefGiven = TRUE;
break;
case BSIM4_MOD_SBREF :
mod->BSIM4sbref = value->rValue;
mod->BSIM4sbrefGiven = TRUE;
break;
case BSIM4_MOD_WLOD :
mod->BSIM4wlod = value->rValue;
mod->BSIM4wlodGiven = TRUE;
break;
case BSIM4_MOD_KU0 :
mod->BSIM4ku0 = value->rValue;
mod->BSIM4ku0Given = TRUE;
break;
case BSIM4_MOD_KVSAT :
mod->BSIM4kvsat = value->rValue;
mod->BSIM4kvsatGiven = TRUE;
break;
case BSIM4_MOD_KVTH0 :
mod->BSIM4kvth0 = value->rValue;
mod->BSIM4kvth0Given = TRUE;
break;
case BSIM4_MOD_TKU0 :
mod->BSIM4tku0 = value->rValue;
mod->BSIM4tku0Given = TRUE;
break;
case BSIM4_MOD_LLODKU0 :
mod->BSIM4llodku0 = value->rValue;
mod->BSIM4llodku0Given = TRUE;
break;
case BSIM4_MOD_WLODKU0 :
mod->BSIM4wlodku0 = value->rValue;
mod->BSIM4wlodku0Given = TRUE;
break;
case BSIM4_MOD_LLODVTH :
mod->BSIM4llodvth = value->rValue;
mod->BSIM4llodvthGiven = TRUE;
break;
case BSIM4_MOD_WLODVTH :
mod->BSIM4wlodvth = value->rValue;
mod->BSIM4wlodvthGiven = TRUE;
break;
case BSIM4_MOD_LKU0 :
mod->BSIM4lku0 = value->rValue;
mod->BSIM4lku0Given = TRUE;
break;
case BSIM4_MOD_WKU0 :
mod->BSIM4wku0 = value->rValue;
mod->BSIM4wku0Given = TRUE;
break;
case BSIM4_MOD_PKU0 :
mod->BSIM4pku0 = value->rValue;
mod->BSIM4pku0Given = TRUE;
break;
case BSIM4_MOD_LKVTH0 :
mod->BSIM4lkvth0 = value->rValue;
mod->BSIM4lkvth0Given = TRUE;
break;
case BSIM4_MOD_WKVTH0 :
mod->BSIM4wkvth0 = value->rValue;
mod->BSIM4wkvth0Given = TRUE;
break;
case BSIM4_MOD_PKVTH0 :
mod->BSIM4pkvth0 = value->rValue;
mod->BSIM4pkvth0Given = TRUE;
break;
case BSIM4_MOD_STK2 :
mod->BSIM4stk2 = value->rValue;
mod->BSIM4stk2Given = TRUE;
break;
case BSIM4_MOD_LODK2 :
mod->BSIM4lodk2 = value->rValue;
mod->BSIM4lodk2Given = TRUE;
break;
case BSIM4_MOD_STETA0 :
mod->BSIM4steta0 = value->rValue;
mod->BSIM4steta0Given = TRUE;
break;
case BSIM4_MOD_LODETA0 :
mod->BSIM4lodeta0 = value->rValue;
mod->BSIM4lodeta0Given = TRUE;
break;
case BSIM4_MOD_WEB :
mod->BSIM4web = value->rValue;
mod->BSIM4webGiven = TRUE;
break;
case BSIM4_MOD_WEC :
mod->BSIM4wec = value->rValue;
mod->BSIM4wecGiven = TRUE;
break;
case BSIM4_MOD_KVTH0WE :
mod->BSIM4kvth0we = value->rValue;
mod->BSIM4kvth0weGiven = TRUE;
break;
case BSIM4_MOD_K2WE :
mod->BSIM4k2we = value->rValue;
mod->BSIM4k2weGiven = TRUE;
break;
case BSIM4_MOD_KU0WE :
mod->BSIM4ku0we = value->rValue;
mod->BSIM4ku0weGiven = TRUE;
break;
case BSIM4_MOD_SCREF :
mod->BSIM4scref = value->rValue;
mod->BSIM4screfGiven = TRUE;
break;
case BSIM4_MOD_WPEMOD :
mod->BSIM4wpemod = value->rValue;
mod->BSIM4wpemodGiven = TRUE;
break;
case BSIM4_MOD_LKVTH0WE :
mod->BSIM4lkvth0we = value->rValue;
mod->BSIM4lkvth0weGiven = TRUE;
break;
case BSIM4_MOD_LK2WE :
mod->BSIM4lk2we = value->rValue;
mod->BSIM4lk2weGiven = TRUE;
break;
case BSIM4_MOD_LKU0WE :
mod->BSIM4lku0we = value->rValue;
mod->BSIM4lku0weGiven = TRUE;
break;
case BSIM4_MOD_WKVTH0WE :
mod->BSIM4wkvth0we = value->rValue;
mod->BSIM4wkvth0weGiven = TRUE;
break;
case BSIM4_MOD_WK2WE :
mod->BSIM4wk2we = value->rValue;
mod->BSIM4wk2weGiven = TRUE;
break;
case BSIM4_MOD_WKU0WE :
mod->BSIM4wku0we = value->rValue;
mod->BSIM4wku0weGiven = TRUE;
break;
case BSIM4_MOD_PKVTH0WE :
mod->BSIM4pkvth0we = value->rValue;
mod->BSIM4pkvth0weGiven = TRUE;
break;
case BSIM4_MOD_PK2WE :
mod->BSIM4pk2we = value->rValue;
mod->BSIM4pk2weGiven = TRUE;
break;
case BSIM4_MOD_PKU0WE :
mod->BSIM4pku0we = value->rValue;
mod->BSIM4pku0weGiven = TRUE;
break;
case BSIM4_MOD_BETA0 :
mod->BSIM4beta0 = value->rValue;
mod->BSIM4beta0Given = TRUE;
@ -620,6 +887,105 @@ GENmodel *inMod;
mod->BSIM4bvs = value->rValue;
mod->BSIM4bvsGiven = TRUE;
break;
/* reverse diode */
case BSIM4_MOD_JTSS :
mod->BSIM4jtss = value->rValue;
mod->BSIM4jtssGiven = TRUE;
break;
case BSIM4_MOD_JTSD :
mod->BSIM4jtsd = value->rValue;
mod->BSIM4jtsdGiven = TRUE;
break;
case BSIM4_MOD_JTSSWS :
mod->BSIM4jtssws = value->rValue;
mod->BSIM4jtsswsGiven = TRUE;
break;
case BSIM4_MOD_JTSSWD :
mod->BSIM4jtsswd = value->rValue;
mod->BSIM4jtsswdGiven = TRUE;
break;
case BSIM4_MOD_JTSSWGS :
mod->BSIM4jtsswgs = value->rValue;
mod->BSIM4jtsswgsGiven = TRUE;
break;
case BSIM4_MOD_JTSSWGD :
mod->BSIM4jtsswgd = value->rValue;
mod->BSIM4jtsswgdGiven = TRUE;
break;
case BSIM4_MOD_NJTS :
mod->BSIM4njts = value->rValue;
mod->BSIM4njtsGiven = TRUE;
break;
case BSIM4_MOD_NJTSSW :
mod->BSIM4njtssw = value->rValue;
mod->BSIM4njtsswGiven = TRUE;
break;
case BSIM4_MOD_NJTSSWG :
mod->BSIM4njtsswg = value->rValue;
mod->BSIM4njtsswgGiven = TRUE;
break;
case BSIM4_MOD_XTSS :
mod->BSIM4xtss = value->rValue;
mod->BSIM4xtssGiven = TRUE;
break;
case BSIM4_MOD_XTSD :
mod->BSIM4xtsd = value->rValue;
mod->BSIM4xtsdGiven = TRUE;
break;
case BSIM4_MOD_XTSSWS :
mod->BSIM4xtssws = value->rValue;
mod->BSIM4xtsswsGiven = TRUE;
break;
case BSIM4_MOD_XTSSWD :
mod->BSIM4xtsswd = value->rValue;
mod->BSIM4xtsswdGiven = TRUE;
break;
case BSIM4_MOD_XTSSWGS :
mod->BSIM4xtsswgs = value->rValue;
mod->BSIM4xtsswgsGiven = TRUE;
break;
case BSIM4_MOD_XTSSWGD :
mod->BSIM4xtsswgd = value->rValue;
mod->BSIM4xtsswgdGiven = TRUE;
break;
case BSIM4_MOD_TNJTS :
mod->BSIM4tnjts = value->rValue;
mod->BSIM4tnjtsGiven = TRUE;
break;
case BSIM4_MOD_TNJTSSW :
mod->BSIM4tnjtssw = value->rValue;
mod->BSIM4tnjtsswGiven = TRUE;
break;
case BSIM4_MOD_TNJTSSWG :
mod->BSIM4tnjtsswg = value->rValue;
mod->BSIM4tnjtsswgGiven = TRUE;
break;
case BSIM4_MOD_VTSS :
mod->BSIM4vtss = value->rValue;
mod->BSIM4vtssGiven = TRUE;
break;
case BSIM4_MOD_VTSD :
mod->BSIM4vtsd = value->rValue;
mod->BSIM4vtsdGiven = TRUE;
break;
case BSIM4_MOD_VTSSWS :
mod->BSIM4vtssws = value->rValue;
mod->BSIM4vtsswsGiven = TRUE;
break;
case BSIM4_MOD_VTSSWD :
mod->BSIM4vtsswd = value->rValue;
mod->BSIM4vtsswdGiven = TRUE;
break;
case BSIM4_MOD_VTSSWGS :
mod->BSIM4vtsswgs = value->rValue;
mod->BSIM4vtsswgsGiven = TRUE;
break;
case BSIM4_MOD_VTSSWGD :
mod->BSIM4vtsswgd = value->rValue;
mod->BSIM4vtsswgdGiven = TRUE;
break;
case BSIM4_MOD_VFB :
mod->BSIM4vfb = value->rValue;
mod->BSIM4vfbGiven = TRUE;
@ -650,6 +1016,115 @@ GENmodel *inMod;
mod->BSIM4rbpdGiven = TRUE;
break;
case BSIM4_MOD_RBPS0 :
mod->BSIM4rbps0 = value->rValue;
mod->BSIM4rbps0Given = TRUE;
break;
case BSIM4_MOD_RBPSL :
mod->BSIM4rbpsl = value->rValue;
mod->BSIM4rbpslGiven = TRUE;
break;
case BSIM4_MOD_RBPSW :
mod->BSIM4rbpsw = value->rValue;
mod->BSIM4rbpswGiven = TRUE;
break;
case BSIM4_MOD_RBPSNF :
mod->BSIM4rbpsnf = value->rValue;
mod->BSIM4rbpsnfGiven = TRUE;
break;
case BSIM4_MOD_RBPD0 :
mod->BSIM4rbpd0 = value->rValue;
mod->BSIM4rbpd0Given = TRUE;
break;
case BSIM4_MOD_RBPDL :
mod->BSIM4rbpdl = value->rValue;
mod->BSIM4rbpdlGiven = TRUE;
break;
case BSIM4_MOD_RBPDW :
mod->BSIM4rbpdw = value->rValue;
mod->BSIM4rbpdwGiven = TRUE;
break;
case BSIM4_MOD_RBPDNF :
mod->BSIM4rbpdnf = value->rValue;
mod->BSIM4rbpdnfGiven = TRUE;
break;
case BSIM4_MOD_RBPBX0 :
mod->BSIM4rbpbx0 = value->rValue;
mod->BSIM4rbpbx0Given = TRUE;
break;
case BSIM4_MOD_RBPBXL :
mod->BSIM4rbpbxl = value->rValue;
mod->BSIM4rbpbxlGiven = TRUE;
break;
case BSIM4_MOD_RBPBXW :
mod->BSIM4rbpbxw = value->rValue;
mod->BSIM4rbpbxwGiven = TRUE;
break;
case BSIM4_MOD_RBPBXNF :
mod->BSIM4rbpbxnf = value->rValue;
mod->BSIM4rbpbxnfGiven = TRUE;
break;
case BSIM4_MOD_RBPBY0 :
mod->BSIM4rbpby0 = value->rValue;
mod->BSIM4rbpby0Given = TRUE;
break;
case BSIM4_MOD_RBPBYL :
mod->BSIM4rbpbyl = value->rValue;
mod->BSIM4rbpbylGiven = TRUE;
break;
case BSIM4_MOD_RBPBYW :
mod->BSIM4rbpbyw = value->rValue;
mod->BSIM4rbpbywGiven = TRUE;
break;
case BSIM4_MOD_RBPBYNF :
mod->BSIM4rbpbynf = value->rValue;
mod->BSIM4rbpbynfGiven = TRUE;
break;
case BSIM4_MOD_RBSBX0 :
mod->BSIM4rbsbx0 = value->rValue;
mod->BSIM4rbsbx0Given = TRUE;
break;
case BSIM4_MOD_RBSBY0 :
mod->BSIM4rbsby0 = value->rValue;
mod->BSIM4rbsby0Given = TRUE;
break;
case BSIM4_MOD_RBDBX0 :
mod->BSIM4rbdbx0 = value->rValue;
mod->BSIM4rbdbx0Given = TRUE;
break;
case BSIM4_MOD_RBDBY0 :
mod->BSIM4rbdby0 = value->rValue;
mod->BSIM4rbdby0Given = TRUE;
break;
case BSIM4_MOD_RBSDBXL :
mod->BSIM4rbsdbxl = value->rValue;
mod->BSIM4rbsdbxlGiven = TRUE;
break;
case BSIM4_MOD_RBSDBXW :
mod->BSIM4rbsdbxw = value->rValue;
mod->BSIM4rbsdbxwGiven = TRUE;
break;
case BSIM4_MOD_RBSDBXNF :
mod->BSIM4rbsdbxnf = value->rValue;
mod->BSIM4rbsdbxnfGiven = TRUE;
break;
case BSIM4_MOD_RBSDBYL :
mod->BSIM4rbsdbyl = value->rValue;
mod->BSIM4rbsdbylGiven = TRUE;
break;
case BSIM4_MOD_RBSDBYW :
mod->BSIM4rbsdbyw = value->rValue;
mod->BSIM4rbsdbywGiven = TRUE;
break;
case BSIM4_MOD_RBSDBYNF :
mod->BSIM4rbsdbynf = value->rValue;
mod->BSIM4rbsdbynfGiven = TRUE;
break;
case BSIM4_MOD_CGSL :
mod->BSIM4cgsl = value->rValue;
mod->BSIM4cgslGiven = TRUE;
@ -998,6 +1473,10 @@ GENmodel *inMod;
mod->BSIM4lvoff = value->rValue;
mod->BSIM4lvoffGiven = TRUE;
break;
case BSIM4_MOD_LTVOFF:
mod->BSIM4ltvoff = value->rValue;
mod->BSIM4ltvoffGiven = TRUE;
break;
case BSIM4_MOD_LMINV:
mod->BSIM4lminv = value->rValue;
mod->BSIM4lminvGiven = TRUE;
@ -1214,6 +1693,26 @@ GENmodel *inMod;
mod->BSIM4lxrcrg2 = value->rValue;
mod->BSIM4lxrcrg2Given = TRUE;
break;
case BSIM4_MOD_LLAMBDA :
mod->BSIM4llambda = value->rValue;
mod->BSIM4llambdaGiven = TRUE;
break;
case BSIM4_MOD_LVTL :
mod->BSIM4lvtl = value->rValue;
mod->BSIM4lvtlGiven = TRUE;
break;
case BSIM4_MOD_LXN:
mod->BSIM4lxn = value->rValue;
mod->BSIM4lxnGiven = TRUE;
break;
case BSIM4_MOD_LVFBSDOFF:
mod->BSIM4lvfbsdoff = value->rValue;
mod->BSIM4lvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_LTVFBSDOFF:
mod->BSIM4ltvfbsdoff = value->rValue;
mod->BSIM4ltvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_LEU :
mod->BSIM4leu = value->rValue;
mod->BSIM4leuGiven = TRUE;
@ -1222,7 +1721,6 @@ GENmodel *inMod;
mod->BSIM4lvfb = value->rValue;
mod->BSIM4lvfbGiven = TRUE;
break;
case BSIM4_MOD_LCGSL :
mod->BSIM4lcgsl = value->rValue;
mod->BSIM4lcgslGiven = TRUE;
@ -1491,6 +1989,10 @@ GENmodel *inMod;
mod->BSIM4wvoff = value->rValue;
mod->BSIM4wvoffGiven = TRUE;
break;
case BSIM4_MOD_WTVOFF:
mod->BSIM4wtvoff = value->rValue;
mod->BSIM4wtvoffGiven = TRUE;
break;
case BSIM4_MOD_WMINV:
mod->BSIM4wminv = value->rValue;
mod->BSIM4wminvGiven = TRUE;
@ -1707,6 +2209,26 @@ GENmodel *inMod;
mod->BSIM4wxrcrg2 = value->rValue;
mod->BSIM4wxrcrg2Given = TRUE;
break;
case BSIM4_MOD_WLAMBDA :
mod->BSIM4wlambda = value->rValue;
mod->BSIM4wlambdaGiven = TRUE;
break;
case BSIM4_MOD_WVTL :
mod->BSIM4wvtl = value->rValue;
mod->BSIM4wvtlGiven = TRUE;
break;
case BSIM4_MOD_WXN:
mod->BSIM4wxn = value->rValue;
mod->BSIM4wxnGiven = TRUE;
break;
case BSIM4_MOD_WVFBSDOFF:
mod->BSIM4wvfbsdoff = value->rValue;
mod->BSIM4wvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_WTVFBSDOFF:
mod->BSIM4wtvfbsdoff = value->rValue;
mod->BSIM4wtvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_WEU :
mod->BSIM4weu = value->rValue;
mod->BSIM4weuGiven = TRUE;
@ -1715,7 +2237,6 @@ GENmodel *inMod;
mod->BSIM4wvfb = value->rValue;
mod->BSIM4wvfbGiven = TRUE;
break;
case BSIM4_MOD_WCGSL :
mod->BSIM4wcgsl = value->rValue;
mod->BSIM4wcgslGiven = TRUE;
@ -1984,6 +2505,10 @@ GENmodel *inMod;
mod->BSIM4pvoff = value->rValue;
mod->BSIM4pvoffGiven = TRUE;
break;
case BSIM4_MOD_PTVOFF:
mod->BSIM4ptvoff = value->rValue;
mod->BSIM4ptvoffGiven = TRUE;
break;
case BSIM4_MOD_PMINV:
mod->BSIM4pminv = value->rValue;
mod->BSIM4pminvGiven = TRUE;
@ -2200,6 +2725,26 @@ GENmodel *inMod;
mod->BSIM4pxrcrg2 = value->rValue;
mod->BSIM4pxrcrg2Given = TRUE;
break;
case BSIM4_MOD_PLAMBDA :
mod->BSIM4plambda = value->rValue;
mod->BSIM4plambdaGiven = TRUE;
break;
case BSIM4_MOD_PVTL :
mod->BSIM4pvtl = value->rValue;
mod->BSIM4pvtlGiven = TRUE;
break;
case BSIM4_MOD_PXN:
mod->BSIM4pxn = value->rValue;
mod->BSIM4pxnGiven = TRUE;
break;
case BSIM4_MOD_PVFBSDOFF:
mod->BSIM4pvfbsdoff = value->rValue;
mod->BSIM4pvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_PTVFBSDOFF:
mod->BSIM4ptvfbsdoff = value->rValue;
mod->BSIM4ptvfbsdoffGiven = TRUE;
break;
case BSIM4_MOD_PEU :
mod->BSIM4peu = value->rValue;
mod->BSIM4peuGiven = TRUE;
@ -2208,7 +2753,6 @@ GENmodel *inMod;
mod->BSIM4pvfb = value->rValue;
mod->BSIM4pvfbGiven = TRUE;
break;
case BSIM4_MOD_PCGSL :
mod->BSIM4pcgsl = value->rValue;
mod->BSIM4pcgslGiven = TRUE;

View File

@ -1,22 +1,25 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4noi.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4noi.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "bsim4def.h"
#include "cktdefs.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "suffix.h"
#include "const.h"
@ -36,22 +39,24 @@ BSIM4model *model;
BSIM4instance *here;
{
struct bsim4SizeDependParam *pParam;
double cd, esat, DelClm, EffFreq, N0, Nl;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi;
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->BSIM4cd);
esat = 2.0 * pParam->BSIM4vsattemp / here->BSIM4ueff;
Leff = pParam->BSIM4leff - 2.0 * model->BSIM4lintnoi;
Leffsq = Leff * Leff;
esat = 2.0 * here->BSIM4vsattemp / here->BSIM4ueff;
if(model->BSIM4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX */
else {
T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl)
+ model->BSIM4em) / esat);
DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG));
if (DelClm < 0.0) DelClm = 0.0; /* bugfix */
}
EffFreq = pow(freq, model->BSIM4ef);
T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff;
T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe
* pParam->BSIM4leff * pParam->BSIM4leff;
T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe * Leffsq;
N0 = model->BSIM4coxe * here->BSIM4Vgsteff / CHARGE;
Nl = model->BSIM4coxe * here->BSIM4Vgsteff
* (1.0 - here->BSIM4AbovVgst2Vtm * here->BSIM4Vdseff) / CHARGE;
@ -62,8 +67,7 @@ double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi;
T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
T6 = CONSTboltz * temp * cd * cd;
T7 = 1.0e10 * EffFreq * pParam->BSIM4leff
* pParam->BSIM4leff * pParam->BSIM4weff;
T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4weff * here->BSIM4nf;
T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl
+ model->BSIM4oxideTrapDensityC * Nl * Nl;
T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar);
@ -89,12 +93,13 @@ double tempInoise;
double noizDens[BSIM4NSRCS];
double lnNdens[BSIM4NSRCS];
double N0, Nl;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13;
double Vds, n, ExpArg, Ssi, Swi;
double tmp, gdpr, gspr, npart_theta, npart_beta, igsquare;
double T0, T1, T2, T5, T10, T11;
double Vds, Ssi, Swi;
double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode;
int error, i;
double m;
int i;
/* define the names of the noise sources */
static char *BSIM4nNames[BSIM4NSRCS] =
@ -181,6 +186,7 @@ int error, i;
}
break;
case N_CALC:
m = here->BSIM4m;
switch (mode)
{ case N_DENS:
if (model->BSIM4tnoiMod == 0)
@ -201,9 +207,9 @@ int error, i;
else
{ T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T5 *= T5;
npart_beta = 0.577 * (1.0 + T5
npart_beta = model->BSIM4rnoia * (1.0 + T5
* model->BSIM4tnoia * pParam->BSIM4leff);
npart_theta = 0.37 * (1.0 + T5
npart_theta = model->BSIM4rnoib * (1.0 + T5
* model->BSIM4tnoib * pParam->BSIM4leff);
if (model->BSIM4rdsMod == 0)
@ -216,35 +222,35 @@ int error, i;
}
if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0)
gspr = gspr * (1.0 + npart_theta * npart_theta * gspr
/ here->BSIM4IdovVds);
gspr = gspr / (1.0 + npart_theta * npart_theta * gspr
/ here->BSIM4IdovVds); /* bugfix */
else
gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr
gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr
/ here->BSIM4IdovVds);
}
NevalSrc(&noizDens[BSIM4RDNOIZ],
&lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE,
here->BSIM4dNodePrime, here->BSIM4dNode,
gdpr);
gdpr * m);
NevalSrc(&noizDens[BSIM4RSNOIZ],
&lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE,
here->BSIM4sNodePrime, here->BSIM4sNode,
gspr);
gspr * m);
if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2))
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodePrime, here->BSIM4gNodeExt,
here->BSIM4grgeltd);
here->BSIM4grgeltd * m);
}
else if (here->BSIM4rgateMod == 3)
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodeMid, here->BSIM4gNodeExt,
here->BSIM4grgeltd);
here->BSIM4grgeltd * m);
}
else
{ noizDens[BSIM4RGNOIZ] = 0.0;
@ -252,28 +258,79 @@ int error, i;
log(MAX(noizDens[BSIM4RGNOIZ], N_MINLOG));
}
bodymode = 5;
if (here->BSIM4rbodyMod == 2)
{ if( ( !model->BSIM4rbps0Given) ||
( !model->BSIM4rbpd0Given) )
bodymode = 1;
else
if( (!model->BSIM4rbsbx0Given && !model->BSIM4rbsby0Given) ||
(!model->BSIM4rbdbx0Given && !model->BSIM4rbdby0Given) )
bodymode = 3;
}
if (here->BSIM4rbodyMod)
{ NevalSrc(&noizDens[BSIM4RBPSNOIZ],
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4sbNode,
here->BSIM4grbps);
NevalSrc(&noizDens[BSIM4RBPDNOIZ],
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4dbNode,
here->BSIM4grbpd);
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb);
NevalSrc(&noizDens[BSIM4RBSBNOIZ],
&lnNdens[BSIM4RBSBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4sbNode,
here->BSIM4grbsb);
NevalSrc(&noizDens[BSIM4RBDBNOIZ],
&lnNdens[BSIM4RBDBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4dbNode,
here->BSIM4grbdb);
{
if(bodymode == 5)
{
NevalSrc(&noizDens[BSIM4RBPSNOIZ],
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4sbNode,
here->BSIM4grbps * m);
NevalSrc(&noizDens[BSIM4RBPDNOIZ],
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4dbNode,
here->BSIM4grbpd * m);
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
NevalSrc(&noizDens[BSIM4RBSBNOIZ],
&lnNdens[BSIM4RBSBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4sbNode,
here->BSIM4grbsb * m);
NevalSrc(&noizDens[BSIM4RBDBNOIZ],
&lnNdens[BSIM4RBDBNOIZ], ckt, THERMNOISE,
here->BSIM4bNode, here->BSIM4dbNode,
here->BSIM4grbdb * m);
}
if(bodymode == 3)
{
NevalSrc(&noizDens[BSIM4RBPSNOIZ],
&lnNdens[BSIM4RBPSNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4sbNode,
here->BSIM4grbps * m);
NevalSrc(&noizDens[BSIM4RBPDNOIZ],
&lnNdens[BSIM4RBPDNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4dbNode,
here->BSIM4grbpd * m);
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0;
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
if(bodymode == 1)
{
NevalSrc(&noizDens[BSIM4RBPBNOIZ],
&lnNdens[BSIM4RBPBNOIZ], ckt, THERMNOISE,
here->BSIM4bNodePrime, here->BSIM4bNode,
here->BSIM4grbpb * m);
noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
noizDens[BSIM4RBSBNOIZ] = noizDens[BSIM4RBDBNOIZ] = 0.0;
lnNdens[BSIM4RBPSNOIZ] =
log(MAX(noizDens[BSIM4RBPSNOIZ], N_MINLOG));
lnNdens[BSIM4RBPDNOIZ] =
log(MAX(noizDens[BSIM4RBPDNOIZ], N_MINLOG));
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
}
else
{ noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
@ -294,7 +351,7 @@ int error, i;
switch(model->BSIM4tnoiMod)
{ case 0:
T0 = here->BSIM4ueff * fabs(here->BSIM4qinv);
T0 = m * here->BSIM4ueff * fabs(here->BSIM4qinv);
T1 = T0 * tmp + pParam->BSIM4leff
* pParam->BSIM4leff;
NevalSrc(&noizDens[BSIM4IDNOIZ],
@ -304,7 +361,7 @@ int error, i;
(T0 / T1) * model->BSIM4ntnoi);
break;
case 1:
T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds;
T0 = m * here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds;
T0 *= T0;
igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds;
T1 = npart_beta * (here->BSIM4gm
@ -323,7 +380,7 @@ int error, i;
switch(model->BSIM4fnoiMod)
{ case 0:
noizDens[BSIM4FLNOIZ] *= model->BSIM4kf
noizDens[BSIM4FLNOIZ] *= m * model->BSIM4kf
* exp(model->BSIM4af
* log(MAX(fabs(here->BSIM4cd),
N_MINLOG)))
@ -341,14 +398,14 @@ int error, i;
data->freq, ckt->CKTtemp);
T10 = model->BSIM4oxideTrapDensityA
* CONSTboltz * ckt->CKTtemp;
T11 = pParam->BSIM4weff * pParam->BSIM4leff
T11 = pParam->BSIM4weff * here->BSIM4nf * pParam->BSIM4leff
* pow(data->freq, model->BSIM4ef) * 1.0e10
* here->BSIM4nstar * here->BSIM4nstar;
Swi = T10 / T11 * here->BSIM4cd
* here->BSIM4cd;
T1 = Swi + Ssi;
if (T1 > 0.0)
noizDens[BSIM4FLNOIZ] *= (Ssi * Swi) / T1;
noizDens[BSIM4FLNOIZ] *= m * (Ssi * Swi) / T1;
else
noizDens[BSIM4FLNOIZ] *= 0.0;
break;
@ -358,19 +415,29 @@ int error, i;
log(MAX(noizDens[BSIM4FLNOIZ], N_MINLOG));
if(here->BSIM4mode >= 0) { /* bugfix */
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
(here->BSIM4Igs + here->BSIM4Igcs));
m * (here->BSIM4Igs + here->BSIM4Igcs));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
(here->BSIM4Igd + here->BSIM4Igcd));
m * (here->BSIM4Igd + here->BSIM4Igcd));
} else {
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
m * (here->BSIM4Igs + here->BSIM4Igcd));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
m * (here->BSIM4Igd + here->BSIM4Igcs));
}
NevalSrc(&noizDens[BSIM4IGBNOIZ],
&lnNdens[BSIM4IGBNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4bNodePrime,
here->BSIM4Igb);
m * here->BSIM4Igb);
noizDens[BSIM4TOTNOIZ] = noizDens[BSIM4RDNOIZ]

View File

@ -1,18 +1,22 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4par.c of BSIM4.2.1.
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4par.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4param(param,value,inst,select)
@ -31,7 +35,11 @@ IFvalue *select;
here->BSIM4l = value->rValue;
here->BSIM4lGiven = TRUE;
break;
case BSIM4_NF:
case BSIM4_M:
here->BSIM4m = value->rValue;
here->BSIM4mGiven = TRUE;
break;
case BSIM4_NF:
here->BSIM4nf = value->rValue;
here->BSIM4nfGiven = TRUE;
break;
@ -66,6 +74,34 @@ IFvalue *select;
case BSIM4_OFF:
here->BSIM4off = value->iValue;
break;
case BSIM4_SA:
here->BSIM4sa = value->rValue;
here->BSIM4saGiven = TRUE;
break;
case BSIM4_SB:
here->BSIM4sb = value->rValue;
here->BSIM4sbGiven = TRUE;
break;
case BSIM4_SD:
here->BSIM4sd = value->rValue;
here->BSIM4sdGiven = TRUE;
break;
case BSIM4_SCA:
here->BSIM4sca = value->rValue;
here->BSIM4scaGiven = TRUE;
break;
case BSIM4_SCB:
here->BSIM4scb = value->rValue;
here->BSIM4scbGiven = TRUE;
break;
case BSIM4_SCC:
here->BSIM4scc = value->rValue;
here->BSIM4sccGiven = TRUE;
break;
case BSIM4_SC:
here->BSIM4sc = value->rValue;
here->BSIM4scGiven = TRUE;
break;
case BSIM4_RBSB:
here->BSIM4rbsb = value->rValue;
here->BSIM4rbsbGiven = TRUE;
@ -86,6 +122,18 @@ IFvalue *select;
here->BSIM4rbpd = value->rValue;
here->BSIM4rbpdGiven = TRUE;
break;
case BSIM4_DELVTO:
here->BSIM4delvto = value->rValue;
here->BSIM4delvtoGiven = TRUE;
break;
case BSIM4_XGW:
here->BSIM4xgw = value->rValue;
here->BSIM4xgwGiven = TRUE;
break;
case BSIM4_NGCON:
here->BSIM4ngcon = value->rValue;
here->BSIM4ngconGiven = TRUE;
break;
case BSIM4_TRNQSMOD:
here->BSIM4trnqsMod = value->iValue;
here->BSIM4trnqsModGiven = TRUE;

View File

@ -1,21 +1,20 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4pzld.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4pzld.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "complex.h"
#include "sperror.h"
#include "bsim4def.h"
#include "suffix.h"
int
BSIM4pzLoad(inModel,ckt,s)
@ -29,7 +28,7 @@ BSIM4instance *here;
double gjbd, gjbs, geltd, gcrg, gcrgg, gcrgd, gcrgs, gcrgb;
double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb;
double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb;
double gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, Gm, Gmbs;
double gds, capbd, capbs, FwdSum, RevSum, Gm, Gmbs;
double gstot, gstotd, gstotg, gstots, gstotb, gspr;
double gdtot, gdtotd, gdtotg, gdtots, gdtotb, gdpr;
double gIstotg, gIstotd, gIstots, gIstotb;
@ -37,24 +36,25 @@ double gIdtotg, gIdtotd, gIdtots, gIdtotb;
double gIbtotg, gIbtotd, gIbtots, gIbtotb;
double gIgtotg, gIgtotd, gIgtots, gIgtotb;
double cgso, cgdo, cgbo;
double xcdbdb, xcsbsb, xcgmgmb, xcgmdb, xcgmsb, xcdgmb, xcsgmb;
double xcgmbb, xcbgmb;
double dxpart, sxpart, xgtg, xgtd, xgts, xgtb, xcqgb, xcqdb, xcqsb, xcqbb;
double xcdbdb=0.0, xcsbsb=0.0, xcgmgmb=0.0, xcgmdb=0.0, xcgmsb=0.0, xcdgmb=0.0, xcsgmb=0.0;
double xcgmbb=0.0, xcbgmb=0.0;
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 T0, T1, CoxWL, qcheq, Cdg, Cdd, Cds, Cdb, Csg, Csd, Css, Csb;
double T0=0.0, T1, CoxWL, qcheq, Cdg, Cdd, Cds, Csg, Csd, Css;
double ScalingFactor = 1.0e-9;
struct bsim4SizeDependParam *pParam;
double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls;
double m;
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here!= NULL;
here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
pParam = here->pParam;
{ if (here->BSIM4owner != ARCHme) continue;
pParam = here->pParam;
capbd = here->BSIM4capbd;
capbs = here->BSIM4capbs;
cgso = here->BSIM4cgso;
@ -483,6 +483,7 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
/*
* Loading PZ matrix
*/
m = here->BSIM4m;
if (!model->BSIM4rdsMod)
{ gdpr = here->BSIM4drainConductance;
@ -501,165 +502,165 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
geltd = here->BSIM4grgeltd;
if (here->BSIM4rgateMod == 1)
{ *(here->BSIM4GEgePtr) += geltd;
*(here->BSIM4GPgePtr) -= geltd;
*(here->BSIM4GEgpPtr) -= geltd;
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GPgePtr) -= m * geltd;
*(here->BSIM4GEgpPtr) -= m * geltd;
*(here->BSIM4GPgpPtr ) += xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += xcggb * s->imag;
*(here->BSIM4GPgpPtr) += geltd - xgtg + gIgtotg;
*(here->BSIM4GPdpPtr ) += xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= xgtd - gIgtotd;
*(here->BSIM4GPspPtr ) += xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= xgts - gIgtots;
*(here->BSIM4GPbpPtr ) += xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= xgtb - gIgtotb;
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag;
*(here->BSIM4GPgpPtr) += m * (geltd - xgtg + gIgtotg);
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= m * (xgtd - gIgtotd);
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= m * (xgts - gIgtots);
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= m * (xgtb - gIgtotb);
}
else if (here->BSIM4rgateMod == 2)
{ *(here->BSIM4GEgePtr) += gcrg;
*(here->BSIM4GEgpPtr) += gcrgg;
*(here->BSIM4GEdpPtr) += gcrgd;
*(here->BSIM4GEspPtr) += gcrgs;
*(here->BSIM4GEbpPtr) += gcrgb;
{ *(here->BSIM4GEgePtr) += m * gcrg;
*(here->BSIM4GEgpPtr) += m * gcrgg;
*(here->BSIM4GEdpPtr) += m * gcrgd;
*(here->BSIM4GEspPtr) += m * gcrgs;
*(here->BSIM4GEbpPtr) += m * gcrgb;
*(here->BSIM4GPgePtr) -= gcrg;
*(here->BSIM4GPgpPtr ) += xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += xcggb * s->imag;
*(here->BSIM4GPgpPtr) -= gcrgg + xgtg - gIgtotg;
*(here->BSIM4GPdpPtr ) += xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= gcrgd + xgtd - gIgtotd;
*(here->BSIM4GPspPtr ) += xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= gcrgs + xgts - gIgtots;
*(here->BSIM4GPbpPtr ) += xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= gcrgb + xgtb - gIgtotb;
*(here->BSIM4GPgePtr) -= m * gcrg;
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag;
*(here->BSIM4GPgpPtr) -= m * (gcrgg + xgtg - gIgtotg);
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= m * (gcrgd + xgtd - gIgtotd);
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= m * (gcrgs + xgts - gIgtots);
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= m * (gcrgb + xgtb - gIgtotb);
}
else if (here->BSIM4rgateMod == 3)
{ *(here->BSIM4GEgePtr) += geltd;
*(here->BSIM4GEgmPtr) -= geltd;
*(here->BSIM4GMgePtr) -= geltd;
*(here->BSIM4GMgmPtr) += geltd + gcrg;
*(here->BSIM4GMgmPtr ) += xcgmgmb * s->real;
*(here->BSIM4GMgmPtr +1) += xcgmgmb * s->imag;
{ *(here->BSIM4GEgePtr) += m * geltd;
*(here->BSIM4GEgmPtr) -= m * geltd;
*(here->BSIM4GMgePtr) -= m * geltd;
*(here->BSIM4GMgmPtr) += m * (geltd + gcrg);
*(here->BSIM4GMgmPtr ) += m * xcgmgmb * s->real;
*(here->BSIM4GMgmPtr +1) += m * xcgmgmb * s->imag;
*(here->BSIM4GMdpPtr) += gcrgd;
*(here->BSIM4GMdpPtr ) += xcgmdb * s->real;
*(here->BSIM4GMdpPtr +1) += xcgmdb * s->imag;
*(here->BSIM4GMgpPtr) += gcrgg;
*(here->BSIM4GMspPtr) += gcrgs;
*(here->BSIM4GMspPtr ) += xcgmsb * s->real;
*(here->BSIM4GMspPtr +1) += xcgmsb * s->imag;
*(here->BSIM4GMbpPtr) += gcrgb;
*(here->BSIM4GMbpPtr ) += xcgmbb * s->real;
*(here->BSIM4GMbpPtr +1) += xcgmbb * s->imag;
*(here->BSIM4GMdpPtr) += m * gcrgd;
*(here->BSIM4GMdpPtr ) += m * xcgmdb * s->real;
*(here->BSIM4GMdpPtr +1) += m * xcgmdb * s->imag;
*(here->BSIM4GMgpPtr) += m * gcrgg;
*(here->BSIM4GMspPtr) += m * gcrgs;
*(here->BSIM4GMspPtr ) += m * xcgmsb * s->real;
*(here->BSIM4GMspPtr +1) += m * xcgmsb * s->imag;
*(here->BSIM4GMbpPtr) += m * gcrgb;
*(here->BSIM4GMbpPtr ) += m * xcgmbb * s->real;
*(here->BSIM4GMbpPtr +1) += m * xcgmbb * s->imag;
*(here->BSIM4DPgmPtr ) += xcdgmb * s->real;
*(here->BSIM4DPgmPtr +1) += xcdgmb * s->imag;
*(here->BSIM4GPgmPtr) -= gcrg;
*(here->BSIM4SPgmPtr ) += xcsgmb * s->real;
*(here->BSIM4SPgmPtr +1) += xcsgmb * s->imag;
*(here->BSIM4BPgmPtr ) += xcbgmb * s->real;
*(here->BSIM4BPgmPtr +1) += xcbgmb * s->imag;
*(here->BSIM4DPgmPtr ) += m * xcdgmb * s->real;
*(here->BSIM4DPgmPtr +1) += m * xcdgmb * s->imag;
*(here->BSIM4GPgmPtr) -= m * gcrg;
*(here->BSIM4SPgmPtr ) += m * xcsgmb * s->real;
*(here->BSIM4SPgmPtr +1) += m * xcsgmb * s->imag;
*(here->BSIM4BPgmPtr ) += m * xcbgmb * s->real;
*(here->BSIM4BPgmPtr +1) += m * xcbgmb * s->imag;
*(here->BSIM4GPgpPtr) -= gcrgg + xgtg - gIgtotg;
*(here->BSIM4GPgpPtr ) += xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += xcggb * s->imag;
*(here->BSIM4GPdpPtr) -= gcrgd + xgtd - gIgtotd;
*(here->BSIM4GPdpPtr ) += xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += xcgdb * s->imag;
*(here->BSIM4GPspPtr) -= gcrgs + xgts - gIgtots;
*(here->BSIM4GPspPtr ) += xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += xcgsb * s->imag;
*(here->BSIM4GPbpPtr) -= gcrgb + xgtb - gIgtotb;
*(here->BSIM4GPbpPtr ) += xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += xcgbb * s->imag;
*(here->BSIM4GPgpPtr) -= m * (gcrgg + xgtg - gIgtotg);
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag;
*(here->BSIM4GPdpPtr) -= m * (gcrgd + xgtd - gIgtotd);
*(here->BSIM4GPdpPtr ) += m * xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag;
*(here->BSIM4GPspPtr) -= m * (gcrgs + xgts - gIgtots);
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag;
*(here->BSIM4GPbpPtr) -= m * (gcrgb + xgtb - gIgtotb);
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag;
}
else
{ *(here->BSIM4GPdpPtr ) += xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= xgtd - gIgtotd;
*(here->BSIM4GPgpPtr ) += xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += xcggb * s->imag;
*(here->BSIM4GPgpPtr) -= xgtg - gIgtotg;
*(here->BSIM4GPspPtr ) += xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= xgts - gIgtots;
*(here->BSIM4GPbpPtr ) += xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= xgtb - gIgtotb;
{ *(here->BSIM4GPdpPtr ) += m * xcgdb * s->real;
*(here->BSIM4GPdpPtr +1) += m * xcgdb * s->imag;
*(here->BSIM4GPdpPtr) -= m * (xgtd - gIgtotd);
*(here->BSIM4GPgpPtr ) += m * xcggb * s->real;
*(here->BSIM4GPgpPtr +1) += m * xcggb * s->imag;
*(here->BSIM4GPgpPtr) -= m * (xgtg - gIgtotg);
*(here->BSIM4GPspPtr ) += m * xcgsb * s->real;
*(here->BSIM4GPspPtr +1) += m * xcgsb * s->imag;
*(here->BSIM4GPspPtr) -= m * (xgts - gIgtots);
*(here->BSIM4GPbpPtr ) += m * xcgbb * s->real;
*(here->BSIM4GPbpPtr +1) += m * xcgbb * s->imag;
*(here->BSIM4GPbpPtr) -= m * (xgtb - gIgtotb);
}
if (model->BSIM4rdsMod)
{ (*(here->BSIM4DgpPtr) += gdtotg);
(*(here->BSIM4DspPtr) += gdtots);
(*(here->BSIM4DbpPtr) += gdtotb);
(*(here->BSIM4SdpPtr) += gstotd);
(*(here->BSIM4SgpPtr) += gstotg);
(*(here->BSIM4SbpPtr) += gstotb);
{ (*(here->BSIM4DgpPtr) += m * gdtotg);
(*(here->BSIM4DspPtr) += m * gdtots);
(*(here->BSIM4DbpPtr) += m * gdtotb);
(*(here->BSIM4SdpPtr) += m * gstotd);
(*(here->BSIM4SgpPtr) += m * gstotg);
(*(here->BSIM4SbpPtr) += m * gstotb);
}
*(here->BSIM4DPdpPtr ) += xcddb * s->real;
*(here->BSIM4DPdpPtr +1) += xcddb * s->imag;
*(here->BSIM4DPdpPtr) += gdpr + gds + here->BSIM4gbd
*(here->BSIM4DPdpPtr ) += m * xcddb * s->real;
*(here->BSIM4DPdpPtr +1) += m * xcddb * s->imag;
*(here->BSIM4DPdpPtr) += m * (gdpr + gds + here->BSIM4gbd
- gdtotd + RevSum + gbdpdp - gIdtotd
+ dxpart * xgtd + T1 * ddxpart_dVd;
*(here->BSIM4DPdPtr) -= gdpr + gdtot;
*(here->BSIM4DPgpPtr ) += xcdgb * s->real;
*(here->BSIM4DPgpPtr +1) += xcdgb * s->imag;
*(here->BSIM4DPgpPtr) += Gm - gdtotg + gbdpg - gIdtotg
+ T1 * ddxpart_dVg + dxpart * xgtg;
*(here->BSIM4DPspPtr ) += xcdsb * s->real;
*(here->BSIM4DPspPtr +1) += xcdsb * s->imag;
*(here->BSIM4DPspPtr) -= gds + FwdSum + gdtots - gbdpsp + gIdtots
- T1 * ddxpart_dVs - dxpart * xgts;
*(here->BSIM4DPbpPtr ) += xcdbb * s->real;
*(here->BSIM4DPbpPtr +1) += xcdbb * s->imag;
*(here->BSIM4DPbpPtr) -= gjbd + gdtotb - Gmbs - gbdpb + gIdtotb
- T1 * ddxpart_dVb - dxpart * xgtb;
+ dxpart * xgtd + T1 * ddxpart_dVd);
*(here->BSIM4DPdPtr) -= m * (gdpr + gdtot);
*(here->BSIM4DPgpPtr ) += m * xcdgb * s->real;
*(here->BSIM4DPgpPtr +1) += m * xcdgb * s->imag;
*(here->BSIM4DPgpPtr) += m * (Gm - gdtotg + gbdpg - gIdtotg
+ T1 * ddxpart_dVg + dxpart * xgtg);
*(here->BSIM4DPspPtr ) += m * xcdsb * s->real;
*(here->BSIM4DPspPtr +1) += m * xcdsb * s->imag;
*(here->BSIM4DPspPtr) -= m * (gds + FwdSum + gdtots - gbdpsp + gIdtots
- T1 * ddxpart_dVs - dxpart * xgts);
*(here->BSIM4DPbpPtr ) += m * xcdbb * s->real;
*(here->BSIM4DPbpPtr +1) += m * xcdbb * s->imag;
*(here->BSIM4DPbpPtr) -= m * (gjbd + gdtotb - Gmbs - gbdpb + gIdtotb
- T1 * ddxpart_dVb - dxpart * xgtb);
*(here->BSIM4DdpPtr) -= gdpr - gdtotd;
*(here->BSIM4DdPtr) += gdpr + gdtot;
*(here->BSIM4DdpPtr) -= m * (gdpr - gdtotd);
*(here->BSIM4DdPtr) += m * (gdpr + gdtot);
*(here->BSIM4SPdpPtr ) += xcsdb * s->real;
*(here->BSIM4SPdpPtr +1) += xcsdb * s->imag;
*(here->BSIM4SPdpPtr) -= gds + gstotd + RevSum - gbspdp + gIstotd
- T1 * dsxpart_dVd - sxpart * xgtd;
*(here->BSIM4SPgpPtr ) += xcsgb * s->real;
*(here->BSIM4SPgpPtr +1) += xcsgb * s->imag;
*(here->BSIM4SPgpPtr) -= Gm + gstotg - gbspg + gIstotg
- T1 * dsxpart_dVg - sxpart * xgtg;
*(here->BSIM4SPspPtr ) += xcssb * s->real;
*(here->BSIM4SPspPtr +1) += xcssb * s->imag;
*(here->BSIM4SPspPtr) += gspr + gds + here->BSIM4gbs - gIstots
*(here->BSIM4SPdpPtr ) += m * xcsdb * s->real;
*(here->BSIM4SPdpPtr +1) += m * xcsdb * s->imag;
*(here->BSIM4SPdpPtr) -= m * (gds + gstotd + RevSum - gbspdp + gIstotd
- T1 * dsxpart_dVd - sxpart * xgtd);
*(here->BSIM4SPgpPtr ) += m * xcsgb * s->real;
*(here->BSIM4SPgpPtr +1) += m * xcsgb * s->imag;
*(here->BSIM4SPgpPtr) -= m * (Gm + gstotg - gbspg + gIstotg
- T1 * dsxpart_dVg - sxpart * xgtg);
*(here->BSIM4SPspPtr ) += m * xcssb * s->real;
*(here->BSIM4SPspPtr +1) += m * xcssb * s->imag;
*(here->BSIM4SPspPtr) += m * (gspr + gds + here->BSIM4gbs - gIstots
- gstots + FwdSum + gbspsp
+ sxpart * xgts + T1 * dsxpart_dVs;
*(here->BSIM4SPsPtr) -= gspr + gstot;
*(here->BSIM4SPbpPtr ) += xcsbb * s->real;
*(here->BSIM4SPbpPtr +1) += xcsbb * s->imag;
*(here->BSIM4SPbpPtr) -= gjbs + gstotb + Gmbs - gbspb + gIstotb
- T1 * dsxpart_dVb - sxpart * xgtb;
+ sxpart * xgts + T1 * dsxpart_dVs);
*(here->BSIM4SPsPtr) -= m * (gspr + gstot);
*(here->BSIM4SPbpPtr ) += m * xcsbb * s->real;
*(here->BSIM4SPbpPtr +1) += m * xcsbb * s->imag;
*(here->BSIM4SPbpPtr) -= m * (gjbs + gstotb + Gmbs - gbspb + gIstotb
- T1 * dsxpart_dVb - sxpart * xgtb);
*(here->BSIM4SspPtr) -= gspr - gstots;
*(here->BSIM4SsPtr) += gspr + gstot;
*(here->BSIM4SspPtr) -= m * (gspr - gstots);
*(here->BSIM4SsPtr) += m * (gspr + gstot);
*(here->BSIM4BPdpPtr ) += xcbdb * s->real;
*(here->BSIM4BPdpPtr +1) += xcbdb * s->imag;
*(here->BSIM4BPdpPtr) -= gjbd - gbbdp + gIbtotd;
*(here->BSIM4BPgpPtr ) += xcbgb * s->real;
*(here->BSIM4BPgpPtr +1) += xcbgb * s->imag;
*(here->BSIM4BPgpPtr) -= here->BSIM4gbgs + gIbtotg;
*(here->BSIM4BPspPtr ) += xcbsb * s->real;
*(here->BSIM4BPspPtr +1) += xcbsb * s->imag;
*(here->BSIM4BPspPtr) -= gjbs - gbbsp + gIbtots;
*(here->BSIM4BPbpPtr ) += xcbbb * s->real;
*(here->BSIM4BPbpPtr +1) += xcbbb * s->imag;
*(here->BSIM4BPbpPtr) += gjbd + gjbs - here->BSIM4gbbs
- gIbtotb;
*(here->BSIM4BPdpPtr ) += m * xcbdb * s->real;
*(here->BSIM4BPdpPtr +1) += m * xcbdb * s->imag;
*(here->BSIM4BPdpPtr) -= m * (gjbd - gbbdp + gIbtotd);
*(here->BSIM4BPgpPtr ) += m * xcbgb * s->real;
*(here->BSIM4BPgpPtr +1) += m * xcbgb * s->imag;
*(here->BSIM4BPgpPtr) -= m * (here->BSIM4gbgs + gIbtotg);
*(here->BSIM4BPspPtr ) += m * xcbsb * s->real;
*(here->BSIM4BPspPtr +1) += m * xcbsb * s->imag;
*(here->BSIM4BPspPtr) -= m * (gjbs - gbbsp + gIbtots);
*(here->BSIM4BPbpPtr ) += m * xcbbb * s->real;
*(here->BSIM4BPbpPtr +1) += m * xcbbb * s->imag;
*(here->BSIM4BPbpPtr) += m * (gjbd + gjbs - here->BSIM4gbbs
- gIbtotb);
ggidld = here->BSIM4ggidld;
ggidlg = here->BSIM4ggidlg;
ggidlb = here->BSIM4ggidlb;
@ -668,87 +669,87 @@ double ggidld, ggidlg, ggidlb,ggisld, ggislg, ggislb, ggisls;
ggislb = here->BSIM4ggislb;
/* stamp gidl */
(*(here->BSIM4DPdpPtr) += ggidld);
(*(here->BSIM4DPgpPtr) += ggidlg);
(*(here->BSIM4DPspPtr) -= (ggidlg + ggidld) + ggidlb);
(*(here->BSIM4DPbpPtr) += ggidlb);
(*(here->BSIM4BPdpPtr) -= ggidld);
(*(here->BSIM4BPgpPtr) -= ggidlg);
(*(here->BSIM4BPspPtr) += (ggidlg + ggidld) + ggidlb);
(*(here->BSIM4BPbpPtr) -= ggidlb);
(*(here->BSIM4DPdpPtr) += m * ggidld);
(*(here->BSIM4DPgpPtr) += m * ggidlg);
(*(here->BSIM4DPspPtr) -= m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4DPbpPtr) += m * ggidlb);
(*(here->BSIM4BPdpPtr) -= m * ggidld);
(*(here->BSIM4BPgpPtr) -= m * ggidlg);
(*(here->BSIM4BPspPtr) += m * ((ggidlg + ggidld) + ggidlb));
(*(here->BSIM4BPbpPtr) -= m * ggidlb);
/* stamp gisl */
(*(here->BSIM4SPdpPtr) -= (ggisls + ggislg) + ggislb);
(*(here->BSIM4SPgpPtr) += ggislg);
(*(here->BSIM4SPspPtr) += ggisls);
(*(here->BSIM4SPbpPtr) += ggislb);
(*(here->BSIM4BPdpPtr) += (ggislg + ggisls) + ggislb);
(*(here->BSIM4BPgpPtr) -= ggislg);
(*(here->BSIM4BPspPtr) -= ggisls);
(*(here->BSIM4BPbpPtr) -= ggislb);
(*(here->BSIM4SPdpPtr) -= m * ((ggisls + ggislg) + ggislb));
(*(here->BSIM4SPgpPtr) += m * ggislg);
(*(here->BSIM4SPspPtr) += m * ggisls);
(*(here->BSIM4SPbpPtr) += m * ggislb);
(*(here->BSIM4BPdpPtr) += m * ((ggislg + ggisls) + ggislb));
(*(here->BSIM4BPgpPtr) -= m * ggislg);
(*(here->BSIM4BPspPtr) -= m * ggisls);
(*(here->BSIM4BPbpPtr) -= m * ggislb);
if (here->BSIM4rbodyMod)
{ (*(here->BSIM4DPdbPtr ) += xcdbdb * s->real);
(*(here->BSIM4DPdbPtr +1) += xcdbdb * s->imag);
(*(here->BSIM4DPdbPtr) -= here->BSIM4gbd);
(*(here->BSIM4SPsbPtr ) += xcsbsb * s->real);
(*(here->BSIM4SPsbPtr +1) += xcsbsb * s->imag);
(*(here->BSIM4SPsbPtr) -= here->BSIM4gbs);
{ (*(here->BSIM4DPdbPtr ) += m * xcdbdb * s->real);
(*(here->BSIM4DPdbPtr +1) += m * xcdbdb * s->imag);
(*(here->BSIM4DPdbPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4SPsbPtr ) += m * xcsbsb * s->real);
(*(here->BSIM4SPsbPtr +1) += m * xcsbsb * s->imag);
(*(here->BSIM4SPsbPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4DBdpPtr ) += xcdbdb * s->real);
(*(here->BSIM4DBdpPtr +1) += xcdbdb * s->imag);
(*(here->BSIM4DBdpPtr) -= here->BSIM4gbd);
(*(here->BSIM4DBdbPtr ) -= xcdbdb * s->real);
(*(here->BSIM4DBdbPtr +1) -= xcdbdb * s->imag);
(*(here->BSIM4DBdbPtr) += here->BSIM4gbd + here->BSIM4grbpd
+ here->BSIM4grbdb);
(*(here->BSIM4DBbpPtr) -= here->BSIM4grbpd);
(*(here->BSIM4DBbPtr) -= here->BSIM4grbdb);
(*(here->BSIM4DBdpPtr ) += m * xcdbdb * s->real);
(*(here->BSIM4DBdpPtr +1) += m * xcdbdb * s->imag);
(*(here->BSIM4DBdpPtr) -= m * here->BSIM4gbd);
(*(here->BSIM4DBdbPtr ) -= m * xcdbdb * s->real);
(*(here->BSIM4DBdbPtr +1) -= m * xcdbdb * s->imag);
(*(here->BSIM4DBdbPtr) += m * (here->BSIM4gbd + here->BSIM4grbpd
+ here->BSIM4grbdb));
(*(here->BSIM4DBbpPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4DBbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BPdbPtr) -= here->BSIM4grbpd);
(*(here->BSIM4BPbPtr) -= here->BSIM4grbpb);
(*(here->BSIM4BPsbPtr) -= here->BSIM4grbps);
(*(here->BSIM4BPbpPtr) += here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb);
(*(here->BSIM4BPdbPtr) -= m * here->BSIM4grbpd);
(*(here->BSIM4BPbPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BPsbPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4BPbpPtr) += m * (here->BSIM4grbpd + here->BSIM4grbps
+ here->BSIM4grbpb));
/* WDL: (-here->BSIM4gbbs) already added to BPbpPtr */
(*(here->BSIM4SBspPtr ) += xcsbsb * s->real);
(*(here->BSIM4SBspPtr +1) += xcsbsb * s->imag);
(*(here->BSIM4SBspPtr) -= here->BSIM4gbs);
(*(here->BSIM4SBbpPtr) -= here->BSIM4grbps);
(*(here->BSIM4SBbPtr) -= here->BSIM4grbsb);
(*(here->BSIM4SBsbPtr ) -= xcsbsb * s->real);
(*(here->BSIM4SBsbPtr +1) -= xcsbsb * s->imag);
(*(here->BSIM4SBsbPtr) += here->BSIM4gbs
+ here->BSIM4grbps + here->BSIM4grbsb);
(*(here->BSIM4SBspPtr ) += m * xcsbsb * s->real);
(*(here->BSIM4SBspPtr +1) += m * xcsbsb * s->imag);
(*(here->BSIM4SBspPtr) -= m * here->BSIM4gbs);
(*(here->BSIM4SBbpPtr) -= m * here->BSIM4grbps);
(*(here->BSIM4SBbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4SBsbPtr ) -= m * xcsbsb * s->real);
(*(here->BSIM4SBsbPtr +1) -= m * xcsbsb * s->imag);
(*(here->BSIM4SBsbPtr) += m * (here->BSIM4gbs
+ here->BSIM4grbps + here->BSIM4grbsb));
(*(here->BSIM4BdbPtr) -= here->BSIM4grbdb);
(*(here->BSIM4BbpPtr) -= here->BSIM4grbpb);
(*(here->BSIM4BsbPtr) -= here->BSIM4grbsb);
(*(here->BSIM4BbPtr) += here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb);
(*(here->BSIM4BdbPtr) -= m * here->BSIM4grbdb);
(*(here->BSIM4BbpPtr) -= m * here->BSIM4grbpb);
(*(here->BSIM4BsbPtr) -= m * here->BSIM4grbsb);
(*(here->BSIM4BbPtr) += m * (here->BSIM4grbsb + here->BSIM4grbdb
+ here->BSIM4grbpb));
}
if (here->BSIM4acnqsMod)
{ *(here->BSIM4QqPtr ) += s->real * ScalingFactor;
*(here->BSIM4QqPtr +1) += s->imag * ScalingFactor;
*(here->BSIM4QgpPtr ) -= xcqgb * s->real;
*(here->BSIM4QgpPtr +1) -= xcqgb * s->imag;
*(here->BSIM4QdpPtr ) -= xcqdb * s->real;
*(here->BSIM4QdpPtr +1) -= xcqdb * s->imag;
*(here->BSIM4QbpPtr ) -= xcqbb * s->real;
*(here->BSIM4QbpPtr +1) -= xcqbb * s->imag;
*(here->BSIM4QspPtr ) -= xcqsb * s->real;
*(here->BSIM4QspPtr +1) -= xcqsb * s->imag;
{ *(here->BSIM4QqPtr ) += m * s->real * ScalingFactor;
*(here->BSIM4QqPtr +1) += m * s->imag * ScalingFactor;
*(here->BSIM4QgpPtr ) -= m * xcqgb * s->real;
*(here->BSIM4QgpPtr +1) -= m * xcqgb * s->imag;
*(here->BSIM4QdpPtr ) -= m * xcqdb * s->real;
*(here->BSIM4QdpPtr +1) -= m * xcqdb * s->imag;
*(here->BSIM4QbpPtr ) -= m * xcqbb * s->real;
*(here->BSIM4QbpPtr +1) -= m * xcqbb * s->imag;
*(here->BSIM4QspPtr ) -= m * xcqsb * s->real;
*(here->BSIM4QspPtr +1) -= m * xcqsb * s->imag;
*(here->BSIM4GPqPtr) -= here->BSIM4gtau;
*(here->BSIM4DPqPtr) += dxpart * here->BSIM4gtau;
*(here->BSIM4SPqPtr) += sxpart * here->BSIM4gtau;
*(here->BSIM4GPqPtr) -= m * here->BSIM4gtau;
*(here->BSIM4DPqPtr) += m * dxpart * here->BSIM4gtau;
*(here->BSIM4SPqPtr) += m * sxpart * here->BSIM4gtau;
*(here->BSIM4QqPtr) += here->BSIM4gtau;
*(here->BSIM4QgpPtr) += xgtg;
*(here->BSIM4QdpPtr) += xgtd;
*(here->BSIM4QbpPtr) += xgtb;
*(here->BSIM4QspPtr) += xgts;
*(here->BSIM4QqPtr) += m * here->BSIM4gtau;
*(here->BSIM4QgpPtr) += m * xgtg;
*(here->BSIM4QdpPtr) += m * xgtd;
*(here->BSIM4QbpPtr) += m * xgtb;
*(here->BSIM4QspPtr) += m * xgts;
}
}
}

View File

@ -1,18 +1,20 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4set.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4set.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
**********/
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "jobdefs.h" /* Needed because the model searches for noise Analysis */
#include "ftedefs.h" /* " " */
#include "smpdefs.h"
@ -20,7 +22,7 @@
#include "bsim4def.h"
#include "const.h"
#include "sperror.h"
#include "suffix.h"
#define MAX_EXP 5.834617425e14
#define MIN_EXP 1.713908431e-15
@ -30,6 +32,11 @@
#define PI 3.141592654
#define Charge_q 1.60219e-19
int
BSIM4PAeffGeo(double, int, int, double, double, double, double, double *, double *, double *, double *);
int
BSIM4RdseffGeo(double, int, int, int, double, double, double, double, double, int, double *);
int
BSIM4setup(matrix,inModel,ckt,states)
SMPmatrix *matrix;
@ -41,13 +48,12 @@ BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
int error;
CKTnode *tmp;
double tmp1, tmp2;
int noiseAnalGiven = 0, createNode; /* Criteria for new node creation */
double Rtot, DMCGeff, DMCIeff, DMDGeff;
JOB *job;
/* Search for a noise analysis request */
for (job = ((TSKtask *)(ft_curckt->ci_curTask))->jobs;job;job = job->JOBnextJob) {
for (job = ((TSKtask *)ft_curckt->ci_curTask)->jobs;job;job = job->JOBnextJob) {
if(strcmp(job->JOBname,"Noise Analysis")==0) {
noiseAnalGiven = 1;
break;
@ -97,7 +103,7 @@ JOB *job;
}
if (!model->BSIM4rbodyModGiven)
model->BSIM4rbodyMod = 0;
else if ((model->BSIM4rbodyMod != 0) && (model->BSIM4rbodyMod != 1))
else if ((model->BSIM4rbodyMod != 0) && (model->BSIM4rbodyMod != 1) && (model->BSIM4rbodyMod != 2))
{ model->BSIM4rbodyMod = 0;
printf("Warning: rbodyMod has been set to its default value: 0.\n");
}
@ -148,7 +154,8 @@ JOB *job;
if (!model->BSIM4igcModGiven)
model->BSIM4igcMod = 0;
else if ((model->BSIM4igcMod != 0) && (model->BSIM4igcMod != 1))
else if ((model->BSIM4igcMod != 0) && (model->BSIM4igcMod != 1)
&& (model->BSIM4igcMod != 2))
{ model->BSIM4igcMod = 0;
printf("Warning: igcMod has been set to its default value: 0.\n");
}
@ -158,9 +165,16 @@ JOB *job;
{ model->BSIM4igbMod = 0;
printf("Warning: igbMod has been set to its default value: 0.\n");
}
if (!model->BSIM4tempModGiven)
model->BSIM4tempMod = 0;
else if ((model->BSIM4tempMod != 0) && (model->BSIM4tempMod != 1)
&& (model->BSIM4tempMod != 2))
{ model->BSIM4tempMod = 0;
printf("Warning: tempMod has been set to its default value: 0.\n");
}
if (!model->BSIM4versionGiven)
model->BSIM4version = "4.2.1";
model->BSIM4version = "4.5.0";
if (!model->BSIM4toxrefGiven)
model->BSIM4toxref = 30.0e-10;
if (!model->BSIM4toxeGiven)
@ -268,6 +282,14 @@ JOB *job;
model->BSIM4uc = (model->BSIM4mobMod == 1) ? -0.0465 : -0.0465e-9;
if (!model->BSIM4uc1Given)
model->BSIM4uc1 = (model->BSIM4mobMod == 1) ? -0.056 : -0.056e-9;
if (!model->BSIM4udGiven)
model->BSIM4ud = 1.0e14; /* unit m**(-2) */
if (!model->BSIM4ud1Given)
model->BSIM4ud1 = 0.0;
if (!model->BSIM4upGiven)
model->BSIM4up = 0.0;
if (!model->BSIM4lpGiven)
model->BSIM4lp = 1.0e-8;
if (!model->BSIM4u0Given)
model->BSIM4u0 = (model->BSIM4type == NMOS) ? 0.067 : 0.025;
if (!model->BSIM4uteGiven)
@ -304,7 +326,6 @@ JOB *job;
model->BSIM4prwg = 1.0; /* in 1/V */
if (!model->BSIM4prwbGiven)
model->BSIM4prwb = 0.0;
if (!model->BSIM4prtGiven)
if (!model->BSIM4prtGiven)
model->BSIM4prt = 0.0;
if (!model->BSIM4eta0Given)
@ -340,7 +361,7 @@ JOB *job;
if (!model->BSIM4alpha1Given)
model->BSIM4alpha1 = 0.0;
if (!model->BSIM4beta0Given)
model->BSIM4beta0 = 30.0;
model->BSIM4beta0 = 0.0;
if (!model->BSIM4agidlGiven)
model->BSIM4agidl = 0.0;
if (!model->BSIM4bgidlGiven)
@ -350,27 +371,27 @@ JOB *job;
if (!model->BSIM4egidlGiven)
model->BSIM4egidl = 0.8; /* V */
if (!model->BSIM4aigcGiven)
model->BSIM4aigc = (model->BSIM4type == NMOS) ? 0.43 : 0.31;
model->BSIM4aigc = (model->BSIM4type == NMOS) ? 1.36e-2 : 9.80e-3;
if (!model->BSIM4bigcGiven)
model->BSIM4bigc = (model->BSIM4type == NMOS) ? 0.054 : 0.024;
model->BSIM4bigc = (model->BSIM4type == NMOS) ? 1.71e-3 : 7.59e-4;
if (!model->BSIM4cigcGiven)
model->BSIM4cigc = (model->BSIM4type == NMOS) ? 0.075 : 0.03;
if (!model->BSIM4aigsdGiven)
model->BSIM4aigsd = (model->BSIM4type == NMOS) ? 0.43 : 0.31;
model->BSIM4aigsd = (model->BSIM4type == NMOS) ? 1.36e-2 : 9.80e-3;
if (!model->BSIM4bigsdGiven)
model->BSIM4bigsd = (model->BSIM4type == NMOS) ? 0.054 : 0.024;
model->BSIM4bigsd = (model->BSIM4type == NMOS) ? 1.71e-3 : 7.59e-4;
if (!model->BSIM4cigsdGiven)
model->BSIM4cigsd = (model->BSIM4type == NMOS) ? 0.075 : 0.03;
if (!model->BSIM4aigbaccGiven)
model->BSIM4aigbacc = 0.43;
model->BSIM4aigbacc = 1.36e-2;
if (!model->BSIM4bigbaccGiven)
model->BSIM4bigbacc = 0.054;
model->BSIM4bigbacc = 1.71e-3;
if (!model->BSIM4cigbaccGiven)
model->BSIM4cigbacc = 0.075;
if (!model->BSIM4aigbinvGiven)
model->BSIM4aigbinv = 0.35;
model->BSIM4aigbinv = 1.11e-2;
if (!model->BSIM4bigbinvGiven)
model->BSIM4bigbinv = 0.03;
model->BSIM4bigbinv = 9.49e-4;
if (!model->BSIM4cigbinvGiven)
model->BSIM4cigbinv = 0.006;
if (!model->BSIM4nigcGiven)
@ -403,8 +424,29 @@ JOB *job;
model->BSIM4tnoia = 1.5;
if (!model->BSIM4tnoibGiven)
model->BSIM4tnoib = 3.5;
if (!model->BSIM4rnoiaGiven)
model->BSIM4rnoia = 0.577;
if (!model->BSIM4rnoibGiven)
model->BSIM4rnoib = 0.5164;
if (!model->BSIM4ntnoiGiven)
model->BSIM4ntnoi = 1.0;
if (!model->BSIM4lambdaGiven)
model->BSIM4lambda = 0.0;
if (!model->BSIM4vtlGiven)
model->BSIM4vtl = 2.0e5; /* unit m/s */
if (!model->BSIM4xnGiven)
model->BSIM4xn = 3.0;
if (!model->BSIM4lcGiven)
model->BSIM4lc = 5.0e-9;
if (!model->BSIM4vfbsdoffGiven)
model->BSIM4vfbsdoff = 0.0; /* unit v */
if (!model->BSIM4tvfbsdoffGiven)
model->BSIM4tvfbsdoff = 0.0;
if (!model->BSIM4tvoffGiven)
model->BSIM4tvoff = 0.0;
if (!model->BSIM4lintnoiGiven)
model->BSIM4lintnoi = 0.0; /* unit m */
if (!model->BSIM4xjbvsGiven)
model->BSIM4xjbvs = 1.0; /* no unit */
@ -414,6 +456,7 @@ JOB *job;
model->BSIM4bvs = 10.0; /* V */
if (!model->BSIM4bvdGiven)
model->BSIM4bvd = model->BSIM4bvs;
if (!model->BSIM4gbminGiven)
model->BSIM4gbmin = 1.0e-12; /* in mho */
if (!model->BSIM4rbdbGiven)
@ -427,6 +470,65 @@ JOB *job;
if (!model->BSIM4rbpdGiven)
model->BSIM4rbpd = 50.0;
if (!model->BSIM4rbps0Given)
model->BSIM4rbps0 = 50.0;
if (!model->BSIM4rbpslGiven)
model->BSIM4rbpsl = 0.0;
if (!model->BSIM4rbpswGiven)
model->BSIM4rbpsw = 0.0;
if (!model->BSIM4rbpsnfGiven)
model->BSIM4rbpsnf = 0.0;
if (!model->BSIM4rbpd0Given)
model->BSIM4rbpd0 = 50.0;
if (!model->BSIM4rbpdlGiven)
model->BSIM4rbpdl = 0.0;
if (!model->BSIM4rbpdwGiven)
model->BSIM4rbpdw = 0.0;
if (!model->BSIM4rbpdnfGiven)
model->BSIM4rbpdnf = 0.0;
if (!model->BSIM4rbpbx0Given)
model->BSIM4rbpbx0 = 100.0;
if (!model->BSIM4rbpbxlGiven)
model->BSIM4rbpbxl = 0.0;
if (!model->BSIM4rbpbxwGiven)
model->BSIM4rbpbxw = 0.0;
if (!model->BSIM4rbpbxnfGiven)
model->BSIM4rbpbxnf = 0.0;
if (!model->BSIM4rbpby0Given)
model->BSIM4rbpby0 = 100.0;
if (!model->BSIM4rbpbylGiven)
model->BSIM4rbpbyl = 0.0;
if (!model->BSIM4rbpbywGiven)
model->BSIM4rbpbyw = 0.0;
if (!model->BSIM4rbpbynfGiven)
model->BSIM4rbpbynf = 0.0;
if (!model->BSIM4rbsbx0Given)
model->BSIM4rbsbx0 = 100.0;
if (!model->BSIM4rbsby0Given)
model->BSIM4rbsby0 = 100.0;
if (!model->BSIM4rbdbx0Given)
model->BSIM4rbdbx0 = 100.0;
if (!model->BSIM4rbdby0Given)
model->BSIM4rbdby0 = 100.0;
if (!model->BSIM4rbsdbxlGiven)
model->BSIM4rbsdbxl = 0.0;
if (!model->BSIM4rbsdbxwGiven)
model->BSIM4rbsdbxw = 0.0;
if (!model->BSIM4rbsdbxnfGiven)
model->BSIM4rbsdbxnf = 0.0;
if (!model->BSIM4rbsdbylGiven)
model->BSIM4rbsdbyl = 0.0;
if (!model->BSIM4rbsdbywGiven)
model->BSIM4rbsdbyw = 0.0;
if (!model->BSIM4rbsdbynfGiven)
model->BSIM4rbsdbynf = 0.0;
if (!model->BSIM4cgslGiven)
model->BSIM4cgsl = 0.0;
if (!model->BSIM4cgdlGiven)
@ -534,7 +636,7 @@ JOB *job;
if (!model->BSIM4llpe0Given)
model->BSIM4llpe0 = 0.0;
if (!model->BSIM4llpebGiven)
model->BSIM4llpeb = model->BSIM4llpe0;
model->BSIM4llpeb = 0.0;
if (!model->BSIM4ldvtp0Given)
model->BSIM4ldvtp0 = 0.0;
if (!model->BSIM4ldvtp1Given)
@ -569,6 +671,14 @@ JOB *job;
model->BSIM4luc = 0.0;
if (!model->BSIM4luc1Given)
model->BSIM4luc1 = 0.0;
if (!model->BSIM4ludGiven)
model->BSIM4lud = 0.0;
if (!model->BSIM4lud1Given)
model->BSIM4lud1 = 0.0;
if (!model->BSIM4lupGiven)
model->BSIM4lup = 0.0;
if (!model->BSIM4llpGiven)
model->BSIM4llp = 0.0;
if (!model->BSIM4lu0Given)
model->BSIM4lu0 = 0.0;
if (!model->BSIM4luteGiven)
@ -685,6 +795,19 @@ JOB *job;
model->BSIM4leu = 0.0;
if (!model->BSIM4lvfbGiven)
model->BSIM4lvfb = 0.0;
if (!model->BSIM4llambdaGiven)
model->BSIM4llambda = 0.0;
if (!model->BSIM4lvtlGiven)
model->BSIM4lvtl = 0.0;
if (!model->BSIM4lxnGiven)
model->BSIM4lxn = 0.0;
if (!model->BSIM4lvfbsdoffGiven)
model->BSIM4lvfbsdoff = 0.0;
if (!model->BSIM4ltvfbsdoffGiven)
model->BSIM4ltvfbsdoff = 0.0;
if (!model->BSIM4ltvoffGiven)
model->BSIM4ltvoff = 0.0;
if (!model->BSIM4lcgslGiven)
model->BSIM4lcgsl = 0.0;
@ -767,7 +890,7 @@ JOB *job;
if (!model->BSIM4wlpe0Given)
model->BSIM4wlpe0 = 0.0;
if (!model->BSIM4wlpebGiven)
model->BSIM4wlpeb = model->BSIM4wlpe0;
model->BSIM4wlpeb = 0.0;
if (!model->BSIM4wdvtp0Given)
model->BSIM4wdvtp0 = 0.0;
if (!model->BSIM4wdvtp1Given)
@ -802,6 +925,14 @@ JOB *job;
model->BSIM4wuc = 0.0;
if (!model->BSIM4wuc1Given)
model->BSIM4wuc1 = 0.0;
if (!model->BSIM4wudGiven)
model->BSIM4wud = 0.0;
if (!model->BSIM4wud1Given)
model->BSIM4wud1 = 0.0;
if (!model->BSIM4wupGiven)
model->BSIM4wup = 0.0;
if (!model->BSIM4wlpGiven)
model->BSIM4wlp = 0.0;
if (!model->BSIM4wu0Given)
model->BSIM4wu0 = 0.0;
if (!model->BSIM4wuteGiven)
@ -918,6 +1049,18 @@ JOB *job;
model->BSIM4weu = 0.0;
if (!model->BSIM4wvfbGiven)
model->BSIM4wvfb = 0.0;
if (!model->BSIM4wlambdaGiven)
model->BSIM4wlambda = 0.0;
if (!model->BSIM4wvtlGiven)
model->BSIM4wvtl = 0.0;
if (!model->BSIM4wxnGiven)
model->BSIM4wxn = 0.0;
if (!model->BSIM4wvfbsdoffGiven)
model->BSIM4wvfbsdoff = 0.0;
if (!model->BSIM4wtvfbsdoffGiven)
model->BSIM4wtvfbsdoff = 0.0;
if (!model->BSIM4wtvoffGiven)
model->BSIM4wtvoff = 0.0;
if (!model->BSIM4wcgslGiven)
model->BSIM4wcgsl = 0.0;
@ -1001,7 +1144,7 @@ JOB *job;
if (!model->BSIM4plpe0Given)
model->BSIM4plpe0 = 0.0;
if (!model->BSIM4plpebGiven)
model->BSIM4plpeb = model->BSIM4plpe0;
model->BSIM4plpeb = 0.0;
if (!model->BSIM4pdvtp0Given)
model->BSIM4pdvtp0 = 0.0;
if (!model->BSIM4pdvtp1Given)
@ -1036,6 +1179,14 @@ JOB *job;
model->BSIM4puc = 0.0;
if (!model->BSIM4puc1Given)
model->BSIM4puc1 = 0.0;
if (!model->BSIM4pudGiven)
model->BSIM4pud = 0.0;
if (!model->BSIM4pud1Given)
model->BSIM4pud1 = 0.0;
if (!model->BSIM4pupGiven)
model->BSIM4pup = 0.0;
if (!model->BSIM4plpGiven)
model->BSIM4plp = 0.0;
if (!model->BSIM4pu0Given)
model->BSIM4pu0 = 0.0;
if (!model->BSIM4puteGiven)
@ -1152,6 +1303,18 @@ JOB *job;
model->BSIM4peu = 0.0;
if (!model->BSIM4pvfbGiven)
model->BSIM4pvfb = 0.0;
if (!model->BSIM4plambdaGiven)
model->BSIM4plambda = 0.0;
if (!model->BSIM4pvtlGiven)
model->BSIM4pvtl = 0.0;
if (!model->BSIM4pxnGiven)
model->BSIM4pxn = 0.0;
if (!model->BSIM4pvfbsdoffGiven)
model->BSIM4pvfbsdoff = 0.0;
if (!model->BSIM4ptvfbsdoffGiven)
model->BSIM4ptvfbsdoff = 0.0;
if (!model->BSIM4ptvoffGiven)
model->BSIM4ptvoff = 0.0;
if (!model->BSIM4pcgslGiven)
model->BSIM4pcgsl = 0.0;
@ -1178,6 +1341,31 @@ JOB *job;
if (!model->BSIM4pvoffcvGiven)
model->BSIM4pvoffcv = 0.0;
if (!model->BSIM4gamma1Given)
model->BSIM4gamma1 = 0.0;
if (!model->BSIM4lgamma1Given)
model->BSIM4lgamma1 = 0.0;
if (!model->BSIM4wgamma1Given)
model->BSIM4wgamma1 = 0.0;
if (!model->BSIM4pgamma1Given)
model->BSIM4pgamma1 = 0.0;
if (!model->BSIM4gamma2Given)
model->BSIM4gamma2 = 0.0;
if (!model->BSIM4lgamma2Given)
model->BSIM4lgamma2 = 0.0;
if (!model->BSIM4wgamma2Given)
model->BSIM4wgamma2 = 0.0;
if (!model->BSIM4pgamma2Given)
model->BSIM4pgamma2 = 0.0;
if (!model->BSIM4vbxGiven)
model->BSIM4vbx = 0.0;
if (!model->BSIM4lvbxGiven)
model->BSIM4lvbx = 0.0;
if (!model->BSIM4wvbxGiven)
model->BSIM4wvbx = 0.0;
if (!model->BSIM4pvbxGiven)
model->BSIM4pvbx = 0.0;
/* unit degree celcius */
if (!model->BSIM4tnomGiven)
model->BSIM4tnom = ckt->CKTnomTemp;
@ -1303,6 +1491,55 @@ JOB *job;
if (!model->BSIM4DjctTempExponentGiven)
model->BSIM4DjctTempExponent = model->BSIM4SjctTempExponent;
if (!model->BSIM4jtssGiven)
model->BSIM4jtss = 0.0;
if (!model->BSIM4jtsdGiven)
model->BSIM4jtsd = model->BSIM4jtss;
if (!model->BSIM4jtsswsGiven)
model->BSIM4jtssws = 0.0;
if (!model->BSIM4jtsswdGiven)
model->BSIM4jtsswd = model->BSIM4jtssws;
if (!model->BSIM4jtsswgsGiven)
model->BSIM4jtsswgs = 0.0;
if (!model->BSIM4jtsswgdGiven)
model->BSIM4jtsswgd = model->BSIM4jtsswgs;
if (!model->BSIM4njtsGiven)
model->BSIM4njts = 20.0;
if (!model->BSIM4njtsswGiven)
model->BSIM4njtssw = 20.0;
if (!model->BSIM4njtsswgGiven)
model->BSIM4njtsswg = 20.0;
if (!model->BSIM4xtssGiven)
model->BSIM4xtss = 0.02;
if (!model->BSIM4xtsdGiven)
model->BSIM4xtsd = model->BSIM4xtss;
if (!model->BSIM4xtsswsGiven)
model->BSIM4xtssws = 0.02;
if (!model->BSIM4xtsswdGiven)
model->BSIM4xtsswd = model->BSIM4xtssws;
if (!model->BSIM4xtsswgsGiven)
model->BSIM4xtsswgs = 0.02;
if (!model->BSIM4xtsswgdGiven)
model->BSIM4xtsswgd = model->BSIM4xtsswgs;
if (!model->BSIM4tnjtsGiven)
model->BSIM4tnjts = 0.0;
if (!model->BSIM4tnjtsswGiven)
model->BSIM4tnjtssw = 0.0;
if (!model->BSIM4tnjtsswgGiven)
model->BSIM4tnjtsswg = 0.0;
if (!model->BSIM4vtssGiven)
model->BSIM4vtss = 10.0;
if (!model->BSIM4vtsdGiven)
model->BSIM4vtsd = model->BSIM4vtss;
if (!model->BSIM4vtsswsGiven)
model->BSIM4vtssws = 10.0;
if (!model->BSIM4vtsswdGiven)
model->BSIM4vtsswd = model->BSIM4vtssws;
if (!model->BSIM4vtsswgsGiven)
model->BSIM4vtsswgs = 10.0;
if (!model->BSIM4vtsswgdGiven)
model->BSIM4vtsswgd = model->BSIM4vtsswgs;
if (!model->BSIM4oxideTrapDensityAGiven)
{ if (model->BSIM4type == NMOS)
model->BSIM4oxideTrapDensityA = 6.25e41;
@ -1325,6 +1562,89 @@ JOB *job;
model->BSIM4af = 1.0;
if (!model->BSIM4kfGiven)
model->BSIM4kf = 0.0;
/* stress effect */
if (!model->BSIM4sarefGiven)
model->BSIM4saref = 1e-6; /* m */
if (!model->BSIM4sbrefGiven)
model->BSIM4sbref = 1e-6; /* m */
if (!model->BSIM4wlodGiven)
model->BSIM4wlod = 0; /* m */
if (!model->BSIM4ku0Given)
model->BSIM4ku0 = 0; /* 1/m */
if (!model->BSIM4kvsatGiven)
model->BSIM4kvsat = 0;
if (!model->BSIM4kvth0Given) /* m */
model->BSIM4kvth0 = 0;
if (!model->BSIM4tku0Given)
model->BSIM4tku0 = 0;
if (!model->BSIM4llodku0Given)
model->BSIM4llodku0 = 0;
if (!model->BSIM4wlodku0Given)
model->BSIM4wlodku0 = 0;
if (!model->BSIM4llodvthGiven)
model->BSIM4llodvth = 0;
if (!model->BSIM4wlodvthGiven)
model->BSIM4wlodvth = 0;
if (!model->BSIM4lku0Given)
model->BSIM4lku0 = 0;
if (!model->BSIM4wku0Given)
model->BSIM4wku0 = 0;
if (!model->BSIM4pku0Given)
model->BSIM4pku0 = 0;
if (!model->BSIM4lkvth0Given)
model->BSIM4lkvth0 = 0;
if (!model->BSIM4wkvth0Given)
model->BSIM4wkvth0 = 0;
if (!model->BSIM4pkvth0Given)
model->BSIM4pkvth0 = 0;
if (!model->BSIM4stk2Given)
model->BSIM4stk2 = 0;
if (!model->BSIM4lodk2Given)
model->BSIM4lodk2 = 1.0;
if (!model->BSIM4steta0Given)
model->BSIM4steta0 = 0;
if (!model->BSIM4lodeta0Given)
model->BSIM4lodeta0 = 1.0;
/* Well Proximity Effect */
if (!model->BSIM4webGiven)
model->BSIM4web = 0.0;
if (!model->BSIM4wecGiven)
model->BSIM4wec = 0.0;
if (!model->BSIM4kvth0weGiven)
model->BSIM4kvth0we = 0.0;
if (!model->BSIM4k2weGiven)
model->BSIM4k2we = 0.0;
if (!model->BSIM4ku0weGiven)
model->BSIM4ku0we = 0.0;
if (!model->BSIM4screfGiven)
model->BSIM4scref = 1.0E-6; /* m */
if (!model->BSIM4wpemodGiven)
model->BSIM4wpemod = 0;
else if ((model->BSIM4wpemod != 0) && (model->BSIM4wpemod != 1))
{ model->BSIM4wpemod = 0;
printf("Warning: wpemod has been set to its default value: 0.\n");
}
if (!model->BSIM4lkvth0weGiven)
model->BSIM4lkvth0we = 0;
if (!model->BSIM4lk2weGiven)
model->BSIM4lk2we = 0;
if (!model->BSIM4lku0weGiven)
model->BSIM4lku0we = 0;
if (!model->BSIM4wkvth0weGiven)
model->BSIM4wkvth0we = 0;
if (!model->BSIM4wk2weGiven)
model->BSIM4wk2we = 0;
if (!model->BSIM4wku0weGiven)
model->BSIM4wku0we = 0;
if (!model->BSIM4pkvth0weGiven)
model->BSIM4pkvth0we = 0;
if (!model->BSIM4pk2weGiven)
model->BSIM4pk2we = 0;
if (!model->BSIM4pku0weGiven)
model->BSIM4pku0we = 0;
DMCGeff = model->BSIM4dmcg - model->BSIM4dmcgt;
DMCIeff = model->BSIM4dmci;
DMDGeff = model->BSIM4dmdg - model->BSIM4dmcgt;
@ -1335,10 +1655,10 @@ JOB *job;
*/
for (here = model->BSIM4instances; here != NULL ;
here=here->BSIM4nextInstance)
here=here->BSIM4nextInstance)
{
if (here->BSIM4owner == ARCHme) {
/* allocate a chunk of the state vector */
if (here->BSIM4owner == ARCHme) {
/* allocate a chunk of the state vector */
here->BSIM4states = *states;
*states += BSIM4numStates;
}
@ -1347,6 +1667,8 @@ JOB *job;
here->BSIM4l = 5.0e-6;
if (!here->BSIM4wGiven)
here->BSIM4w = 5.0e-6;
if (!here->BSIM4mGiven)
here->BSIM4m = 1.0;
if (!here->BSIM4nfGiven)
here->BSIM4nf = 1.0;
if (!here->BSIM4minGiven)
@ -1380,6 +1702,12 @@ JOB *job;
here->BSIM4rbps = model->BSIM4rbps;
if (!here->BSIM4rbpdGiven)
here->BSIM4rbpd = model->BSIM4rbpd;
if (!here->BSIM4delvtoGiven)
here->BSIM4delvto = 0.0;
if (!here->BSIM4xgwGiven)
here->BSIM4xgw = model->BSIM4xgw;
if (!here->BSIM4ngconGiven)
here->BSIM4ngcon = model->BSIM4ngcon;
/* Process instance model selectors, some
@ -1387,7 +1715,7 @@ JOB *job;
*/
if (!here->BSIM4rbodyModGiven)
here->BSIM4rbodyMod = model->BSIM4rbodyMod;
else if ((here->BSIM4rbodyMod != 0) && (here->BSIM4rbodyMod != 1))
else if ((here->BSIM4rbodyMod != 0) && (here->BSIM4rbodyMod != 1) && (here->BSIM4rbodyMod != 2))
{ here->BSIM4rbodyMod = model->BSIM4rbodyMod;
printf("Warning: rbodyMod has been set to its global value %d.\n",
model->BSIM4rbodyMod);
@ -1405,7 +1733,7 @@ JOB *job;
if (!here->BSIM4geoModGiven)
here->BSIM4geoMod = model->BSIM4geoMod;
if (!here->BSIM4rgeoModGiven)
here->BSIM4rgeoMod = 0.0;
here->BSIM4rgeoMod = 0;
if (!here->BSIM4trnqsModGiven)
here->BSIM4trnqsMod = model->BSIM4trnqsMod;
else if ((here->BSIM4trnqsMod != 0) && (here->BSIM4trnqsMod != 1))
@ -1422,6 +1750,23 @@ JOB *job;
model->BSIM4acnqsMod);
}
/* stress effect */
if (!here->BSIM4saGiven)
here->BSIM4sa = 0.0;
if (!here->BSIM4sbGiven)
here->BSIM4sb = 0.0;
if (!here->BSIM4sdGiven)
here->BSIM4sd = 2 * model->BSIM4dmcg;
/* Well Proximity Effect */
if (!here->BSIM4scaGiven)
here->BSIM4sca = 0.0;
if (!here->BSIM4scbGiven)
here->BSIM4scb = 0.0;
if (!here->BSIM4sccGiven)
here->BSIM4scc = 0.0;
if (!here->BSIM4scGiven)
here->BSIM4sc = 0.0; /* m */
/* process drain series resistance */
createNode = 0;
if ( (model->BSIM4rdsMod != 0)
@ -1437,7 +1782,7 @@ JOB *job;
} else if (!here->BSIM4drainSquaresGiven
&& (here->BSIM4rgeoMod != 0))
{
BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod,
BSIM4RdseffGeo(here->BSIM4nf*here->BSIM4m, here->BSIM4geoMod,
here->BSIM4rgeoMod, here->BSIM4min,
here->BSIM4w, model->BSIM4sheetResistance,
DMCGeff, DMCIeff, DMDGeff, 0, &Rtot);
@ -1449,6 +1794,16 @@ JOB *job;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"drain");
if(error) return(error);
here->BSIM4dNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) {
CKTnode *tmpNode;
IFuid tmpName;
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
if (tmpNode->nsGiven) {
tmp->nodeset=tmpNode->nodeset;
tmp->nsGiven=tmpNode->nsGiven;
}
}
}
}
else
{ here->BSIM4dNodePrime = here->BSIM4dNode;
@ -1469,7 +1824,7 @@ JOB *job;
} else if (!here->BSIM4sourceSquaresGiven
&& (here->BSIM4rgeoMod != 0))
{
BSIM4RdseffGeo(here->BSIM4nf, here->BSIM4geoMod,
BSIM4RdseffGeo(here->BSIM4nf*here->BSIM4m, here->BSIM4geoMod,
here->BSIM4rgeoMod, here->BSIM4min,
here->BSIM4w, model->BSIM4sheetResistance,
DMCGeff, DMCIeff, DMDGeff, 1, &Rtot);
@ -1481,6 +1836,16 @@ JOB *job;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"source");
if(error) return(error);
here->BSIM4sNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) {
CKTnode *tmpNode;
IFuid tmpName;
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
if (tmpNode->nsGiven) {
tmp->nodeset=tmpNode->nodeset;
tmp->nsGiven=tmpNode->nsGiven;
}
}
}
}
else
here->BSIM4sNodePrime = here->BSIM4sNode;
@ -1489,15 +1854,15 @@ JOB *job;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"gate");
if(error) return(error);
here->BSIM4gNodePrime = tmp->number;
if (here->BSIM4rgateMod == 1)
{ if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg should be positive for rgateMod = 1.\n");
}
else if (here->BSIM4rgateMod == 2)
{ if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg <= 0.0 for rgateMod = 2!!!\n");
else if (model->BSIM4xrcrg1 <= 0.0)
printf("Warning: xrcrg1 <= 0.0 for rgateMod = 2!!!\n");
if (ckt->CKTcopyNodesets) {
CKTnode *tmpNode;
IFuid tmpName;
if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) {
if (tmpNode->nsGiven) {
tmp->nodeset=tmpNode->nodeset;
tmp->nsGiven=tmpNode->nsGiven;
}
}
}
}
else
@ -1507,17 +1872,13 @@ JOB *job;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"midgate");
if(error) return(error);
here->BSIM4gNodeMid = tmp->number;
if (model->BSIM4rshg <= 0.0)
printf("Warning: rshg should be positive for rgateMod = 3.\n");
else if (model->BSIM4xrcrg1 <= 0.0)
printf("Warning: xrcrg1 should be positive for rgateMod = 3.\n");
}
else
here->BSIM4gNodeMid = here->BSIM4gNodeExt;
/* internal body nodes for body resistance model */
if (here->BSIM4rbodyMod)
if ((here->BSIM4rbodyMod ==1) || (here->BSIM4rbodyMod ==2))
{ if (here->BSIM4dbNode == 0)
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"dbody");
if(error) return(error);
@ -1527,6 +1888,16 @@ JOB *job;
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"body");
if(error) return(error);
here->BSIM4bNodePrime = tmp->number;
if (ckt->CKTcopyNodesets) {
CKTnode *tmpNode;
IFuid tmpName;
if (CKTinst2Node(ckt,here,4,&tmpNode,&tmpName)==OK) {
if (tmpNode->nsGiven) {
tmp->nodeset=tmpNode->nodeset;
tmp->nsGiven=tmpNode->nsGiven;
}
}
}
}
if (here->BSIM4sbNode == 0)
{ error = CKTmkVolt(ckt,&tmp,here->BSIM4name,"sbody");
@ -1609,7 +1980,7 @@ if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
TSTALLOC(BSIM4BPgmPtr, BSIM4bNodePrime, BSIM4gNodeMid)
}
if (here->BSIM4rbodyMod)
if ((here->BSIM4rbodyMod ==1) || (here->BSIM4rbodyMod ==2))
{ TSTALLOC(BSIM4DPdbPtr, BSIM4dNodePrime, BSIM4dbNode)
TSTALLOC(BSIM4SPsbPtr, BSIM4sNodePrime, BSIM4sbNode)
@ -1651,7 +2022,7 @@ BSIM4unsetup(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
#ifndef HAS_BATCHSIM
BSIM4model *model;
BSIM4instance *here;
@ -1675,5 +2046,6 @@ BSIM4unsetup(inModel,ckt)
}
}
}
#endif
return OK;
}

View File

@ -1,23 +1,26 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4temp.c of BSIM4.2.1.
* Copyright 2005 Regents of the University of California. All rights reserved.
* File: b4temp.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 04/06/2001.
* Modified by Xuemei Xi, 10/05/2001.
* Modified by Xuemei Xi, 11/15/2002.
* Modified by Xuemei Xi, 05/09/2003.
* Modified by Xuemei Xi, 03/04/2004.
* Modified by Xuemei Xi, Mohan Dunga, 07/29/2005.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "smpdefs.h"
#include "cktdefs.h"
#include "bsim4def.h"
#include "const.h"
#include "sperror.h"
#include "suffix.h"
#define Kb 1.3806226e-23
#define KboQ 8.617087e-5
@ -28,6 +31,22 @@
#define MIN_EXP 1.713908431e-15
#define EXP_THRESHOLD 34.0
#define Charge_q 1.60219e-19
#define DELTA 1.0E-9
#define DEXP(A,B) { \
if (A > EXP_THRESHOLD) { \
B = MAX_EXP*(1.0+(A)-EXP_THRESHOLD); \
} else if (A < -EXP_THRESHOLD) { \
B = MIN_EXP; \
} else { \
B = exp(A); \
} \
}
int
BSIM4PAeffGeo(double, int, int, double, double, double, double, double *, double *, double *, double *);
int
BSIM4RdseffGeo(double, int, int, int, double, double, double, double, double, int, double *);
int
BSIM4DioIjthVjmEval(Nvtm, Ijth, Isb, XExpBV, Vjm)
@ -52,14 +71,20 @@ CKTcircuit *ckt;
{
BSIM4model *model = (BSIM4model*) inModel;
BSIM4instance *here;
struct bsim4SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam;
double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni;
double T0, T1, T2, T3, T4, T5, T8, T9, Lnew, Wnew;
double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom;
struct bsim4SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam=NULL;
double tmp, tmp1, tmp2, Eg, Eg0, ni;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Lnew=0.0, Wnew;
double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom;
double dumPs, dumPd, dumAs, dumAd, PowWeffWr;
double DMCGeff, DMCIeff, DMDGeff;
double Nvtms, Nvtmd, SourceSatCurrent, DrainSatCurrent;
int Size_Not_Found;
double T10;
double Inv_saref, Inv_sbref, Inv_sa, Inv_sb, rho, Ldrn, dvth0_lod;
double W_tmp, Inv_ODeff, OD_offset, dk2_lod, deta0_lod;
double lnl, lnw, lnnf, rbpbx, rbpby, rbsbx, rbsby, rbdbx, rbdby,bodymode;
double kvsat, wlod, sceff, Wdrn;
int Size_Not_Found, i;
/* loop through all the BSIM4 device models */
for (; model != NULL; model = model->BSIM4nextModel)
@ -117,7 +142,8 @@ int Size_Not_Found;
}
if (!model->BSIM4cgboGiven)
model->BSIM4cgbo = 2.0 * model->BSIM4dwc * model->BSIM4coxe;
/* va: was memory leakage - free old node, (or better use again?) */
FREE(model->pSizeDependParamKnot);
model->pSizeDependParamKnot = NULL;
pLastKnot = NULL;
@ -128,7 +154,7 @@ int Size_Not_Found;
model->BSIM4factor1 = sqrt(EPSSI / (model->BSIM4epsrox * EPS0)
* model->BSIM4toxe);
Vtm0 = KboQ * Tnom;
Vtm0 = model->BSIM4vtm0 = 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));
@ -175,7 +201,6 @@ int Size_Not_Found;
model->BSIM4SjctSidewallTempSatCurDensity = 0.0;
if (model->BSIM4SjctGateSidewallTempSatCurDensity < 0.0)
model->BSIM4SjctGateSidewallTempSatCurDensity = 0.0;
if (model->BSIM4DjctTempSatCurDensity < 0.0)
model->BSIM4DjctTempSatCurDensity = 0.0;
if (model->BSIM4DjctSidewallTempSatCurDensity < 0.0)
@ -337,9 +362,13 @@ int Size_Not_Found;
}
}
/* stress effect */
Ldrn = here->BSIM4l;
Wdrn = here->BSIM4w / here->BSIM4nf;
if (Size_Not_Found)
{ pParam = (struct bsim4SizeDependParam *)malloc(
sizeof(struct bsim4SizeDependParam));
sizeof(struct bsim4SizeDependParam));
if (pLastKnot == NULL)
model->pSizeDependParamKnot = pParam;
else
@ -352,7 +381,7 @@ int Size_Not_Found;
pParam->NFinger = here->BSIM4nf;
Lnew = here->BSIM4l + model->BSIM4xl ;
Wnew = here->BSIM4w / here->BSIM4nf + model->BSIM4xw;
T0 = pow(Lnew, model->BSIM4Lln);
T1 = pow(Wnew, model->BSIM4Lwn);
tmp1 = model->BSIM4Ll / T0 + model->BSIM4Lw / T1
@ -361,7 +390,6 @@ int Size_Not_Found;
tmp2 = model->BSIM4Llc / T0 + model->BSIM4Lwc / T1
+ model->BSIM4Lwlc / (T0 * T1);
pParam->BSIM4dlc = model->BSIM4dlc + tmp2;
pParam->BSIM4dlcig = model->BSIM4dlcig + tmp2;
T2 = pow(Lnew, model->BSIM4Wln);
T3 = pow(Wnew, model->BSIM4Wwn);
@ -649,6 +677,22 @@ int Size_Not_Found;
+ model->BSIM4luc1 * Inv_L
+ model->BSIM4wuc1 * Inv_W
+ model->BSIM4puc1 * Inv_LW;
pParam->BSIM4ud = model->BSIM4ud
+ model->BSIM4lud * Inv_L
+ model->BSIM4wud * Inv_W
+ model->BSIM4pud * Inv_LW;
pParam->BSIM4ud1 = model->BSIM4ud1
+ model->BSIM4lud1 * Inv_L
+ model->BSIM4wud1 * Inv_W
+ model->BSIM4pud1 * Inv_LW;
pParam->BSIM4up = model->BSIM4up
+ model->BSIM4lup * Inv_L
+ model->BSIM4wup * Inv_W
+ model->BSIM4pup * Inv_LW;
pParam->BSIM4lp = model->BSIM4lp
+ model->BSIM4llp * Inv_L
+ model->BSIM4wlp * Inv_W
+ model->BSIM4plp * Inv_LW;
pParam->BSIM4eu = model->BSIM4eu
+ model->BSIM4leu * Inv_L
+ model->BSIM4weu * Inv_W
@ -665,6 +709,10 @@ int Size_Not_Found;
+ model->BSIM4lvoff * Inv_L
+ model->BSIM4wvoff * Inv_W
+ model->BSIM4pvoff * Inv_LW;
pParam->BSIM4tvoff = model->BSIM4tvoff
+ model->BSIM4ltvoff * Inv_L
+ model->BSIM4wtvoff * Inv_W
+ model->BSIM4ptvoff * Inv_LW;
pParam->BSIM4minv = model->BSIM4minv
+ model->BSIM4lminv * Inv_L
+ model->BSIM4wminv * Inv_W
@ -877,6 +925,26 @@ int Size_Not_Found;
+ model->BSIM4lxrcrg2 * Inv_L
+ model->BSIM4wxrcrg2 * Inv_W
+ model->BSIM4pxrcrg2 * Inv_LW;
pParam->BSIM4lambda = model->BSIM4lambda
+ model->BSIM4llambda * Inv_L
+ model->BSIM4wlambda * Inv_W
+ model->BSIM4plambda * Inv_LW;
pParam->BSIM4vtl = model->BSIM4vtl
+ model->BSIM4lvtl * Inv_L
+ model->BSIM4wvtl * Inv_W
+ model->BSIM4pvtl * Inv_LW;
pParam->BSIM4xn = model->BSIM4xn
+ model->BSIM4lxn * Inv_L
+ model->BSIM4wxn * Inv_W
+ model->BSIM4pxn * Inv_LW;
pParam->BSIM4vfbsdoff = model->BSIM4vfbsdoff
+ model->BSIM4lvfbsdoff * Inv_L
+ model->BSIM4wvfbsdoff * Inv_W
+ model->BSIM4pvfbsdoff * Inv_LW;
pParam->BSIM4tvfbsdoff = model->BSIM4tvfbsdoff
+ model->BSIM4ltvfbsdoff * Inv_L
+ model->BSIM4wtvfbsdoff * Inv_W
+ model->BSIM4ptvfbsdoff * Inv_LW;
pParam->BSIM4cgsl = model->BSIM4cgsl
+ model->BSIM4lcgsl * Inv_L
@ -926,63 +994,111 @@ int Size_Not_Found;
+ model->BSIM4lvoffcv * Inv_L
+ model->BSIM4wvoffcv * Inv_W
+ model->BSIM4pvoffcv * Inv_LW;
pParam->BSIM4kvth0we = model->BSIM4kvth0we
+ model->BSIM4lkvth0we * Inv_L
+ model->BSIM4wkvth0we * Inv_W
+ model->BSIM4pkvth0we * Inv_LW;
pParam->BSIM4k2we = model->BSIM4k2we
+ model->BSIM4lk2we * Inv_L
+ model->BSIM4wk2we * Inv_W
+ model->BSIM4pk2we * Inv_LW;
pParam->BSIM4ku0we = model->BSIM4ku0we
+ model->BSIM4lku0we * Inv_L
+ model->BSIM4wku0we * Inv_W
+ model->BSIM4pku0we * Inv_LW;
pParam->BSIM4abulkCVfactor = 1.0 + pow((pParam->BSIM4clc
/ pParam->BSIM4leffCV),
pParam->BSIM4cle);
T0 = (TRatio - 1.0);
pParam->BSIM4ua = pParam->BSIM4ua + pParam->BSIM4ua1 * T0;
pParam->BSIM4ub = pParam->BSIM4ub + pParam->BSIM4ub1 * T0;
pParam->BSIM4uc = pParam->BSIM4uc + pParam->BSIM4uc1 * T0;
if (pParam->BSIM4u0 > 1.0)
pParam->BSIM4u0 = pParam->BSIM4u0 / 1.0e4;
pParam->BSIM4u0temp = pParam->BSIM4u0
* pow(TRatio, pParam->BSIM4ute);
pParam->BSIM4vsattemp = pParam->BSIM4vsat - pParam->BSIM4at
* T0;
if (pParam->BSIM4eu < 0.0)
{ pParam->BSIM4eu = 0.0;
printf("Warning: eu has been negative; reset to 0.0.\n");
}
PowWeffWr = pow(pParam->BSIM4weffCJ * 1.0e6, pParam->BSIM4wr) * here->BSIM4nf;
/* External Rd(V) */
T1 = pParam->BSIM4rdw + pParam->BSIM4prt * T0;
T1 = T2 = T3 = T4 = 0.0;
if(model->BSIM4tempMod == 0) {
pParam->BSIM4ua = pParam->BSIM4ua + pParam->BSIM4ua1 * T0;
pParam->BSIM4ub = pParam->BSIM4ub + pParam->BSIM4ub1 * T0;
pParam->BSIM4uc = pParam->BSIM4uc + pParam->BSIM4uc1 * T0;
pParam->BSIM4ud = pParam->BSIM4ud + pParam->BSIM4ud1 * T0;
pParam->BSIM4vsattemp = pParam->BSIM4vsat - pParam->BSIM4at * T0;
T10 = pParam->BSIM4prt * T0;
if(model->BSIM4rdsMod) {
/* External Rd(V) */
T1 = pParam->BSIM4rdw + T10;
T2 = model->BSIM4rdwmin + T10;
/* External Rs(V) */
T3 = pParam->BSIM4rsw + T10;
T4 = model->BSIM4rswmin + T10;
}
/* Internal Rds(V) in IV */
pParam->BSIM4rds0 = (pParam->BSIM4rdsw + T10)
* here->BSIM4nf / PowWeffWr;
pParam->BSIM4rdswmin = (model->BSIM4rdswmin + T10)
* here->BSIM4nf / PowWeffWr;
} else { /* tempMod = 1, 2 */
pParam->BSIM4ua = pParam->BSIM4ua * (1.0 + pParam->BSIM4ua1 * delTemp) ;
pParam->BSIM4ub = pParam->BSIM4ub * (1.0 + pParam->BSIM4ub1 * delTemp);
pParam->BSIM4uc = pParam->BSIM4uc * (1.0 + pParam->BSIM4uc1 * delTemp);
pParam->BSIM4ud = pParam->BSIM4ud * (1.0 + pParam->BSIM4ud1 * delTemp);
pParam->BSIM4vsattemp = pParam->BSIM4vsat * (1.0 - pParam->BSIM4at * delTemp);
T10 = 1.0 + pParam->BSIM4prt * delTemp;
if(model->BSIM4rdsMod) {
/* External Rd(V) */
T1 = pParam->BSIM4rdw * T10;
T2 = model->BSIM4rdwmin * T10;
/* External Rs(V) */
T3 = pParam->BSIM4rsw * T10;
T4 = model->BSIM4rswmin * T10;
}
/* Internal Rds(V) in IV */
pParam->BSIM4rds0 = pParam->BSIM4rdsw * T10 * here->BSIM4nf / PowWeffWr;
pParam->BSIM4rdswmin = model->BSIM4rdswmin * T10 * here->BSIM4nf / PowWeffWr;
}
if (T1 < 0.0)
{ T1 = 0.0;
printf("Warning: Rdw at current temperature is negative; set to 0.\n");
}
T2 = model->BSIM4rdwmin + pParam->BSIM4prt * T0;
if (T2 < 0.0)
{ T2 = 0.0;
printf("Warning: Rdwmin at current temperature is negative; set to 0.\n");
}
pParam->BSIM4rd0 = T1 / PowWeffWr;
pParam->BSIM4rdwmin = T2 / PowWeffWr;
/* External Rs(V) */
T1 = pParam->BSIM4rsw + pParam->BSIM4prt * T0;
if (T1 < 0.0)
{ T1 = 0.0;
if (T3 < 0.0)
{ T3 = 0.0;
printf("Warning: Rsw at current temperature is negative; set to 0.\n");
}
T2 = model->BSIM4rswmin + pParam->BSIM4prt * T0;
if (T2 < 0.0)
{ T2 = 0.0;
if (T4 < 0.0)
{ T4 = 0.0;
printf("Warning: Rswmin at current temperature is negative; set to 0.\n");
}
pParam->BSIM4rs0 = T1 / PowWeffWr;
pParam->BSIM4rswmin = T2 / PowWeffWr;
pParam->BSIM4rs0 = T3 / PowWeffWr;
pParam->BSIM4rswmin = T4 / PowWeffWr;
/* Internal Rds(V) in IV */
pParam->BSIM4rds0 = (pParam->BSIM4rdsw + pParam->BSIM4prt * T0)
* here->BSIM4nf / PowWeffWr;
pParam->BSIM4rdswmin = (model->BSIM4rdswmin + pParam->BSIM4prt * T0)
* here->BSIM4nf / PowWeffWr;
if (pParam->BSIM4u0 > 1.0)
pParam->BSIM4u0 = pParam->BSIM4u0 / 1.0e4;
/* mobility channel length dependence */
T5 = 1.0 - pParam->BSIM4up * exp( - pParam->BSIM4leff / pParam->BSIM4lp);
pParam->BSIM4u0temp = pParam->BSIM4u0 * T5
* pow(TRatio, pParam->BSIM4ute);
if (pParam->BSIM4eu < 0.0)
{ pParam->BSIM4eu = 0.0;
printf("Warning: eu has been negative; reset to 0.0.\n");
}
pParam->BSIM4vfbsdoff = pParam->BSIM4vfbsdoff * (1.0 + pParam->BSIM4tvfbsdoff * delTemp);
pParam->BSIM4voff = pParam->BSIM4voff * (1.0 + pParam->BSIM4tvoff * delTemp);
/* Source End Velocity Limit */
if((model->BSIM4vtlGiven) && (model->BSIM4vtl > 0.0) )
{
if(model->BSIM4lc < 0.0) pParam->BSIM4lc = 0.0;
else pParam->BSIM4lc = model->BSIM4lc ;
T0 = pParam->BSIM4leff / (pParam->BSIM4xn * pParam->BSIM4leff + pParam->BSIM4lc);
pParam->BSIM4tfactor = (1.0 - T0) / (1.0 + T0 );
}
pParam->BSIM4cgdo = (model->BSIM4cgdo + pParam->BSIM4cf)
* pParam->BSIM4weffCV;
@ -1032,7 +1148,7 @@ int Size_Not_Found;
pParam->BSIM4Aechvb = (model->BSIM4type == NMOS) ? 4.97232e-7 : 3.42537e-7;
pParam->BSIM4Bechvb = (model->BSIM4type == NMOS) ? 7.45669e11 : 1.16645e12;
pParam->BSIM4AechvbEdge = pParam->BSIM4Aechvb * pParam->BSIM4weff
* pParam->BSIM4dlcig * pParam->BSIM4ToxRatioEdge;
* model->BSIM4dlcig * pParam->BSIM4ToxRatioEdge;
pParam->BSIM4BechvbEdge = -pParam->BSIM4Bechvb
* model->BSIM4toxe * pParam->BSIM4poxedge;
pParam->BSIM4Aechvb *= pParam->BSIM4weff * pParam->BSIM4leff
@ -1097,20 +1213,6 @@ int Size_Not_Found;
* pParam->BSIM4k2 * sqrt(pParam->BSIM4phi
- pParam->BSIM4vbm);
}
if (pParam->BSIM4k2 < 0.0)
{ T0 = 0.5 * pParam->BSIM4k1 / pParam->BSIM4k2;
pParam->BSIM4vbsc = 0.9 * (pParam->BSIM4phi - T0 * T0);
if (pParam->BSIM4vbsc > -3.0)
pParam->BSIM4vbsc = -3.0;
else if (pParam->BSIM4vbsc < -30.0)
pParam->BSIM4vbsc = -30.0;
}
else
{ pParam->BSIM4vbsc = -30.0;
}
if (pParam->BSIM4vbsc > pParam->BSIM4vbm)
pParam->BSIM4vbsc = pParam->BSIM4vbm;
if (!model->BSIM4vfbGiven)
{ if (model->BSIM4vth0Given)
@ -1122,28 +1224,14 @@ int Size_Not_Found;
{ pParam->BSIM4vfb = -1.0;
}
}
if (!model->BSIM4vth0Given)
if (!model->BSIM4vth0Given)
{ pParam->BSIM4vth0 = model->BSIM4type * (pParam->BSIM4vfb
+ pParam->BSIM4phi + pParam->BSIM4k1
* pParam->BSIM4sqrtPhi);
}
pParam->BSIM4k1ox = pParam->BSIM4k1 * model->BSIM4toxe
/ model->BSIM4toxm;
pParam->BSIM4k2ox = pParam->BSIM4k2 * model->BSIM4toxe
/ model->BSIM4toxm;
T3 = model->BSIM4type * pParam->BSIM4vth0
- pParam->BSIM4vfb - pParam->BSIM4phi;
T4 = T3 + T3;
T5 = 2.5 * T3;
pParam->BSIM4vtfbphi1 = (model->BSIM4type == NMOS) ? T4 : T5;
if (pParam->BSIM4vtfbphi1 < 0.0)
pParam->BSIM4vtfbphi1 = 0.0;
pParam->BSIM4vtfbphi2 = 4.0 * T3;
if (pParam->BSIM4vtfbphi2 < 0.0)
pParam->BSIM4vtfbphi2 = 0.0;
tmp = sqrt(EPSSI / (model->BSIM4epsrox * EPS0)
* model->BSIM4toxe * pParam->BSIM4Xdep0);
@ -1196,7 +1284,7 @@ int Size_Not_Found;
T3 = T2 * T2;
T4 = T3 + 2.0 * T1 * MIN_EXP;
T9 = T1 / T4;
}
}
else
T9 = 1.0 / (MAX_EXP - 2.0);
T9 = pParam->BSIM4dvt0 * T9 * tmp1;
@ -1205,20 +1293,214 @@ int Size_Not_Found;
/ (pParam->BSIM4weff + pParam->BSIM4w0);
T0 = sqrt(1.0 + pParam->BSIM4lpe0 / pParam->BSIM4leff);
T5 = pParam->BSIM4k1ox * (T0 - 1.0) * pParam->BSIM4sqrtPhi
+ (pParam->BSIM4kt1 + pParam->BSIM4kt1l / pParam->BSIM4leff)
* (TRatio - 1.0);
if((model->BSIM4tempMod == 1) || (model->BSIM4tempMod == 0))
T3 = (pParam->BSIM4kt1 + pParam->BSIM4kt1l / pParam->BSIM4leff)
* (TRatio - 1.0);
if(model->BSIM4tempMod == 2)
T3 = - pParam->BSIM4kt1 * (TRatio - 1.0);
T5 = pParam->BSIM4k1ox * (T0 - 1.0) * pParam->BSIM4sqrtPhi
+ T3;
pParam->BSIM4vfbzbfactor = - T8 - T9 + pParam->BSIM4k3 * T4 + T5
- pParam->BSIM4phi - pParam->BSIM4k1 * pParam->BSIM4sqrtPhi;
/* stress effect */
wlod = model->BSIM4wlod;
if (model->BSIM4wlod < 0.0)
{ fprintf(stderr, "Warning: WLOD = %g is less than 0. 0.0 is used\n",model->BSIM4wlod);
wlod = 0.0;
}
T0 = pow(Lnew, model->BSIM4llodku0);
W_tmp = Wnew + wlod;
T1 = pow(W_tmp, model->BSIM4wlodku0);
tmp1 = model->BSIM4lku0 / T0 + model->BSIM4wku0 / T1
+ model->BSIM4pku0 / (T0 * T1);
pParam->BSIM4ku0 = 1.0 + tmp1;
T0 = pow(Lnew, model->BSIM4llodvth);
T1 = pow(W_tmp, model->BSIM4wlodvth);
tmp1 = model->BSIM4lkvth0 / T0 + model->BSIM4wkvth0 / T1
+ model->BSIM4pkvth0 / (T0 * T1);
pParam->BSIM4kvth0 = 1.0 + tmp1;
pParam->BSIM4kvth0 = sqrt(pParam->BSIM4kvth0*pParam->BSIM4kvth0 + DELTA);
T0 = (TRatio - 1.0);
pParam->BSIM4ku0temp = pParam->BSIM4ku0 * (1.0 + model->BSIM4tku0 *T0) + DELTA;
Inv_saref = 1.0/(model->BSIM4saref + 0.5*Ldrn);
Inv_sbref = 1.0/(model->BSIM4sbref + 0.5*Ldrn);
pParam->BSIM4inv_od_ref = Inv_saref + Inv_sbref;
pParam->BSIM4rho_ref = model->BSIM4ku0 / pParam->BSIM4ku0temp * pParam->BSIM4inv_od_ref;
tmp3 = model->BSIM4type * pParam->BSIM4vth0
- T8 - T9 + pParam->BSIM4k3 * T4 + T5;
pParam->BSIM4vfbzb = tmp3 - pParam->BSIM4phi - pParam->BSIM4k1
* pParam->BSIM4sqrtPhi; /* End of vfbzb */
} /* End of SizeNotFound */
/* stress effect */
if( (here->BSIM4sa > 0.0) && (here->BSIM4sb > 0.0) &&
((here->BSIM4nf == 1.0) || ((here->BSIM4nf > 1.0) && (here->BSIM4sd > 0.0))) )
{ Inv_sa = 0;
Inv_sb = 0;
kvsat = model->BSIM4kvsat;
if (model->BSIM4kvsat < -1.0 )
{ fprintf(stderr, "Warning: KVSAT = %g is too small; -1.0 is used.\n",model->BSIM4kvsat);
kvsat = -1.0;
}
if (model->BSIM4kvsat > 1.0)
{ fprintf(stderr, "Warning: KVSAT = %g is too big; 1.0 is used.\n",model->BSIM4kvsat);
kvsat = 1.0;
}
for(i = 0; i < here->BSIM4nf; i++){
T0 = 1.0 / here->BSIM4nf / (here->BSIM4sa + 0.5*Ldrn + i * (here->BSIM4sd +Ldrn));
T1 = 1.0 / here->BSIM4nf / (here->BSIM4sb + 0.5*Ldrn + i * (here->BSIM4sd +Ldrn));
Inv_sa += T0;
Inv_sb += T1;
}
Inv_ODeff = Inv_sa + Inv_sb;
rho = model->BSIM4ku0 / pParam->BSIM4ku0temp * Inv_ODeff;
T0 = (1.0 + rho)/(1.0 + pParam->BSIM4rho_ref);
here->BSIM4u0temp = pParam->BSIM4u0temp * T0;
T1 = (1.0 + kvsat * rho)/(1.0 + kvsat * pParam->BSIM4rho_ref);
here->BSIM4vsattemp = pParam->BSIM4vsattemp * T1;
OD_offset = Inv_ODeff - pParam->BSIM4inv_od_ref;
dvth0_lod = model->BSIM4kvth0 / pParam->BSIM4kvth0 * OD_offset;
dk2_lod = model->BSIM4stk2 / pow(pParam->BSIM4kvth0, model->BSIM4lodk2) *
OD_offset;
deta0_lod = model->BSIM4steta0 / pow(pParam->BSIM4kvth0, model->BSIM4lodeta0) *
OD_offset;
here->BSIM4vth0 = pParam->BSIM4vth0 + dvth0_lod;
here->BSIM4eta0 = pParam->BSIM4eta0 + deta0_lod;
here->BSIM4k2 = pParam->BSIM4k2 + dk2_lod;
} else {
here->BSIM4u0temp = pParam->BSIM4u0temp;
here->BSIM4vth0 = pParam->BSIM4vth0;
here->BSIM4vsattemp = pParam->BSIM4vsattemp;
here->BSIM4eta0 = pParam->BSIM4eta0;
here->BSIM4k2 = pParam->BSIM4k2;
}
/* Well Proximity Effect */
if (model->BSIM4wpemod)
{ if( (!here->BSIM4scaGiven) && (!here->BSIM4scbGiven) && (!here->BSIM4sccGiven) )
{ if((here->BSIM4scGiven) && (here->BSIM4sc > 0.0) )
{ T1 = here->BSIM4sc + Wdrn;
T2 = 1.0 / model->BSIM4scref;
here->BSIM4sca = model->BSIM4scref * model->BSIM4scref
/ (here->BSIM4sc * T1);
here->BSIM4scb = ( (0.1 * here->BSIM4sc + 0.01 * model->BSIM4scref)
* exp(-10.0 * here->BSIM4sc * T2)
- (0.1 * T1 + 0.01 * model->BSIM4scref)
* exp(-10.0 * T1 * T2) ) / Wdrn;
here->BSIM4scc = ( (0.05 * here->BSIM4sc + 0.0025 * model->BSIM4scref)
* exp(-20.0 * here->BSIM4sc * T2)
- (0.05 * T1 + 0.0025 * model->BSIM4scref)
* exp(-20.0 * T1 * T2) ) / Wdrn;
} else {
fprintf(stderr, "Warning: No WPE as none of SCA, SCB, SCC, SC is given and/or SC not positive.\n");
}
}
sceff = here->BSIM4sca + model->BSIM4web * here->BSIM4scb
+ model->BSIM4wec * here->BSIM4scc;
here->BSIM4vth0 += pParam->BSIM4kvth0we * sceff;
here->BSIM4k2 += pParam->BSIM4k2we * sceff;
T3 = 1.0 + pParam->BSIM4ku0we * sceff;
if (T3 <= 0.0)
{ T3 = 0.0;
fprintf(stderr, "Warning: ku0we = %g is negatively too high. Negative mobility! \n", pParam->BSIM4ku0we);
}
here->BSIM4u0temp *= T3;
}
/* adding delvto */
here->BSIM4vth0 += here->BSIM4delvto;
here->BSIM4vfb = pParam->BSIM4vfb + model->BSIM4type * here->BSIM4delvto;
/* Instance variables calculation */
T3 = model->BSIM4type * here->BSIM4vth0
- here->BSIM4vfb - pParam->BSIM4phi;
T4 = T3 + T3;
T5 = 2.5 * T3;
here->BSIM4vtfbphi1 = (model->BSIM4type == NMOS) ? T4 : T5;
if (here->BSIM4vtfbphi1 < 0.0)
here->BSIM4vtfbphi1 = 0.0;
here->BSIM4vtfbphi2 = 4.0 * T3;
if (here->BSIM4vtfbphi2 < 0.0)
here->BSIM4vtfbphi2 = 0.0;
if (here->BSIM4k2 < 0.0)
{ T0 = 0.5 * pParam->BSIM4k1 / here->BSIM4k2;
here->BSIM4vbsc = 0.9 * (pParam->BSIM4phi - T0 * T0);
if (here->BSIM4vbsc > -3.0)
here->BSIM4vbsc = -3.0;
else if (here->BSIM4vbsc < -30.0)
here->BSIM4vbsc = -30.0;
}
else
here->BSIM4vbsc = -30.0;
if (here->BSIM4vbsc > pParam->BSIM4vbm)
here->BSIM4vbsc = pParam->BSIM4vbm;
here->BSIM4k2ox = here->BSIM4k2 * model->BSIM4toxe
/ model->BSIM4toxm;
here->BSIM4vfbzb = pParam->BSIM4vfbzbfactor
+ model->BSIM4type * here->BSIM4vth0 ;
here->BSIM4cgso = pParam->BSIM4cgso;
here->BSIM4cgdo = pParam->BSIM4cgdo;
lnl = log(pParam->BSIM4leff * 1.0e6);
lnw = log(pParam->BSIM4weff * 1.0e6);
lnnf = log(here->BSIM4nf);
if (here->BSIM4rbodyMod)
bodymode = 5;
if( ( !model->BSIM4rbps0Given) ||
( !model->BSIM4rbpd0Given) )
bodymode = 1;
else
if( (!model->BSIM4rbsbx0Given && !model->BSIM4rbsby0Given) ||
(!model->BSIM4rbdbx0Given && !model->BSIM4rbdby0Given) )
bodymode = 3;
if(here->BSIM4rbodyMod == 2)
{
if (bodymode == 5)
{
rbsbx = exp( log(model->BSIM4rbsbx0) + model->BSIM4rbsdbxl * lnl +
model->BSIM4rbsdbxw * lnw + model->BSIM4rbsdbxnf * lnnf );
rbsby = exp( log(model->BSIM4rbsby0) + model->BSIM4rbsdbyl * lnl +
model->BSIM4rbsdbyw * lnw + model->BSIM4rbsdbynf * lnnf );
here->BSIM4rbsb = rbsbx * rbsby / (rbsbx + rbsby);
rbdbx = exp( log(model->BSIM4rbdbx0) + model->BSIM4rbsdbxl * lnl +
model->BSIM4rbsdbxw * lnw + model->BSIM4rbsdbxnf * lnnf );
rbdby = exp( log(model->BSIM4rbdby0) + model->BSIM4rbsdbyl * lnl +
model->BSIM4rbsdbyw * lnw + model->BSIM4rbsdbynf * lnnf );
here->BSIM4rbdb = rbdbx * rbdby / (rbdbx + rbdby);
}
if ((bodymode == 3)|| (bodymode == 5))
{
here->BSIM4rbps = exp( log(model->BSIM4rbps0) + model->BSIM4rbpsl * lnl +
model->BSIM4rbpsw * lnw + model->BSIM4rbpsnf * lnnf );
here->BSIM4rbpd = exp( log(model->BSIM4rbpd0) + model->BSIM4rbpdl * lnl +
model->BSIM4rbpdw * lnw + model->BSIM4rbpdnf * lnnf );
}
rbpbx = exp( log(model->BSIM4rbpbx0) + model->BSIM4rbpbxl * lnl +
model->BSIM4rbpbxw * lnw + model->BSIM4rbpbxnf * lnnf );
rbpby = exp( log(model->BSIM4rbpby0) + model->BSIM4rbpbyl * lnl +
model->BSIM4rbpbyw * lnw + model->BSIM4rbpbynf * lnnf );
here->BSIM4rbpb = rbpbx*rbpby/(rbpbx + rbpby);
}
if ((here->BSIM4rbodyMod == 1 ) || ((here->BSIM4rbodyMod == 2 ) && (bodymode == 5)) )
{ if (here->BSIM4rbdb < 1.0e-3)
here->BSIM4grbdb = 1.0e3; /* in mho */
else
@ -1239,6 +1521,34 @@ int Size_Not_Found;
here->BSIM4grbpd = 1.0e3;
else
here->BSIM4grbpd = model->BSIM4gbmin + 1.0 / here->BSIM4rbpd;
}
if((here->BSIM4rbodyMod == 2) && (bodymode == 3))
{
here->BSIM4grbdb = here->BSIM4grbsb = model->BSIM4gbmin;
if (here->BSIM4rbpb < 1.0e-3)
here->BSIM4grbpb = 1.0e3;
else
here->BSIM4grbpb = model->BSIM4gbmin + 1.0 / here->BSIM4rbpb;
if (here->BSIM4rbps < 1.0e-3)
here->BSIM4grbps = 1.0e3;
else
here->BSIM4grbps = model->BSIM4gbmin + 1.0 / here->BSIM4rbps;
if (here->BSIM4rbpd < 1.0e-3)
here->BSIM4grbpd = 1.0e3;
else
here->BSIM4grbpd = model->BSIM4gbmin + 1.0 / here->BSIM4rbpd;
}
if((here->BSIM4rbodyMod == 2) && (bodymode == 1))
{
here->BSIM4grbdb = here->BSIM4grbsb = model->BSIM4gbmin;
here->BSIM4grbps = here->BSIM4grbpd = 1.0e3;
if (here->BSIM4rbpb < 1.0e-3)
here->BSIM4grbpb = 1.0e3;
else
here->BSIM4grbpb = model->BSIM4gbmin + 1.0 / here->BSIM4rbpb;
}
@ -1246,9 +1556,9 @@ int Size_Not_Found;
* Process geomertry dependent parasitics
*/
here->BSIM4grgeltd = model->BSIM4rshg * (model->BSIM4xgw
+ pParam->BSIM4weffCJ / 3.0 / model->BSIM4ngcon) /
(model->BSIM4ngcon * here->BSIM4nf *
here->BSIM4grgeltd = model->BSIM4rshg * (here->BSIM4xgw
+ pParam->BSIM4weffCJ / 3.0 / here->BSIM4ngcon) /
(here->BSIM4ngcon * here->BSIM4nf *
(Lnew - model->BSIM4xgl));
if (here->BSIM4grgeltd > 0.0)
here->BSIM4grgeltd = 1.0 / here->BSIM4grgeltd;
@ -1473,7 +1783,7 @@ int Size_Not_Found;
fprintf(stderr, "Warning: ijthdrev too small and set to 10 times IdbSat.\n");
}
here->BSIM4vjdmRev = -model->BSIM4bvd
- Nvtms * log((T2 - 1.0) / model->BSIM4xjbvd);
- Nvtmd * log((T2 - 1.0) / model->BSIM4xjbvd); /* bugfix */
T1 = model->BSIM4xjbvd * exp(-(model->BSIM4bvd
+ here->BSIM4vjdmRev) / Nvtmd);
here->BSIM4IVjdmRev = DrainSatCurrent * (1.0 + T1);
@ -1484,11 +1794,39 @@ int Size_Not_Found;
}
}
/* GEDL current reverse bias */
T0 = (TRatio - 1.0);
model->BSIM4njtstemp = model->BSIM4njts * (1.0 + model->BSIM4tnjts * T0);
model->BSIM4njtsswtemp = model->BSIM4njtssw * (1.0 + model->BSIM4tnjtssw * T0);
model->BSIM4njtsswgtemp = model->BSIM4njtsswg * (1.0 + model->BSIM4tnjtsswg * T0);
T7 = Eg0 / model->BSIM4vtm * T0;
T9 = model->BSIM4xtss * T7;
DEXP(T9, T1);
T9 = model->BSIM4xtsd * T7;
DEXP(T9, T2);
T9 = model->BSIM4xtssws * T7;
DEXP(T9, T3);
T9 = model->BSIM4xtsswd * T7;
DEXP(T9, T4);
T9 = model->BSIM4xtsswgs * T7;
DEXP(T9, T5);
T9 = model->BSIM4xtsswgd * T7;
DEXP(T9, T6);
T10 = pParam->BSIM4weffCJ * here->BSIM4nf;
here->BSIM4SjctTempRevSatCur = T1 * here->BSIM4Aseff * model->BSIM4jtss;
here->BSIM4DjctTempRevSatCur = T2 * here->BSIM4Adeff * model->BSIM4jtsd;
here->BSIM4SswTempRevSatCur = T3 * here->BSIM4Pseff * model->BSIM4jtssws;
here->BSIM4DswTempRevSatCur = T4 * here->BSIM4Pdeff * model->BSIM4jtsswd;
here->BSIM4SswgTempRevSatCur = T5 * T10 * model->BSIM4jtsswgs;
here->BSIM4DswgTempRevSatCur = T6 * T10 * model->BSIM4jtsswgd;
if (BSIM4checkModel(model, here, ckt))
{ IFuid namarray[2];
namarray[0] = model->BSIM4modName;
namarray[1] = here->BSIM4name;
(*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during BSIM4.2.1 parameter checking for %s in model %s", namarray);
(*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during BSIM4.5.0 parameter checking for %s in model %s", namarray);
return(E_BADPARM);
}
} /* End instance */

View File

@ -1,19 +1,18 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**** BSIM4.5.0 Released by Xuemei (Jane) Xi 07/29/2005 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4trunc.c of BSIM4.2.1.
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4trunc.c of BSIM4.5.0.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int

View File

@ -1,7 +1,11 @@
/**********
Copyright 2001 Regents of the University of California. All rights reserved.
Copyright 2005 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu.
Modified by Xuemei Xi October 2001
Modified by Xuemei Xi, 11/15/2002.
Modified by Xuemei Xi, 05/09/2003.
Modified by Xuemei Xi, 03/04/2004.
Modified by Xuemei Xi, Mohan Dunga, 09/24/2004.
Modified by Xuemei Xi, 07/29/2005.
File: bsim4def.h
**********/
@ -12,8 +16,8 @@ File: bsim4def.h
#include "gendefs.h"
#include "cktdefs.h"
#include "complex.h"
#include "noisedef.h"
#include "noisedef.h"
typedef struct sBSIM4instance
{
struct sBSIM4model *BSIM4modPtr;
@ -79,15 +83,42 @@ typedef struct sBSIM4instance
double BSIM4sourcePerimeter;
double BSIM4sourceConductance;
double BSIM4drainConductance;
/* stress effect instance param */
double BSIM4sa;
double BSIM4sb;
double BSIM4sd;
double BSIM4sca;
double BSIM4scb;
double BSIM4scc;
double BSIM4sc;
double BSIM4rbdb;
double BSIM4rbsb;
double BSIM4rbpb;
double BSIM4rbps;
double BSIM4rbpd;
double BSIM4delvto;
double BSIM4xgw;
double BSIM4ngcon;
/* added here to account stress effect instance dependence */
double BSIM4u0temp;
double BSIM4vsattemp;
double BSIM4vth0;
double BSIM4vfb;
double BSIM4vfbzb;
double BSIM4vtfbphi1;
double BSIM4vtfbphi2;
double BSIM4k2;
double BSIM4vbsc;
double BSIM4k2ox;
double BSIM4eta0;
double BSIM4icVDS;
double BSIM4icVGS;
double BSIM4icVBS;
double BSIM4m;
double BSIM4nf;
int BSIM4off;
int BSIM4mode;
@ -99,6 +130,7 @@ typedef struct sBSIM4instance
int BSIM4rgeoMod;
int BSIM4min;
/* OP point */
double BSIM4Vgsteff;
double BSIM4vgs_eff;
@ -207,6 +239,7 @@ typedef struct sBSIM4instance
double BSIM4qbulk;
double BSIM4qdrn;
double BSIM4qsrc;
double BSIM4qdef;
double BSIM4qchqs;
double BSIM4taunet;
@ -215,11 +248,18 @@ typedef struct sBSIM4instance
double BSIM4gtd;
double BSIM4gts;
double BSIM4gtb;
double BSIM4SjctTempRevSatCur;
double BSIM4DjctTempRevSatCur;
double BSIM4SswTempRevSatCur;
double BSIM4DswTempRevSatCur;
double BSIM4SswgTempRevSatCur;
double BSIM4DswgTempRevSatCur;
struct bsim4SizeDependParam *pParam;
unsigned BSIM4lGiven :1;
unsigned BSIM4wGiven :1;
unsigned BSIM4mGiven :1;
unsigned BSIM4nfGiven :1;
unsigned BSIM4minGiven :1;
unsigned BSIM4drainAreaGiven :1;
@ -228,11 +268,21 @@ typedef struct sBSIM4instance
unsigned BSIM4sourceSquaresGiven :1;
unsigned BSIM4drainPerimeterGiven :1;
unsigned BSIM4sourcePerimeterGiven :1;
unsigned BSIM4saGiven :1;
unsigned BSIM4sbGiven :1;
unsigned BSIM4sdGiven :1;
unsigned BSIM4scaGiven :1;
unsigned BSIM4scbGiven :1;
unsigned BSIM4sccGiven :1;
unsigned BSIM4scGiven :1;
unsigned BSIM4rbdbGiven :1;
unsigned BSIM4rbsbGiven :1;
unsigned BSIM4rbpbGiven :1;
unsigned BSIM4rbpdGiven :1;
unsigned BSIM4rbpsGiven :1;
unsigned BSIM4delvtoGiven :1;
unsigned BSIM4xgwGiven :1;
unsigned BSIM4ngconGiven :1;
unsigned BSIM4icVDSGiven :1;
unsigned BSIM4icVGSGiven :1;
unsigned BSIM4icVBSGiven :1;
@ -243,6 +293,7 @@ typedef struct sBSIM4instance
unsigned BSIM4geoModGiven :1;
unsigned BSIM4rgeoModGiven :1;
double *BSIM4DPdPtr;
double *BSIM4DPdpPtr;
double *BSIM4DPgpPtr;
@ -419,7 +470,6 @@ struct bsim4SizeDependParam
double BSIM4vbx;
double BSIM4vbi;
double BSIM4vbm;
double BSIM4vbsc;
double BSIM4xt;
double BSIM4phi;
double BSIM4litl;
@ -450,10 +500,15 @@ struct bsim4SizeDependParam
double BSIM4ub1;
double BSIM4uc;
double BSIM4uc1;
double BSIM4ud;
double BSIM4ud1;
double BSIM4up;
double BSIM4lp;
double BSIM4u0;
double BSIM4eu;
double BSIM4ute;
double BSIM4voff;
double BSIM4tvoff;
double BSIM4minv;
double BSIM4vfb;
double BSIM4delta;
@ -511,11 +566,24 @@ struct bsim4SizeDependParam
double BSIM4poxedge;
double BSIM4xrcrg1;
double BSIM4xrcrg2;
double BSIM4fpkt;
double BSIM4plcr;
double BSIM4plcrl;
double BSIM4plcrd;
double BSIM4lambda; /* overshoot */
double BSIM4vtl; /* thermal velocity limit */
double BSIM4xn; /* back scattering parameter */
double BSIM4lc; /* back scattering parameter */
double BSIM4tfactor; /* ballistic transportation factor */
double BSIM4vfbsdoff; /* S/D flatband offset voltage */
double BSIM4tvfbsdoff;
/* added for stress effect */
double BSIM4ku0;
double BSIM4kvth0;
double BSIM4ku0temp;
double BSIM4rho_ref;
double BSIM4inv_od_ref;
/* added for well proximity effect */
double BSIM4kvth0we;
double BSIM4k2we;
double BSIM4ku0we;
/* CV model */
double BSIM4cgsl;
@ -570,9 +638,6 @@ struct bsim4SizeDependParam
double BSIM4cof3;
double BSIM4cof4;
double BSIM4cdep0;
double BSIM4vfbzb;
double BSIM4vtfbphi1;
double BSIM4vtfbphi2;
double BSIM4ToxRatio;
double BSIM4Aechvb;
double BSIM4Bechvb;
@ -582,6 +647,8 @@ struct bsim4SizeDependParam
double BSIM4ldeb;
double BSIM4k1ox;
double BSIM4k2ox;
double BSIM4vfbzbfactor;
struct bsim4SizeDependParam *pNext;
};
@ -609,6 +676,7 @@ typedef struct sBSIM4model
int BSIM4geoMod;
int BSIM4igcMod;
int BSIM4igbMod;
int BSIM4tempMod;
int BSIM4binUnit;
int BSIM4paramChk;
char *BSIM4version;
@ -668,9 +736,14 @@ typedef struct sBSIM4model
double BSIM4ub1;
double BSIM4uc;
double BSIM4uc1;
double BSIM4ud;
double BSIM4ud1;
double BSIM4up;
double BSIM4lp;
double BSIM4u0;
double BSIM4ute;
double BSIM4voff;
double BSIM4tvoff;
double BSIM4minv;
double BSIM4voffl;
double BSIM4delta;
@ -736,8 +809,41 @@ typedef struct sBSIM4model
double BSIM4xjbvs;
double BSIM4bvd;
double BSIM4bvs;
double BSIM4jtss;
double BSIM4jtsd;
double BSIM4jtssws;
double BSIM4jtsswd;
double BSIM4jtsswgs;
double BSIM4jtsswgd;
double BSIM4njts;
double BSIM4njtssw;
double BSIM4njtsswg;
double BSIM4xtss;
double BSIM4xtsd;
double BSIM4xtssws;
double BSIM4xtsswd;
double BSIM4xtsswgs;
double BSIM4xtsswgd;
double BSIM4tnjts;
double BSIM4tnjtssw;
double BSIM4tnjtsswg;
double BSIM4vtss;
double BSIM4vtsd;
double BSIM4vtssws;
double BSIM4vtsswd;
double BSIM4vtsswgs;
double BSIM4vtsswgd;
double BSIM4xrcrg1;
double BSIM4xrcrg2;
double BSIM4lambda;
double BSIM4vtl;
double BSIM4lc;
double BSIM4xn;
double BSIM4vfbsdoff; /* S/D flatband offset voltage */
double BSIM4lintnoi; /* lint offset for noise calculation */
double BSIM4tvfbsdoff;
double BSIM4vfb;
double BSIM4gbmin;
@ -746,8 +852,42 @@ typedef struct sBSIM4model
double BSIM4rbpb;
double BSIM4rbps;
double BSIM4rbpd;
double BSIM4rbps0;
double BSIM4rbpsl;
double BSIM4rbpsw;
double BSIM4rbpsnf;
double BSIM4rbpd0;
double BSIM4rbpdl;
double BSIM4rbpdw;
double BSIM4rbpdnf;
double BSIM4rbpbx0;
double BSIM4rbpbxl;
double BSIM4rbpbxw;
double BSIM4rbpbxnf;
double BSIM4rbpby0;
double BSIM4rbpbyl;
double BSIM4rbpbyw;
double BSIM4rbpbynf;
double BSIM4rbsbx0;
double BSIM4rbsby0;
double BSIM4rbdbx0;
double BSIM4rbdby0;
double BSIM4rbsdbxl;
double BSIM4rbsdbxw;
double BSIM4rbsdbxnf;
double BSIM4rbsdbyl;
double BSIM4rbsdbyw;
double BSIM4rbsdbynf;
double BSIM4tnoia;
double BSIM4tnoib;
double BSIM4rnoia;
double BSIM4rnoib;
double BSIM4ntnoi;
/* CV model and Parasitics */
@ -835,10 +975,15 @@ typedef struct sBSIM4model
double BSIM4lub1;
double BSIM4luc;
double BSIM4luc1;
double BSIM4lud;
double BSIM4lud1;
double BSIM4lup;
double BSIM4llp;
double BSIM4lu0;
double BSIM4leu;
double BSIM4lute;
double BSIM4lvoff;
double BSIM4ltvoff;
double BSIM4lminv;
double BSIM4ldelta;
double BSIM4lrdsw;
@ -893,6 +1038,11 @@ typedef struct sBSIM4model
double BSIM4lpoxedge;
double BSIM4lxrcrg1;
double BSIM4lxrcrg2;
double BSIM4llambda;
double BSIM4lvtl;
double BSIM4lxn;
double BSIM4lvfbsdoff;
double BSIM4ltvfbsdoff;
/* CV model */
double BSIM4lcgsl;
@ -959,10 +1109,15 @@ typedef struct sBSIM4model
double BSIM4wub1;
double BSIM4wuc;
double BSIM4wuc1;
double BSIM4wud;
double BSIM4wud1;
double BSIM4wup;
double BSIM4wlp;
double BSIM4wu0;
double BSIM4weu;
double BSIM4wute;
double BSIM4wvoff;
double BSIM4wtvoff;
double BSIM4wminv;
double BSIM4wdelta;
double BSIM4wrdsw;
@ -1017,6 +1172,11 @@ typedef struct sBSIM4model
double BSIM4wpoxedge;
double BSIM4wxrcrg1;
double BSIM4wxrcrg2;
double BSIM4wlambda;
double BSIM4wvtl;
double BSIM4wxn;
double BSIM4wvfbsdoff;
double BSIM4wtvfbsdoff;
/* CV model */
double BSIM4wcgsl;
@ -1083,10 +1243,15 @@ typedef struct sBSIM4model
double BSIM4pub1;
double BSIM4puc;
double BSIM4puc1;
double BSIM4pud;
double BSIM4pud1;
double BSIM4pup;
double BSIM4plp;
double BSIM4pu0;
double BSIM4peu;
double BSIM4pute;
double BSIM4pvoff;
double BSIM4ptvoff;
double BSIM4pminv;
double BSIM4pdelta;
double BSIM4prdsw;
@ -1141,6 +1306,11 @@ typedef struct sBSIM4model
double BSIM4ppoxedge;
double BSIM4pxrcrg1;
double BSIM4pxrcrg2;
double BSIM4plambda;
double BSIM4pvtl;
double BSIM4pxn;
double BSIM4pvfbsdoff;
double BSIM4ptvfbsdoff;
/* CV model */
double BSIM4pcgsl;
@ -1193,6 +1363,9 @@ typedef struct sBSIM4model
double BSIM4DjctEmissionCoeff;
double BSIM4SjctTempExponent;
double BSIM4DjctTempExponent;
double BSIM4njtstemp;
double BSIM4njtsswtemp;
double BSIM4njtsswgtemp;
double BSIM4Lint;
double BSIM4Ll;
@ -1218,10 +1391,50 @@ typedef struct sBSIM4model
double BSIM4Wmin;
double BSIM4Wmax;
/* added for stress effect */
double BSIM4saref;
double BSIM4sbref;
double BSIM4wlod;
double BSIM4ku0;
double BSIM4kvsat;
double BSIM4kvth0;
double BSIM4tku0;
double BSIM4llodku0;
double BSIM4wlodku0;
double BSIM4llodvth;
double BSIM4wlodvth;
double BSIM4lku0;
double BSIM4wku0;
double BSIM4pku0;
double BSIM4lkvth0;
double BSIM4wkvth0;
double BSIM4pkvth0;
double BSIM4stk2;
double BSIM4lodk2;
double BSIM4steta0;
double BSIM4lodeta0;
double BSIM4web;
double BSIM4wec;
double BSIM4kvth0we;
double BSIM4k2we;
double BSIM4ku0we;
double BSIM4scref;
double BSIM4wpemod;
double BSIM4lkvth0we;
double BSIM4lk2we;
double BSIM4lku0we;
double BSIM4wkvth0we;
double BSIM4wk2we;
double BSIM4wku0we;
double BSIM4pkvth0we;
double BSIM4pk2we;
double BSIM4pku0we;
/* Pre-calculated constants
* move to size-dependent param */
double BSIM4vtm;
double BSIM4vtm0;
double BSIM4coxe;
double BSIM4coxp;
double BSIM4cof1;
@ -1276,6 +1489,7 @@ typedef struct sBSIM4model
unsigned BSIM4tnoiModGiven :1;
unsigned BSIM4igcModGiven :1;
unsigned BSIM4igbModGiven :1;
unsigned BSIM4tempModGiven :1;
unsigned BSIM4typeGiven :1;
unsigned BSIM4toxrefGiven :1;
unsigned BSIM4toxeGiven :1;
@ -1335,9 +1549,14 @@ typedef struct sBSIM4model
unsigned BSIM4ub1Given :1;
unsigned BSIM4ucGiven :1;
unsigned BSIM4uc1Given :1;
unsigned BSIM4udGiven :1;
unsigned BSIM4ud1Given :1;
unsigned BSIM4upGiven :1;
unsigned BSIM4lpGiven :1;
unsigned BSIM4u0Given :1;
unsigned BSIM4uteGiven :1;
unsigned BSIM4voffGiven :1;
unsigned BSIM4tvoffGiven :1;
unsigned BSIM4vofflGiven :1;
unsigned BSIM4minvGiven :1;
unsigned BSIM4rdswGiven :1;
@ -1402,6 +1621,32 @@ typedef struct sBSIM4model
unsigned BSIM4xjbvsGiven :1;
unsigned BSIM4bvdGiven :1;
unsigned BSIM4bvsGiven :1;
unsigned BSIM4jtssGiven :1;
unsigned BSIM4jtsdGiven :1;
unsigned BSIM4jtsswsGiven :1;
unsigned BSIM4jtsswdGiven :1;
unsigned BSIM4jtsswgsGiven :1;
unsigned BSIM4jtsswgdGiven :1;
unsigned BSIM4njtsGiven :1;
unsigned BSIM4njtsswGiven :1;
unsigned BSIM4njtsswgGiven :1;
unsigned BSIM4xtssGiven :1;
unsigned BSIM4xtsdGiven :1;
unsigned BSIM4xtsswsGiven :1;
unsigned BSIM4xtsswdGiven :1;
unsigned BSIM4xtsswgsGiven :1;
unsigned BSIM4xtsswgdGiven :1;
unsigned BSIM4tnjtsGiven :1;
unsigned BSIM4tnjtsswGiven :1;
unsigned BSIM4tnjtsswgGiven :1;
unsigned BSIM4vtssGiven :1;
unsigned BSIM4vtsdGiven :1;
unsigned BSIM4vtsswsGiven :1;
unsigned BSIM4vtsswdGiven :1;
unsigned BSIM4vtsswgsGiven :1;
unsigned BSIM4vtsswgdGiven :1;
unsigned BSIM4vfbGiven :1;
unsigned BSIM4gbminGiven :1;
unsigned BSIM4rbdbGiven :1;
@ -1409,12 +1654,54 @@ typedef struct sBSIM4model
unsigned BSIM4rbpsGiven :1;
unsigned BSIM4rbpdGiven :1;
unsigned BSIM4rbpbGiven :1;
unsigned BSIM4rbps0Given :1;
unsigned BSIM4rbpslGiven :1;
unsigned BSIM4rbpswGiven :1;
unsigned BSIM4rbpsnfGiven :1;
unsigned BSIM4rbpd0Given :1;
unsigned BSIM4rbpdlGiven :1;
unsigned BSIM4rbpdwGiven :1;
unsigned BSIM4rbpdnfGiven :1;
unsigned BSIM4rbpbx0Given :1;
unsigned BSIM4rbpbxlGiven :1;
unsigned BSIM4rbpbxwGiven :1;
unsigned BSIM4rbpbxnfGiven :1;
unsigned BSIM4rbpby0Given :1;
unsigned BSIM4rbpbylGiven :1;
unsigned BSIM4rbpbywGiven :1;
unsigned BSIM4rbpbynfGiven :1;
unsigned BSIM4rbsbx0Given :1;
unsigned BSIM4rbsby0Given :1;
unsigned BSIM4rbdbx0Given :1;
unsigned BSIM4rbdby0Given :1;
unsigned BSIM4rbsdbxlGiven :1;
unsigned BSIM4rbsdbxwGiven :1;
unsigned BSIM4rbsdbxnfGiven :1;
unsigned BSIM4rbsdbylGiven :1;
unsigned BSIM4rbsdbywGiven :1;
unsigned BSIM4rbsdbynfGiven :1;
unsigned BSIM4xrcrg1Given :1;
unsigned BSIM4xrcrg2Given :1;
unsigned BSIM4tnoiaGiven :1;
unsigned BSIM4tnoibGiven :1;
unsigned BSIM4rnoiaGiven :1;
unsigned BSIM4rnoibGiven :1;
unsigned BSIM4ntnoiGiven :1;
unsigned BSIM4lambdaGiven :1;
unsigned BSIM4vtlGiven :1;
unsigned BSIM4lcGiven :1;
unsigned BSIM4xnGiven :1;
unsigned BSIM4vfbsdoffGiven :1;
unsigned BSIM4lintnoiGiven :1;
unsigned BSIM4tvfbsdoffGiven :1;
/* CV model and parasitics */
unsigned BSIM4cgslGiven :1;
unsigned BSIM4cgdlGiven :1;
@ -1501,10 +1788,15 @@ typedef struct sBSIM4model
unsigned BSIM4lub1Given :1;
unsigned BSIM4lucGiven :1;
unsigned BSIM4luc1Given :1;
unsigned BSIM4ludGiven :1;
unsigned BSIM4lud1Given :1;
unsigned BSIM4lupGiven :1;
unsigned BSIM4llpGiven :1;
unsigned BSIM4lu0Given :1;
unsigned BSIM4leuGiven :1;
unsigned BSIM4luteGiven :1;
unsigned BSIM4lvoffGiven :1;
unsigned BSIM4ltvoffGiven :1;
unsigned BSIM4lminvGiven :1;
unsigned BSIM4lrdswGiven :1;
unsigned BSIM4lrswGiven :1;
@ -1559,6 +1851,11 @@ typedef struct sBSIM4model
unsigned BSIM4lpoxedgeGiven :1;
unsigned BSIM4lxrcrg1Given :1;
unsigned BSIM4lxrcrg2Given :1;
unsigned BSIM4llambdaGiven :1;
unsigned BSIM4lvtlGiven :1;
unsigned BSIM4lxnGiven :1;
unsigned BSIM4lvfbsdoffGiven :1;
unsigned BSIM4ltvfbsdoffGiven :1;
/* CV model */
unsigned BSIM4lcgslGiven :1;
@ -1625,10 +1922,15 @@ typedef struct sBSIM4model
unsigned BSIM4wub1Given :1;
unsigned BSIM4wucGiven :1;
unsigned BSIM4wuc1Given :1;
unsigned BSIM4wudGiven :1;
unsigned BSIM4wud1Given :1;
unsigned BSIM4wupGiven :1;
unsigned BSIM4wlpGiven :1;
unsigned BSIM4wu0Given :1;
unsigned BSIM4weuGiven :1;
unsigned BSIM4wuteGiven :1;
unsigned BSIM4wvoffGiven :1;
unsigned BSIM4wtvoffGiven :1;
unsigned BSIM4wminvGiven :1;
unsigned BSIM4wrdswGiven :1;
unsigned BSIM4wrswGiven :1;
@ -1683,6 +1985,11 @@ typedef struct sBSIM4model
unsigned BSIM4wpoxedgeGiven :1;
unsigned BSIM4wxrcrg1Given :1;
unsigned BSIM4wxrcrg2Given :1;
unsigned BSIM4wlambdaGiven :1;
unsigned BSIM4wvtlGiven :1;
unsigned BSIM4wxnGiven :1;
unsigned BSIM4wvfbsdoffGiven :1;
unsigned BSIM4wtvfbsdoffGiven :1;
/* CV model */
unsigned BSIM4wcgslGiven :1;
@ -1749,10 +2056,15 @@ typedef struct sBSIM4model
unsigned BSIM4pub1Given :1;
unsigned BSIM4pucGiven :1;
unsigned BSIM4puc1Given :1;
unsigned BSIM4pudGiven :1;
unsigned BSIM4pud1Given :1;
unsigned BSIM4pupGiven :1;
unsigned BSIM4plpGiven :1;
unsigned BSIM4pu0Given :1;
unsigned BSIM4peuGiven :1;
unsigned BSIM4puteGiven :1;
unsigned BSIM4pvoffGiven :1;
unsigned BSIM4ptvoffGiven :1;
unsigned BSIM4pminvGiven :1;
unsigned BSIM4prdswGiven :1;
unsigned BSIM4prswGiven :1;
@ -1807,6 +2119,11 @@ typedef struct sBSIM4model
unsigned BSIM4ppoxedgeGiven :1;
unsigned BSIM4pxrcrg1Given :1;
unsigned BSIM4pxrcrg2Given :1;
unsigned BSIM4plambdaGiven :1;
unsigned BSIM4pvtlGiven :1;
unsigned BSIM4pxnGiven :1;
unsigned BSIM4pvfbsdoffGiven :1;
unsigned BSIM4ptvfbsdoffGiven :1;
/* CV model */
unsigned BSIM4pcgslGiven :1;
@ -1893,6 +2210,47 @@ typedef struct sBSIM4model
unsigned BSIM4WminGiven :1;
unsigned BSIM4WmaxGiven :1;
/* added for stress effect */
unsigned BSIM4sarefGiven :1;
unsigned BSIM4sbrefGiven :1;
unsigned BSIM4wlodGiven :1;
unsigned BSIM4ku0Given :1;
unsigned BSIM4kvsatGiven :1;
unsigned BSIM4kvth0Given :1;
unsigned BSIM4tku0Given :1;
unsigned BSIM4llodku0Given :1;
unsigned BSIM4wlodku0Given :1;
unsigned BSIM4llodvthGiven :1;
unsigned BSIM4wlodvthGiven :1;
unsigned BSIM4lku0Given :1;
unsigned BSIM4wku0Given :1;
unsigned BSIM4pku0Given :1;
unsigned BSIM4lkvth0Given :1;
unsigned BSIM4wkvth0Given :1;
unsigned BSIM4pkvth0Given :1;
unsigned BSIM4stk2Given :1;
unsigned BSIM4lodk2Given :1;
unsigned BSIM4steta0Given :1;
unsigned BSIM4lodeta0Given :1;
unsigned BSIM4webGiven :1;
unsigned BSIM4wecGiven :1;
unsigned BSIM4kvth0weGiven :1;
unsigned BSIM4k2weGiven :1;
unsigned BSIM4ku0weGiven :1;
unsigned BSIM4screfGiven :1;
unsigned BSIM4wpemodGiven :1;
unsigned BSIM4lkvth0weGiven :1;
unsigned BSIM4lk2weGiven :1;
unsigned BSIM4lku0weGiven :1;
unsigned BSIM4wkvth0weGiven :1;
unsigned BSIM4wk2weGiven :1;
unsigned BSIM4wku0weGiven :1;
unsigned BSIM4pkvth0weGiven :1;
unsigned BSIM4pk2weGiven :1;
unsigned BSIM4pku0weGiven :1;
} BSIM4model;
@ -1929,9 +2287,20 @@ typedef struct sBSIM4model
#define BSIM4_RBPB 25
#define BSIM4_RBPS 26
#define BSIM4_RBPD 27
#define BSIM4_SA 28
#define BSIM4_SB 29
#define BSIM4_SD 30
#define BSIM4_DELVTO 31
#define BSIM4_XGW 32
#define BSIM4_NGCON 33
#define BSIM4_SCA 34
#define BSIM4_SCB 35
#define BSIM4_SCC 36
#define BSIM4_SC 37
#define BSIM4_M 38
/* Global parameters */
#define BSIM4_MOD_TEMPMOD 89
#define BSIM4_MOD_IGCMOD 90
#define BSIM4_MOD_IGBMOD 91
#define BSIM4_MOD_ACNQSMOD 92
@ -2116,7 +2485,20 @@ typedef struct sBSIM4model
#define BSIM4_MOD_CIGSD 279
#define BSIM4_MOD_JSWGS 280
#define BSIM4_MOD_JSWGD 281
#define BSIM4_MOD_LAMBDA 282
#define BSIM4_MOD_VTL 283
#define BSIM4_MOD_LC 284
#define BSIM4_MOD_XN 285
#define BSIM4_MOD_RNOIA 286
#define BSIM4_MOD_RNOIB 287
#define BSIM4_MOD_VFBSDOFF 288
#define BSIM4_MOD_LINTNOI 289
#define BSIM4_MOD_UD 290
#define BSIM4_MOD_UD1 291
#define BSIM4_MOD_UP 292
#define BSIM4_MOD_LP 293
#define BSIM4_MOD_TVOFF 294
#define BSIM4_MOD_TVFBSDOFF 295
/* Length dependence */
#define BSIM4_MOD_LCDSC 301
@ -2244,6 +2626,14 @@ typedef struct sBSIM4model
#define BSIM4_MOD_LBIGSD 433
#define BSIM4_MOD_LCIGSD 434
#define BSIM4_MOD_LLAMBDA 435
#define BSIM4_MOD_LVTL 436
#define BSIM4_MOD_LXN 437
#define BSIM4_MOD_LVFBSDOFF 438
#define BSIM4_MOD_LUD 439
#define BSIM4_MOD_LUD1 440
#define BSIM4_MOD_LUP 441
#define BSIM4_MOD_LLP 442
/* Width dependence */
#define BSIM4_MOD_WCDSC 481
@ -2370,7 +2760,14 @@ typedef struct sBSIM4model
#define BSIM4_MOD_WAIGSD 612
#define BSIM4_MOD_WBIGSD 613
#define BSIM4_MOD_WCIGSD 614
#define BSIM4_MOD_WLAMBDA 615
#define BSIM4_MOD_WVTL 616
#define BSIM4_MOD_WXN 617
#define BSIM4_MOD_WVFBSDOFF 618
#define BSIM4_MOD_WUD 619
#define BSIM4_MOD_WUD1 620
#define BSIM4_MOD_WUP 621
#define BSIM4_MOD_WLP 622
/* Cross-term dependence */
#define BSIM4_MOD_PCDSC 661
@ -2505,6 +2902,41 @@ typedef struct sBSIM4model
#define BSIM4_MOD_PBIGSD 793
#define BSIM4_MOD_PCIGSD 794
#define BSIM4_MOD_SAREF 795
#define BSIM4_MOD_SBREF 796
#define BSIM4_MOD_KU0 797
#define BSIM4_MOD_KVSAT 798
#define BSIM4_MOD_TKU0 799
#define BSIM4_MOD_LLODKU0 800
#define BSIM4_MOD_WLODKU0 801
#define BSIM4_MOD_LLODVTH 802
#define BSIM4_MOD_WLODVTH 803
#define BSIM4_MOD_LKU0 804
#define BSIM4_MOD_WKU0 805
#define BSIM4_MOD_PKU0 806
#define BSIM4_MOD_KVTH0 807
#define BSIM4_MOD_LKVTH0 808
#define BSIM4_MOD_WKVTH0 809
#define BSIM4_MOD_PKVTH0 810
#define BSIM4_MOD_WLOD 811
#define BSIM4_MOD_STK2 812
#define BSIM4_MOD_LODK2 813
#define BSIM4_MOD_STETA0 814
#define BSIM4_MOD_LODETA0 815
#define BSIM4_MOD_WEB 816
#define BSIM4_MOD_WEC 817
#define BSIM4_MOD_KVTH0WE 818
#define BSIM4_MOD_K2WE 819
#define BSIM4_MOD_KU0WE 820
#define BSIM4_MOD_SCREF 821
#define BSIM4_MOD_WPEMOD 822
#define BSIM4_MOD_PLAMBDA 825
#define BSIM4_MOD_PVTL 826
#define BSIM4_MOD_PXN 827
#define BSIM4_MOD_PVFBSDOFF 828
#define BSIM4_MOD_TNOM 831
#define BSIM4_MOD_CGSO 832
#define BSIM4_MOD_CGDO 833
@ -2575,6 +3007,37 @@ typedef struct sBSIM4model
#define BSIM4_MOD_JSWD 898
#define BSIM4_MOD_DLCIG 899
/* trap-assisted tunneling */
#define BSIM4_MOD_JTSS 900
#define BSIM4_MOD_JTSD 901
#define BSIM4_MOD_JTSSWS 902
#define BSIM4_MOD_JTSSWD 903
#define BSIM4_MOD_JTSSWGS 904
#define BSIM4_MOD_JTSSWGD 905
#define BSIM4_MOD_NJTS 906
#define BSIM4_MOD_NJTSSW 907
#define BSIM4_MOD_NJTSSWG 908
#define BSIM4_MOD_XTSS 909
#define BSIM4_MOD_XTSD 910
#define BSIM4_MOD_XTSSWS 911
#define BSIM4_MOD_XTSSWD 912
#define BSIM4_MOD_XTSSWGS 913
#define BSIM4_MOD_XTSSWGD 914
#define BSIM4_MOD_TNJTS 915
#define BSIM4_MOD_TNJTSSW 916
#define BSIM4_MOD_TNJTSSWG 917
#define BSIM4_MOD_VTSS 918
#define BSIM4_MOD_VTSD 919
#define BSIM4_MOD_VTSSWS 920
#define BSIM4_MOD_VTSSWD 921
#define BSIM4_MOD_VTSSWGS 922
#define BSIM4_MOD_VTSSWGD 923
#define BSIM4_MOD_PUD 924
#define BSIM4_MOD_PUD1 925
#define BSIM4_MOD_PUP 926
#define BSIM4_MOD_PLP 927
/* device questions */
#define BSIM4_DNODE 945
#define BSIM4_GNODEEXT 946
@ -2642,22 +3105,65 @@ typedef struct sBSIM4model
#define BSIM4_IGB 1008
#define BSIM4_IGCS 1009
#define BSIM4_IGCD 1010
#define BSIM4_QDEF 1011
#define BSIM4_DELVT0 1012
#define BSIM4_GCRG 1013
#define BSIM4_GTAU 1014
#define BSIM4_MOD_LTVOFF 1051
#define BSIM4_MOD_LTVFBSDOFF 1052
#define BSIM4_MOD_WTVOFF 1053
#define BSIM4_MOD_WTVFBSDOFF 1054
#define BSIM4_MOD_PTVOFF 1055
#define BSIM4_MOD_PTVFBSDOFF 1056
#define BSIM4_MOD_LKVTH0WE 1061
#define BSIM4_MOD_LK2WE 1062
#define BSIM4_MOD_LKU0WE 1063
#define BSIM4_MOD_WKVTH0WE 1064
#define BSIM4_MOD_WK2WE 1065
#define BSIM4_MOD_WKU0WE 1066
#define BSIM4_MOD_PKVTH0WE 1067
#define BSIM4_MOD_PK2WE 1068
#define BSIM4_MOD_PKU0WE 1069
#define BSIM4_MOD_RBPS0 1101
#define BSIM4_MOD_RBPSL 1102
#define BSIM4_MOD_RBPSW 1103
#define BSIM4_MOD_RBPSNF 1104
#define BSIM4_MOD_RBPD0 1105
#define BSIM4_MOD_RBPDL 1106
#define BSIM4_MOD_RBPDW 1107
#define BSIM4_MOD_RBPDNF 1108
#define BSIM4_MOD_RBPBX0 1109
#define BSIM4_MOD_RBPBXL 1110
#define BSIM4_MOD_RBPBXW 1111
#define BSIM4_MOD_RBPBXNF 1112
#define BSIM4_MOD_RBPBY0 1113
#define BSIM4_MOD_RBPBYL 1114
#define BSIM4_MOD_RBPBYW 1115
#define BSIM4_MOD_RBPBYNF 1116
#define BSIM4_MOD_RBSBX0 1117
#define BSIM4_MOD_RBSBY0 1118
#define BSIM4_MOD_RBDBX0 1119
#define BSIM4_MOD_RBDBY0 1120
#define BSIM4_MOD_RBSDBXL 1121
#define BSIM4_MOD_RBSDBXW 1122
#define BSIM4_MOD_RBSDBXNF 1123
#define BSIM4_MOD_RBSDBYL 1124
#define BSIM4_MOD_RBSDBYW 1125
#define BSIM4_MOD_RBSDBYNF 1126
#
#include "bsim4ext.h"
#ifdef __STDC__
extern void BSIM4evaluate(double,double,double,BSIM4instance*,BSIM4model*,
double*,double*,double*, double*, double*, double*, double*,
double*, double*, double*, double*, double*, double*, double*,
double*, double*, double*, double*, CKTcircuit*);
extern int BSIM4debug(BSIM4model*, BSIM4instance*, CKTcircuit*, int);
extern int BSIM4checkModel(BSIM4model*, BSIM4instance*, CKTcircuit*);
#else /* stdc */
extern void BSIM4evaluate();
extern int BSIM4debug();
extern int BSIM4checkModel();
#endif /* stdc */
#endif /*BSIM4*/

View File

@ -1,11 +1,10 @@
/**********
Copyright 2001 Regents of the University of California. All rights reserved.
Copyright 2004 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu
Author: 2001 Xuemei Xi
Author: 2001- Xuemei Xi
File: bsim4ext.h
**********/
#ifdef __STDC__
extern int BSIM4acLoad(GENmodel *,CKTcircuit*);
extern int BSIM4ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*);
extern int BSIM4convTest(GENmodel *,CKTcircuit*);
@ -29,26 +28,3 @@ extern int BSIM4temp(GENmodel*,CKTcircuit*);
extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM4unsetup(GENmodel*,CKTcircuit*);
#else /* stdc */
extern int BSIM4acLoad();
extern int BSIM4delete();
extern void BSIM4destroy();
extern int BSIM4getic();
extern int BSIM4load();
extern int BSIM4mDelete();
extern int BSIM4ask();
extern int BSIM4mAsk();
extern int BSIM4convTest();
extern int BSIM4temp();
extern int BSIM4mParam();
extern void BSIM4mosCap();
extern int BSIM4param();
extern int BSIM4pzLoad();
extern int BSIM4setup();
extern int BSIM4trunc();
extern int BSIM4noise();
extern int BSIM4unsetup();
#endif /* stdc */

View File

@ -1,6 +1,6 @@
#include <config.h>
#include "config.h"
#include <devdefs.h>
#include "devdefs.h"
#include "bsim4itf.h"
#include "bsim4ext.h"
@ -40,36 +40,39 @@ SPICEdev BSIM4info = {
DEV_DEFAULT
},
DEVparam : BSIM4param,
DEVmodParam : BSIM4mParam,
DEVload : BSIM4load,
DEVsetup : BSIM4setup,
DEVunsetup : BSIM4unsetup,
DEVpzSetup : BSIM4setup,
DEVtemperature: BSIM4temp,
DEVtrunc : BSIM4trunc,
DEVfindBranch : NULL,
DEVacLoad : BSIM4acLoad,
DEVaccept : NULL,
DEVdestroy : BSIM4destroy,
DEVmodDelete : BSIM4mDelete,
DEVdelete : BSIM4delete,
DEVsetic : BSIM4getic,
DEVask : BSIM4ask,
DEVmodAsk : BSIM4mAsk,
DEVpzLoad : BSIM4pzLoad,
DEVconvTest : BSIM4convTest,
DEVsenSetup : NULL,
DEVsenLoad : NULL,
DEVsenUpdate : NULL,
DEVsenAcLoad : NULL,
DEVsenPrint : NULL,
DEVsenTrunc : NULL,
DEVdisto : NULL,
DEVnoise : BSIM4noise,
DEVinstSize : &BSIM4iSize,
DEVmodSize : &BSIM4mSize
BSIM4param, /* DEVparam */
BSIM4mParam, /* DEVmodParam */
BSIM4load, /* DEVload */
BSIM4setup, /* DEVsetup */
BSIM4unsetup, /* DEVunsetup */
BSIM4setup, /* DEVpzSetup */
BSIM4temp, /* DEVtemperature */
BSIM4trunc, /* DEVtrunc */
NULL, /* DEVfindBranch */
BSIM4acLoad, /* DEVacLoad */
NULL, /* DEVaccept */
BSIM4destroy, /* DEVdestroy */
BSIM4mDelete, /* DEVmodDelete */
BSIM4delete, /* DEVdelete */
BSIM4getic, /* DEVsetic */
BSIM4ask, /* DEVask */
BSIM4mAsk, /* DEVmodAsk */
BSIM4pzLoad, /* DEVpzLoad */
BSIM4convTest, /* DEVconvTest */
NULL, /* DEVsenSetup */
NULL, /* DEVsenLoad */
NULL, /* DEVsenUpdate */
NULL, /* DEVsenAcLoad */
NULL, /* DEVsenPrint */
NULL, /* DEVsenTrunc */
NULL, /* DEVdisto */
BSIM4noise, /* DEVnoise */
#ifdef CIDER
NULL, /* DEVdump */
NULL, /* DEVacct */
#endif
&BSIM4iSize, /* DEVinstSize */
&BSIM4mSize /* DEVmodSize */
};

View File

@ -1,7 +1,7 @@
/**********
Copyright 2001 Regents of the University of California. All rights reserved.
Copyright 2004 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu.
Author: 2001 Xuemei Xi
Author: 2001- Xuemei Xi
File: bsim4itf.h
**********/