Browse Source

Updated bsim4 model to version 4.3.0 (replace older versions).

pre-master-46
pnenzi 21 years ago
parent
commit
a1c0c9b12d
  1. 70
      src/spicelib/devices/bsim4/Makefile.am
  2. 1563
      src/spicelib/devices/bsim4/b4.c
  3. 1342
      src/spicelib/devices/bsim4/b4acld.c
  4. 623
      src/spicelib/devices/bsim4/b4ask.c
  5. 1308
      src/spicelib/devices/bsim4/b4check.c
  6. 400
      src/spicelib/devices/bsim4/b4cvtest.c
  7. 82
      src/spicelib/devices/bsim4/b4del.c
  8. 76
      src/spicelib/devices/bsim4/b4dest.c
  9. 774
      src/spicelib/devices/bsim4/b4geo.c
  10. 88
      src/spicelib/devices/bsim4/b4getic.c
  11. 9228
      src/spicelib/devices/bsim4/b4ld.c
  12. 3845
      src/spicelib/devices/bsim4/b4mask.c
  13. 94
      src/spicelib/devices/bsim4/b4mdel.c
  14. 5333
      src/spicelib/devices/bsim4/b4mpar.c
  15. 961
      src/spicelib/devices/bsim4/b4noi.c
  16. 309
      src/spicelib/devices/bsim4/b4par.c
  17. 1516
      src/spicelib/devices/bsim4/b4pzld.c
  18. 3595
      src/spicelib/devices/bsim4/b4set.c
  19. 3211
      src/spicelib/devices/bsim4/b4temp.c
  20. 118
      src/spicelib/devices/bsim4/b4trunc.c
  21. 5580
      src/spicelib/devices/bsim4/bsim4def.h
  22. 27
      src/spicelib/devices/bsim4/bsim4ext.h
  23. 163
      src/spicelib/devices/bsim4/bsim4init.c
  24. 26
      src/spicelib/devices/bsim4/bsim4init.h
  25. 26
      src/spicelib/devices/bsim4/bsim4itf.h

70
src/spicelib/devices/bsim4/Makefile.am

@ -1,35 +1,35 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libbsim4.a
libbsim4_a_SOURCES = \
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 \
bsim4init.h \
bsim4itf.h
INCLUDES = -I$(top_srcdir)/src/include
MAINTAINERCLEANFILES = Makefile.in
## Process this file with automake to produce Makefile.in
pkglib_LIBRARIES = libbsim4.a
libbsim4_a_SOURCES = \
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 \
bsim4init.h \
bsim4itf.h
INCLUDES = -I$(top_srcdir)/src/include
MAINTAINERCLEANFILES = Makefile.in

1563
src/spicelib/devices/bsim4/b4.c
File diff suppressed because it is too large
View File

1342
src/spicelib/devices/bsim4/b4acld.c
File diff suppressed because it is too large
View File

623
src/spicelib/devices/bsim4/b4ask.c

@ -1,300 +1,323 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4ask.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "bsim4def.h"
#include "sperror.h"
int
BSIM4ask(ckt,inst,which,value,select)
CKTcircuit *ckt;
GENinstance *inst;
int which;
IFvalue *value;
IFvalue *select;
{
BSIM4instance *here = (BSIM4instance*)inst;
switch(which)
{ case BSIM4_L:
value->rValue = here->BSIM4l;
return(OK);
case BSIM4_W:
value->rValue = here->BSIM4w;
return(OK);
case BSIM4_NF:
value->rValue = here->BSIM4nf;
return(OK);
case BSIM4_MIN:
value->iValue = here->BSIM4min;
return(OK);
case BSIM4_AS:
value->rValue = here->BSIM4sourceArea;
return(OK);
case BSIM4_AD:
value->rValue = here->BSIM4drainArea;
return(OK);
case BSIM4_PS:
value->rValue = here->BSIM4sourcePerimeter;
return(OK);
case BSIM4_PD:
value->rValue = here->BSIM4drainPerimeter;
return(OK);
case BSIM4_NRS:
value->rValue = here->BSIM4sourceSquares;
return(OK);
case BSIM4_NRD:
value->rValue = here->BSIM4drainSquares;
return(OK);
case BSIM4_OFF:
value->rValue = here->BSIM4off;
return(OK);
case BSIM4_RBSB:
value->rValue = here->BSIM4rbsb;
return(OK);
case BSIM4_RBDB:
value->rValue = here->BSIM4rbdb;
return(OK);
case BSIM4_RBPB:
value->rValue = here->BSIM4rbpb;
return(OK);
case BSIM4_RBPS:
value->rValue = here->BSIM4rbps;
return(OK);
case BSIM4_RBPD:
value->rValue = here->BSIM4rbpd;
return(OK);
case BSIM4_TRNQSMOD:
value->iValue = here->BSIM4trnqsMod;
return(OK);
case BSIM4_ACNQSMOD:
value->iValue = here->BSIM4acnqsMod;
return(OK);
case BSIM4_RBODYMOD:
value->iValue = here->BSIM4rbodyMod;
return(OK);
case BSIM4_RGATEMOD:
value->iValue = here->BSIM4rgateMod;
return(OK);
case BSIM4_GEOMOD:
value->iValue = here->BSIM4geoMod;
return(OK);
case BSIM4_RGEOMOD:
value->iValue = here->BSIM4rgeoMod;
return(OK);
case BSIM4_IC_VDS:
value->rValue = here->BSIM4icVDS;
return(OK);
case BSIM4_IC_VGS:
value->rValue = here->BSIM4icVGS;
return(OK);
case BSIM4_IC_VBS:
value->rValue = here->BSIM4icVBS;
return(OK);
case BSIM4_DNODE:
value->iValue = here->BSIM4dNode;
return(OK);
case BSIM4_GNODEEXT:
value->iValue = here->BSIM4gNodeExt;
return(OK);
case BSIM4_SNODE:
value->iValue = here->BSIM4sNode;
return(OK);
case BSIM4_BNODE:
value->iValue = here->BSIM4bNode;
return(OK);
case BSIM4_DNODEPRIME:
value->iValue = here->BSIM4dNodePrime;
return(OK);
case BSIM4_GNODEPRIME:
value->iValue = here->BSIM4gNodePrime;
return(OK);
case BSIM4_GNODEMID:
value->iValue = here->BSIM4gNodeMid;
return(OK);
case BSIM4_SNODEPRIME:
value->iValue = here->BSIM4sNodePrime;
return(OK);
case BSIM4_DBNODE:
value->iValue = here->BSIM4dbNode;
return(OK);
case BSIM4_BNODEPRIME:
value->iValue = here->BSIM4bNodePrime;
return(OK);
case BSIM4_SBNODE:
value->iValue = here->BSIM4sbNode;
return(OK);
case BSIM4_SOURCECONDUCT:
value->rValue = here->BSIM4sourceConductance;
return(OK);
case BSIM4_DRAINCONDUCT:
value->rValue = here->BSIM4drainConductance;
return(OK);
case BSIM4_VBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbd);
return(OK);
case BSIM4_VBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbs);
return(OK);
case BSIM4_VGS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vgs);
return(OK);
case BSIM4_VDS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vds);
return(OK);
case BSIM4_CD:
value->rValue = here->BSIM4cd;
return(OK);
case BSIM4_CBS:
value->rValue = here->BSIM4cbs;
return(OK);
case BSIM4_CBD:
value->rValue = here->BSIM4cbd;
return(OK);
case BSIM4_CSUB:
value->rValue = here->BSIM4csub;
return(OK);
case BSIM4_IGIDL:
value->rValue = here->BSIM4Igidl;
return(OK);
case BSIM4_IGISL:
value->rValue = here->BSIM4Igisl;
return(OK);
case BSIM4_IGS:
value->rValue = here->BSIM4Igs;
return(OK);
case BSIM4_IGD:
value->rValue = here->BSIM4Igd;
return(OK);
case BSIM4_IGB:
value->rValue = here->BSIM4Igb;
return(OK);
case BSIM4_IGCS:
value->rValue = here->BSIM4Igcs;
return(OK);
case BSIM4_IGCD:
value->rValue = here->BSIM4Igcd;
return(OK);
case BSIM4_GM:
value->rValue = here->BSIM4gm;
return(OK);
case BSIM4_GDS:
value->rValue = here->BSIM4gds;
return(OK);
case BSIM4_GMBS:
value->rValue = here->BSIM4gmbs;
return(OK);
case BSIM4_GBD:
value->rValue = here->BSIM4gbd;
return(OK);
case BSIM4_GBS:
value->rValue = here->BSIM4gbs;
return(OK);
case BSIM4_QB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qb);
return(OK);
case BSIM4_CQB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqb);
return(OK);
case BSIM4_QG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qg);
return(OK);
case BSIM4_CQG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqg);
return(OK);
case BSIM4_QD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qd);
return(OK);
case BSIM4_CQD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqd);
return(OK);
case BSIM4_QS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qs);
return(OK);
case BSIM4_CGGB:
value->rValue = here->BSIM4cggb;
return(OK);
case BSIM4_CGDB:
value->rValue = here->BSIM4cgdb;
return(OK);
case BSIM4_CGSB:
value->rValue = here->BSIM4cgsb;
return(OK);
case BSIM4_CDGB:
value->rValue = here->BSIM4cdgb;
return(OK);
case BSIM4_CDDB:
value->rValue = here->BSIM4cddb;
return(OK);
case BSIM4_CDSB:
value->rValue = here->BSIM4cdsb;
return(OK);
case BSIM4_CBGB:
value->rValue = here->BSIM4cbgb;
return(OK);
case BSIM4_CBDB:
value->rValue = here->BSIM4cbdb;
return(OK);
case BSIM4_CBSB:
value->rValue = here->BSIM4cbsb;
return(OK);
case BSIM4_CSGB:
value->rValue = here->BSIM4csgb;
return(OK);
case BSIM4_CSDB:
value->rValue = here->BSIM4csdb;
return(OK);
case BSIM4_CSSB:
value->rValue = here->BSIM4cssb;
return(OK);
case BSIM4_CGBB:
value->rValue = here->BSIM4cgbb;
return(OK);
case BSIM4_CDBB:
value->rValue = here->BSIM4cdbb;
return(OK);
case BSIM4_CSBB:
value->rValue = here->BSIM4csbb;
return(OK);
case BSIM4_CBBB:
value->rValue = here->BSIM4cbbb;
return(OK);
case BSIM4_CAPBD:
value->rValue = here->BSIM4capbd;
return(OK);
case BSIM4_CAPBS:
value->rValue = here->BSIM4capbs;
return(OK);
case BSIM4_VON:
value->rValue = here->BSIM4von;
return(OK);
case BSIM4_VDSAT:
value->rValue = here->BSIM4vdsat;
return(OK);
case BSIM4_QBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbs);
return(OK);
case BSIM4_QBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbd);
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4ask.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, 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 "ifsim.h"
#include "cktdefs.h"
#include "devdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4ask(ckt,inst,which,value,select)
CKTcircuit *ckt;
GENinstance *inst;
int which;
IFvalue *value;
IFvalue *select;
{
BSIM4instance *here = (BSIM4instance*)inst;
switch(which)
{ case BSIM4_L:
value->rValue = here->BSIM4l;
return(OK);
case BSIM4_W:
value->rValue = here->BSIM4w;
return(OK);
case BSIM4_M:
value->rValue = here->BSIM4m;
return(OK);
case BSIM4_NF:
value->rValue = here->BSIM4nf;
return(OK);
case BSIM4_MIN:
value->iValue = here->BSIM4min;
return(OK);
case BSIM4_AS:
value->rValue = here->BSIM4sourceArea;
return(OK);
case BSIM4_AD:
value->rValue = here->BSIM4drainArea;
return(OK);
case BSIM4_PS:
value->rValue = here->BSIM4sourcePerimeter;
return(OK);
case BSIM4_PD:
value->rValue = here->BSIM4drainPerimeter;
return(OK);
case BSIM4_NRS:
value->rValue = here->BSIM4sourceSquares;
return(OK);
case BSIM4_NRD:
value->rValue = here->BSIM4drainSquares;
return(OK);
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_RBSB:
value->rValue = here->BSIM4rbsb;
return(OK);
case BSIM4_RBDB:
value->rValue = here->BSIM4rbdb;
return(OK);
case BSIM4_RBPB:
value->rValue = here->BSIM4rbpb;
return(OK);
case BSIM4_RBPS:
value->rValue = here->BSIM4rbps;
return(OK);
case BSIM4_RBPD:
value->rValue = here->BSIM4rbpd;
return(OK);
case BSIM4_TRNQSMOD:
value->iValue = here->BSIM4trnqsMod;
return(OK);
case BSIM4_ACNQSMOD:
value->iValue = here->BSIM4acnqsMod;
return(OK);
case BSIM4_RBODYMOD:
value->iValue = here->BSIM4rbodyMod;
return(OK);
case BSIM4_RGATEMOD:
value->iValue = here->BSIM4rgateMod;
return(OK);
case BSIM4_GEOMOD:
value->iValue = here->BSIM4geoMod;
return(OK);
case BSIM4_RGEOMOD:
value->iValue = here->BSIM4rgeoMod;
return(OK);
case BSIM4_IC_VDS:
value->rValue = here->BSIM4icVDS;
return(OK);
case BSIM4_IC_VGS:
value->rValue = here->BSIM4icVGS;
return(OK);
case BSIM4_IC_VBS:
value->rValue = here->BSIM4icVBS;
return(OK);
case BSIM4_DNODE:
value->iValue = here->BSIM4dNode;
return(OK);
case BSIM4_GNODEEXT:
value->iValue = here->BSIM4gNodeExt;
return(OK);
case BSIM4_SNODE:
value->iValue = here->BSIM4sNode;
return(OK);
case BSIM4_BNODE:
value->iValue = here->BSIM4bNode;
return(OK);
case BSIM4_DNODEPRIME:
value->iValue = here->BSIM4dNodePrime;
return(OK);
case BSIM4_GNODEPRIME:
value->iValue = here->BSIM4gNodePrime;
return(OK);
case BSIM4_GNODEMID:
value->iValue = here->BSIM4gNodeMid;
return(OK);
case BSIM4_SNODEPRIME:
value->iValue = here->BSIM4sNodePrime;
return(OK);
case BSIM4_DBNODE:
value->iValue = here->BSIM4dbNode;
return(OK);
case BSIM4_BNODEPRIME:
value->iValue = here->BSIM4bNodePrime;
return(OK);
case BSIM4_SBNODE:
value->iValue = here->BSIM4sbNode;
return(OK);
case BSIM4_SOURCECONDUCT:
value->rValue = here->BSIM4sourceConductance;
return(OK);
case BSIM4_DRAINCONDUCT:
value->rValue = here->BSIM4drainConductance;
return(OK);
case BSIM4_VBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbd);
return(OK);
case BSIM4_VBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vbs);
return(OK);
case BSIM4_VGS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vgs);
return(OK);
case BSIM4_VDS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4vds);
return(OK);
case BSIM4_CD:
value->rValue = here->BSIM4cd;
return(OK);
case BSIM4_CBS:
value->rValue = here->BSIM4cbs;
return(OK);
case BSIM4_CBD:
value->rValue = here->BSIM4cbd;
return(OK);
case BSIM4_CSUB:
value->rValue = here->BSIM4csub;
return(OK);
case BSIM4_IGIDL:
value->rValue = here->BSIM4Igidl;
return(OK);
case BSIM4_IGISL:
value->rValue = here->BSIM4Igisl;
return(OK);
case BSIM4_IGS:
value->rValue = here->BSIM4Igs;
return(OK);
case BSIM4_IGD:
value->rValue = here->BSIM4Igd;
return(OK);
case BSIM4_IGB:
value->rValue = here->BSIM4Igb;
return(OK);
case BSIM4_IGCS:
value->rValue = here->BSIM4Igcs;
return(OK);
case BSIM4_IGCD:
value->rValue = here->BSIM4Igcd;
return(OK);
case BSIM4_GM:
value->rValue = here->BSIM4gm;
return(OK);
case BSIM4_GDS:
value->rValue = here->BSIM4gds;
return(OK);
case BSIM4_GMBS:
value->rValue = here->BSIM4gmbs;
return(OK);
case BSIM4_GBD:
value->rValue = here->BSIM4gbd;
return(OK);
case BSIM4_GBS:
value->rValue = here->BSIM4gbs;
return(OK);
/* case BSIM4_QB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qb);
return(OK); */
case BSIM4_CQB:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqb);
return(OK);
/* case BSIM4_QG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qg);
return(OK); */
case BSIM4_CQG:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqg);
return(OK);
/* case BSIM4_QD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qd);
return(OK); */
case BSIM4_CQD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4cqd);
return(OK);
/* 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_CGGB:
value->rValue = here->BSIM4cggb;
return(OK);
case BSIM4_CGDB:
value->rValue = here->BSIM4cgdb;
return(OK);
case BSIM4_CGSB:
value->rValue = here->BSIM4cgsb;
return(OK);
case BSIM4_CDGB:
value->rValue = here->BSIM4cdgb;
return(OK);
case BSIM4_CDDB:
value->rValue = here->BSIM4cddb;
return(OK);
case BSIM4_CDSB:
value->rValue = here->BSIM4cdsb;
return(OK);
case BSIM4_CBGB:
value->rValue = here->BSIM4cbgb;
return(OK);
case BSIM4_CBDB:
value->rValue = here->BSIM4cbdb;
return(OK);
case BSIM4_CBSB:
value->rValue = here->BSIM4cbsb;
return(OK);
case BSIM4_CSGB:
value->rValue = here->BSIM4csgb;
return(OK);
case BSIM4_CSDB:
value->rValue = here->BSIM4csdb;
return(OK);
case BSIM4_CSSB:
value->rValue = here->BSIM4cssb;
return(OK);
case BSIM4_CGBB:
value->rValue = here->BSIM4cgbb;
return(OK);
case BSIM4_CDBB:
value->rValue = here->BSIM4cdbb;
return(OK);
case BSIM4_CSBB:
value->rValue = here->BSIM4csbb;
return(OK);
case BSIM4_CBBB:
value->rValue = here->BSIM4cbbb;
return(OK);
case BSIM4_CAPBD:
value->rValue = here->BSIM4capbd;
return(OK);
case BSIM4_CAPBS:
value->rValue = here->BSIM4capbs;
return(OK);
case BSIM4_VON:
value->rValue = here->BSIM4von;
return(OK);
case BSIM4_VDSAT:
value->rValue = here->BSIM4vdsat;
return(OK);
case BSIM4_QBS:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbs);
return(OK);
case BSIM4_QBD:
value->rValue = *(ckt->CKTstate0 + here->BSIM4qbd);
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}

1308
src/spicelib/devices/bsim4/b4check.c
File diff suppressed because it is too large
View File

400
src/spicelib/devices/bsim4/b4cvtest.c

@ -1,201 +1,199 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4cvtest.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
*
* Modified by Xuemei Xi, 10/05/2001.
**********/
#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"
int
BSIM4convTest(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
double delvbd, delvbs, delvds, delvgd, delvgs;
double delvdbd, delvsbs;
double delvbd_jct, delvbs_jct;
double vds, vgs, vgd, vgdo, vbs, vbd;
double vdbd, vdbs, vsbs;
double cbhat, cdhat, Idtot, Ibtot;
double vses, vdes, vdedo, delvses, delvded, delvdes;
double Isestot, cseshat, Idedtot, cdedhat;
double Igstot, cgshat, Igdtot, cgdhat, Igbtot, cgbhat;
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
* (*(ckt->CKTrhsOld + here->BSIM4dNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vgs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4gNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4bNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vdbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4dbNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vsbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4sbNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vses = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4sNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vdes = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4dNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vgdo = *(ckt->CKTstate0 + here->BSIM4vgs)
- *(ckt->CKTstate0 + here->BSIM4vds);
vbd = vbs - vds;
vdbd = vdbs - vds;
vgd = vgs - vds;
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM4vbd);
delvdbd = vdbd - *(ckt->CKTstate0 + here->BSIM4vdbd);
delvgd = vgd - vgdo;
delvds = vds - *(ckt->CKTstate0 + here->BSIM4vds);
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM4vgs);
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM4vbs);
delvsbs = vsbs - *(ckt->CKTstate0 + here->BSIM4vsbs);
delvses = vses - (*(ckt->CKTstate0 + here->BSIM4vses));
vdedo = *(ckt->CKTstate0 + here->BSIM4vdes)
- *(ckt->CKTstate0 + here->BSIM4vds);
delvdes = vdes - *(ckt->CKTstate0 + here->BSIM4vdes);
delvded = vdes - vds - vdedo;
delvbd_jct = (!here->BSIM4rbodyMod) ? delvbd : delvdbd;
delvbs_jct = (!here->BSIM4rbodyMod) ? delvbs : delvsbs;
if (here->BSIM4mode >= 0)
{ Idtot = here->BSIM4cd + here->BSIM4csub - here->BSIM4cbd
+ here->BSIM4Igidl;
cdhat = Idtot - here->BSIM4gbd * delvbd_jct
+ (here->BSIM4gmbs + here->BSIM4gbbs + here->BSIM4ggidlb) * delvbs
+ (here->BSIM4gm + here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs
+ (here->BSIM4gds + here->BSIM4gbds + here->BSIM4ggidld) * delvds;
Igstot = here->BSIM4Igs + here->BSIM4Igcs;
cgshat = Igstot + (here->BSIM4gIgsg + here->BSIM4gIgcsg) * delvgs
+ here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbs;
Igdtot = here->BSIM4Igd + here->BSIM4Igcd;
cgdhat = Igdtot + here->BSIM4gIgdg * delvgd + here->BSIM4gIgcdg * delvgs
+ here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbs;
Igbtot = here->BSIM4Igb;
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgs + here->BSIM4gIgbd
* delvds + here->BSIM4gIgbb * delvbs;
}
else
{ Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igisl;
cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs
* delvbd + here->BSIM4gm * delvgd
- here->BSIM4gds * delvds - here->BSIM4ggislg * vgd
- here->BSIM4ggislb * vbd + here->BSIM4ggisls * vds;
Igstot = here->BSIM4Igs + here->BSIM4Igcd;
cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd
- here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbd;
Igdtot = here->BSIM4Igd + here->BSIM4Igcs;
cgdhat = Igdtot + (here->BSIM4gIgdg + here->BSIM4gIgcsg) * delvgd
- here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbd;
Igbtot = here->BSIM4Igb;
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgd - here->BSIM4gIgbd
* delvds + here->BSIM4gIgbb * delvbd;
}
Isestot = here->BSIM4gstot * (*(ckt->CKTstate0 + here->BSIM4vses));
cseshat = Isestot + here->BSIM4gstot * delvses
+ here->BSIM4gstotd * delvds + here->BSIM4gstotg * delvgs
+ here->BSIM4gstotb * delvbs;
Idedtot = here->BSIM4gdtot * vdedo;
cdedhat = Idedtot + here->BSIM4gdtot * delvded
+ here->BSIM4gdtotd * delvds + here->BSIM4gdtotg * delvgs
+ here->BSIM4gdtotb * delvbs;
/*
* Check convergence
*/
if ((here->BSIM4off == 0) || (!(ckt->CKTmode & MODEINITFIX)))
{ tol0 = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot))
+ ckt->CKTabstol;
tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot))
+ ckt->CKTabstol;
tol2 = ckt->CKTreltol * MAX(fabs(cdedhat), fabs(Idedtot))
+ ckt->CKTabstol;
tol3 = ckt->CKTreltol * MAX(fabs(cgshat), fabs(Igstot))
+ ckt->CKTabstol;
tol4 = ckt->CKTreltol * MAX(fabs(cgdhat), fabs(Igdtot))
+ ckt->CKTabstol;
tol5 = ckt->CKTreltol * MAX(fabs(cgbhat), fabs(Igbtot))
+ ckt->CKTabstol;
if ((fabs(cdhat - Idtot) >= tol0) || (fabs(cseshat - Isestot) >= tol1)
|| (fabs(cdedhat - Idedtot) >= tol2))
{ ckt->CKTnoncon++;
return(OK);
}
if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4)
|| (fabs(cgbhat - Igbtot) >= tol5))
{ ckt->CKTnoncon++;
return(OK);
}
Ibtot = here->BSIM4cbs + here->BSIM4cbd
- here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub;
if (here->BSIM4mode >= 0)
{ cbhat = Ibtot + here->BSIM4gbd * delvbd_jct
+ here->BSIM4gbs * delvbs_jct - (here->BSIM4gbbs + here->BSIM4ggidlb)
* delvbs - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs
- (here->BSIM4gbds + here->BSIM4ggidld) * delvds
- 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;
}
tol6 = ckt->CKTreltol * MAX(fabs(cbhat),
fabs(Ibtot)) + ckt->CKTabstol;
if (fabs(cbhat - Ibtot) > tol6)
{ ckt->CKTnoncon++;
return(OK);
}
}
}
}
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4cvtest.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, 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 "cktdefs.h"
#include "bsim4def.h"
#include "trandefs.h"
#include "const.h"
#include "devdefs.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4convTest(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
double delvbd, delvbs, delvds, delvgd, delvgs;
double delvdbd, delvsbs;
double delvbd_jct, delvbs_jct;
double vds, vgs, vgd, vgdo, vbs, vbd;
double vdbd, vdbs, vsbs;
double cbhat, cdhat, Idtot, Ibtot;
double vses, vdes, vdedo, delvses, delvded, delvdes;
double Isestot, cseshat, Idedtot, cdedhat;
double Igstot, cgshat, Igdtot, cgdhat, Igbtot, cgbhat;
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
* (*(ckt->CKTrhsOld + here->BSIM4dNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vgs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4gNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4bNodePrime)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vdbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4dbNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vsbs = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4sbNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vses = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4sNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vdes = model->BSIM4type
* (*(ckt->CKTrhsOld + here->BSIM4dNode)
- *(ckt->CKTrhsOld + here->BSIM4sNodePrime));
vgdo = *(ckt->CKTstate0 + here->BSIM4vgs)
- *(ckt->CKTstate0 + here->BSIM4vds);
vbd = vbs - vds;
vdbd = vdbs - vds;
vgd = vgs - vds;
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM4vbd);
delvdbd = vdbd - *(ckt->CKTstate0 + here->BSIM4vdbd);
delvgd = vgd - vgdo;
delvds = vds - *(ckt->CKTstate0 + here->BSIM4vds);
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM4vgs);
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM4vbs);
delvsbs = vsbs - *(ckt->CKTstate0 + here->BSIM4vsbs);
delvses = vses - (*(ckt->CKTstate0 + here->BSIM4vses));
vdedo = *(ckt->CKTstate0 + here->BSIM4vdes)
- *(ckt->CKTstate0 + here->BSIM4vds);
delvdes = vdes - *(ckt->CKTstate0 + here->BSIM4vdes);
delvded = vdes - vds - vdedo;
delvbd_jct = (!here->BSIM4rbodyMod) ? delvbd : delvdbd;
delvbs_jct = (!here->BSIM4rbodyMod) ? delvbs : delvsbs;
if (here->BSIM4mode >= 0)
{ Idtot = here->BSIM4cd + here->BSIM4csub - here->BSIM4cbd
+ here->BSIM4Igidl;
cdhat = Idtot - here->BSIM4gbd * delvbd_jct
+ (here->BSIM4gmbs + here->BSIM4gbbs + here->BSIM4ggidlb) * delvbs
+ (here->BSIM4gm + here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs
+ (here->BSIM4gds + here->BSIM4gbds + here->BSIM4ggidld) * delvds;
Igstot = here->BSIM4Igs + here->BSIM4Igcs;
cgshat = Igstot + (here->BSIM4gIgsg + here->BSIM4gIgcsg) * delvgs
+ here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbs;
Igdtot = here->BSIM4Igd + here->BSIM4Igcd;
cgdhat = Igdtot + here->BSIM4gIgdg * delvgd + here->BSIM4gIgcdg * delvgs
+ here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbs;
Igbtot = here->BSIM4Igb;
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgs + here->BSIM4gIgbd
* delvds + here->BSIM4gIgbb * delvbs;
}
else
{ Idtot = here->BSIM4cd + here->BSIM4cbd - here->BSIM4Igidl; /* bugfix */
cdhat = Idtot + here->BSIM4gbd * delvbd_jct + here->BSIM4gmbs
* delvbd + here->BSIM4gm * delvgd
- (here->BSIM4gds + here->BSIM4ggidls) * delvds
- here->BSIM4ggidlg * delvgs - here->BSIM4ggidlb * delvbs;
Igstot = here->BSIM4Igs + here->BSIM4Igcd;
cgshat = Igstot + here->BSIM4gIgsg * delvgs + here->BSIM4gIgcdg * delvgd
- here->BSIM4gIgcdd * delvds + here->BSIM4gIgcdb * delvbd;
Igdtot = here->BSIM4Igd + here->BSIM4Igcs;
cgdhat = Igdtot + (here->BSIM4gIgdg + here->BSIM4gIgcsg) * delvgd
- here->BSIM4gIgcsd * delvds + here->BSIM4gIgcsb * delvbd;
Igbtot = here->BSIM4Igb;
cgbhat = here->BSIM4Igb + here->BSIM4gIgbg * delvgd - here->BSIM4gIgbd
* delvds + here->BSIM4gIgbb * delvbd;
}
Isestot = here->BSIM4gstot * (*(ckt->CKTstate0 + here->BSIM4vses));
cseshat = Isestot + here->BSIM4gstot * delvses
+ here->BSIM4gstotd * delvds + here->BSIM4gstotg * delvgs
+ here->BSIM4gstotb * delvbs;
Idedtot = here->BSIM4gdtot * vdedo;
cdedhat = Idedtot + here->BSIM4gdtot * delvded
+ here->BSIM4gdtotd * delvds + here->BSIM4gdtotg * delvgs
+ here->BSIM4gdtotb * delvbs;
/*
* Check convergence
*/
if ((here->BSIM4off == 0) || (!(ckt->CKTmode & MODEINITFIX)))
{ tol0 = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot))
+ ckt->CKTabstol;
tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot))
+ ckt->CKTabstol;
tol2 = ckt->CKTreltol * MAX(fabs(cdedhat), fabs(Idedtot))
+ ckt->CKTabstol;
tol3 = ckt->CKTreltol * MAX(fabs(cgshat), fabs(Igstot))
+ ckt->CKTabstol;
tol4 = ckt->CKTreltol * MAX(fabs(cgdhat), fabs(Igdtot))
+ ckt->CKTabstol;
tol5 = ckt->CKTreltol * MAX(fabs(cgbhat), fabs(Igbtot))
+ ckt->CKTabstol;
if ((fabs(cdhat - Idtot) >= tol0) || (fabs(cseshat - Isestot) >= tol1)
|| (fabs(cdedhat - Idedtot) >= tol2))
{ ckt->CKTnoncon++;
return(OK);
}
if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4)
|| (fabs(cgbhat - Igbtot) >= tol5))
{ ckt->CKTnoncon++;
return(OK);
}
Ibtot = here->BSIM4cbs + here->BSIM4cbd
- here->BSIM4Igidl - here->BSIM4Igisl - here->BSIM4csub;
if (here->BSIM4mode >= 0)
{ cbhat = Ibtot + here->BSIM4gbd * delvbd_jct
+ here->BSIM4gbs * delvbs_jct - (here->BSIM4gbbs + here->BSIM4ggidlb)
* delvbs - (here->BSIM4gbgs + here->BSIM4ggidlg) * delvgs
- (here->BSIM4gbds + here->BSIM4ggidld) * delvds
- here->BSIM4ggislg * delvgd - here->BSIM4ggislb* delvbd + here->BSIM4ggisls * delvds ;
}
else
{ 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;
if (fabs(cbhat - Ibtot) > tol6)
{ ckt->CKTnoncon++;
return(OK);
}
}
}
}
return(OK);
}

82
src/spicelib/devices/bsim4/b4del.c

@ -1,41 +1,41 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4del.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "sperror.h"
#include "gendefs.h"
int
BSIM4delete(inModel,name,inInst)
GENmodel *inModel;
IFuid name;
GENinstance **inInst;
{
BSIM4instance **fast = (BSIM4instance**)inInst;
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance **prev = NULL;
BSIM4instance *here;
for (; model ; model = model->BSIM4nextModel)
{ prev = &(model->BSIM4instances);
for (here = *prev; here ; here = *prev)
{ if (here->BSIM4name == name || (fast && here==*fast))
{ *prev= here->BSIM4nextInstance;
FREE(here);
return(OK);
}
prev = &(here->BSIM4nextInstance);
}
}
return(E_NODEV);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4del.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include "bsim4def.h"
#include "sperror.h"
#include "gendefs.h"
#include "suffix.h"
int
BSIM4delete(inModel,name,inInst)
GENmodel *inModel;
IFuid name;
GENinstance **inInst;
{
BSIM4instance **fast = (BSIM4instance**)inInst;
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance **prev = NULL;
BSIM4instance *here;
for (; model ; model = model->BSIM4nextModel)
{ prev = &(model->BSIM4instances);
for (here = *prev; here ; here = *prev)
{ if (here->BSIM4name == name || (fast && here==*fast))
{ *prev= here->BSIM4nextInstance;
FREE(here);
return(OK);
}
prev = &(here->BSIM4nextInstance);
}
}
return(E_NODEV);
}

76
src/spicelib/devices/bsim4/b4dest.c

@ -1,38 +1,38 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4dest.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
void
BSIM4destroy(inModel)
GENmodel **inModel;
{
BSIM4model **model = (BSIM4model**)inModel;
BSIM4instance *here;
BSIM4instance *prev = NULL;
BSIM4model *mod = *model;
BSIM4model *oldmod = NULL;
for (; mod ; mod = mod->BSIM4nextModel)
{ if(oldmod) FREE(oldmod);
oldmod = mod;
prev = (BSIM4instance *)NULL;
for (here = mod->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
}
if(oldmod) FREE(oldmod);
*model = NULL;
return;
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4dest.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include "bsim4def.h"
#include "suffix.h"
void
BSIM4destroy(inModel)
GENmodel **inModel;
{
BSIM4model **model = (BSIM4model**)inModel;
BSIM4instance *here;
BSIM4instance *prev = NULL;
BSIM4model *mod = *model;
BSIM4model *oldmod = NULL;
for (; mod ; mod = mod->BSIM4nextModel)
{ if(oldmod) FREE(oldmod);
oldmod = mod;
prev = (BSIM4instance *)NULL;
for (here = mod->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
}
if(oldmod) FREE(oldmod);
*model = NULL;
return;
}

774
src/spicelib/devices/bsim4/b4geo.c

@ -1,389 +1,385 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4geo.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
int BSIM4RdsEndIso(double Weffcj, double Rsh, double DMCG, double DMCI,
double DMDG, double nuEnd, int rgeo, int Type,
double *Rend);
int BSIM4RdsEndSha(double Weffcj, double Rsh, double DMCG, double DMCI,
double DMDG, double nuEnd, int rgeo, int Type,
double *Rend);
/*
* WDLiu:
* This subrutine is a special module to process the geometry dependent
* parasitics for BSIM4, which calculates Ps, Pd, As, Ad, and Rs and Rd
* for multi-fingers and varous GEO and RGEO options.
*/
int
BSIM4NumFingerDiff(nf, minSD, nuIntD, nuEndD, nuIntS, nuEndS)
int minSD;
double nf, *nuIntD, *nuEndD, *nuIntS, *nuEndS;
{
int NF;
NF = (int)nf;
if ((NF%2) != 0)
{ *nuEndD = *nuEndS = 1.0;
*nuIntD = *nuIntS = 2.0 * MAX((nf - 1.0) / 2.0, 0.0);
}
else
{ if (minSD == 1) /* minimize # of source */
{ *nuEndD = 2.0;
*nuIntD = 2.0 * MAX((nf / 2.0 - 1.0), 0.0);
*nuEndS = 0.0;
*nuIntS = nf;
}
else
{ *nuEndD = 0.0;
*nuIntD = nf;
*nuEndS = 2.0;
*nuIntS = 2.0 * MAX((nf / 2.0 - 1.0), 0.0);
}
}
return 0;
}
int
BSIM4PAeffGeo(nf, geo, minSD, Weffcj, DMCG, DMCI, DMDG, Ps, Pd, As, Ad)
int geo, minSD;
double Weffcj, DMCG, DMCI, DMDG;
double nf, *Ps, *Pd, *As, *Ad;
{
double T0, T1, T2;
double ADiso, ADsha, ADmer, ASiso, ASsha, ASmer;
double PDiso, PDsha, PDmer, PSiso, PSsha, PSmer;
double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0;
if (geo < 9) /* For geo = 9 and 10, the numbers of S/D diffusions already known */
BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS);
T0 = DMCG + DMCI;
T1 = DMCG + DMCG;
T2 = DMDG + DMDG;
PSiso = PDiso = T0 + T0 + Weffcj;
PSsha = PDsha = T1;
PSmer = PDmer = T2;
ASiso = ADiso = T0 * Weffcj;
ASsha = ADsha = DMCG * Weffcj;
ASmer = ADmer = DMDG * Weffcj;
switch(geo)
{ case 0:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 1:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 2:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 3:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 4:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 5:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 6:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 7:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 8:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 9: /* geo = 9 and 10 happen only when nf = even */
*Ps = PSiso + (nf - 1.0) * PSsha;
*Pd = nf * PDsha;
*As = ASiso + (nf - 1.0) * ASsha;
*Ad = nf * ADsha;
break;
case 10:
*Ps = nf * PSsha;
*Pd = PDiso + (nf - 1.0) * PDsha;
*As = nf * ASsha;
*Ad = ADiso + (nf - 1.0) * ADsha;
break;
default:
printf("Warning: Specified GEO = %d not matched\n", geo);
}
return 0;
}
int
BSIM4RdseffGeo(nf, geo, rgeo, minSD, Weffcj, Rsh, DMCG, DMCI, DMDG, Type, Rtot)
int geo, rgeo, minSD, Type;
double nf, Weffcj, Rsh, DMCG, DMCI, DMDG;
double *Rtot;
{
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 */
{ BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS);
/* Internal S/D resistance -- assume shared S or D and all wide contacts */
if (Type == 1)
{ if (nuIntS == 0.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / ( Weffcj * nuIntS);
}
else
{ if (nuIntD == 0.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / ( Weffcj * nuIntD);
}
}
/* End S/D resistance -- geo dependent */
switch(geo)
{ case 0:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 1:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 2:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 3:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 4:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else Rend = Rsh * DMDG / Weffcj;
break;
case 5:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else Rend = Rsh * DMDG / (Weffcj * nuEndD);
break;
case 6:
if (Type == 1) Rend = Rsh * DMDG / Weffcj;
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 7:
if (Type == 1) Rend = Rsh * DMDG / (Weffcj * nuEndS);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 8:
Rend = Rsh * DMDG / Weffcj;
break;
case 9: /* all wide contacts assumed for geo = 9 and 10 */
if (Type == 1)
{ Rend = 0.5 * Rsh * DMCG / Weffcj;
if (nf == 2.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0));
}
else
{ Rend = 0.0;
Rint = Rsh * DMCG / (Weffcj * nf);
}
break;
case 10:
if (Type == 1)
{ Rend = 0.0;
Rint = Rsh * DMCG / (Weffcj * nf);
}
else
{ Rend = 0.5 * Rsh * DMCG / Weffcj;;
if (nf == 2.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0));
}
break;
default:
printf("Warning: Specified GEO = %d not matched\n", geo);
}
if (Rint <= 0.0)
*Rtot = Rend;
else if (Rend <= 0.0)
*Rtot = Rint;
else
*Rtot = Rint * Rend / (Rint + Rend);
if(*Rtot==0.0)
printf("Warning: Zero resistance returned from RdseffGeo\n");
return 0;
}
int
BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)
double Weffcj, Rsh, DMCG, DMCI, DMDG;
int rgeo, Type;
double nuEnd, *Rend;
{
if (Type == 1)
{ switch(rgeo)
{ case 1:
case 2:
case 5:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 3:
case 4:
case 6:
if ((DMCG + DMCI) == 0.0)
printf("(DMCG + DMCI) can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI));
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
else
{ switch(rgeo)
{ case 1:
case 3:
case 7:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 2:
case 4:
case 8:
if ((DMCG + DMCI) == 0.0)
printf("(DMCG + DMCI) can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI));
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
return 0;
}
int
BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)
double Weffcj, Rsh, DMCG, DMCI, DMDG;
int rgeo, Type;
double nuEnd, *Rend;
{
if (Type == 1)
{ switch(rgeo)
{ case 1:
case 2:
case 5:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 3:
case 4:
case 6:
if (DMCG == 0.0)
printf("DMCG can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG);
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
else
{ switch(rgeo)
{ case 1:
case 3:
case 7:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 2:
case 4:
case 8:
if (DMCG == 0.0)
printf("DMCG can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG);
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
return 0;
}
/**** BSIM4.4.0 Released by Xuemei(Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2003 Regents of the University of California. All rights reserved.
* File: b4geo.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
/*
* WDLiu:
* This subrutine is a special module to process the geometry dependent
* parasitics for BSIM4, which calculates Ps, Pd, As, Ad, and Rs and Rd
* 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;
double nf, *nuIntD, *nuEndD, *nuIntS, *nuEndS;
{
int NF;
NF = (int)nf;
if ((NF%2) != 0)
{ *nuEndD = *nuEndS = 1.0;
*nuIntD = *nuIntS = 2.0 * MAX((nf - 1.0) / 2.0, 0.0);
}
else
{ if (minSD == 1) /* minimize # of source */
{ *nuEndD = 2.0;
*nuIntD = 2.0 * MAX((nf / 2.0 - 1.0), 0.0);
*nuEndS = 0.0;
*nuIntS = nf;
}
else
{ *nuEndD = 0.0;
*nuIntD = nf;
*nuEndS = 2.0;
*nuIntS = 2.0 * MAX((nf / 2.0 - 1.0), 0.0);
}
}
return 0;
}
int
BSIM4PAeffGeo(nf, geo, minSD, Weffcj, DMCG, DMCI, DMDG, Ps, Pd, As, Ad)
int geo, minSD;
double Weffcj, DMCG, DMCI, DMDG;
double nf, *Ps, *Pd, *As, *Ad;
{
double T0, T1, T2;
double ADiso, ADsha, ADmer, ASiso, ASsha, ASmer;
double PDiso, PDsha, PDmer, PSiso, PSsha, PSmer;
double nuIntD = 0.0, nuEndD = 0.0, nuIntS = 0.0, nuEndS = 0.0;
if (geo < 9) /* For geo = 9 and 10, the numbers of S/D diffusions already known */
BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS);
T0 = DMCG + DMCI;
T1 = DMCG + DMCG;
T2 = DMDG + DMDG;
PSiso = PDiso = T0 + T0 + Weffcj;
PSsha = PDsha = T1;
PSmer = PDmer = T2;
ASiso = ADiso = T0 * Weffcj;
ASsha = ADsha = DMCG * Weffcj;
ASmer = ADmer = DMDG * Weffcj;
switch(geo)
{ case 0:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 1:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 2:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 3:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 4:
*Ps = nuEndS * PSiso + nuIntS * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = nuEndS * ASiso + nuIntS * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 5:
*Ps = (nuEndS + nuIntS) * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = (nuEndS + nuIntS) * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 6:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = nuEndD * PDiso + nuIntD * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = nuEndD * ADiso + nuIntD * ADsha;
break;
case 7:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = (nuEndD + nuIntD) * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = (nuEndD + nuIntD) * ADsha;
break;
case 8:
*Ps = nuEndS * PSmer + nuIntS * PSsha;
*Pd = nuEndD * PDmer + nuIntD * PDsha;
*As = nuEndS * ASmer + nuIntS * ASsha;
*Ad = nuEndD * ADmer + nuIntD * ADsha;
break;
case 9: /* geo = 9 and 10 happen only when nf = even */
*Ps = PSiso + (nf - 1.0) * PSsha;
*Pd = nf * PDsha;
*As = ASiso + (nf - 1.0) * ASsha;
*Ad = nf * ADsha;
break;
case 10:
*Ps = nf * PSsha;
*Pd = PDiso + (nf - 1.0) * PDsha;
*As = nf * ASsha;
*Ad = ADiso + (nf - 1.0) * ADsha;
break;
default:
printf("Warning: Specified GEO = %d not matched\n", geo);
}
return 0;
}
int
BSIM4RdseffGeo(nf, geo, rgeo, minSD, Weffcj, Rsh, DMCG, DMCI, DMDG, Type, Rtot)
int geo, rgeo, minSD, Type;
double nf, Weffcj, Rsh, DMCG, DMCI, DMDG;
double *Rtot;
{
double Rint, 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 */
{ BSIM4NumFingerDiff(nf, minSD, &nuIntD, &nuEndD, &nuIntS, &nuEndS);
/* Internal S/D resistance -- assume shared S or D and all wide contacts */
if (Type == 1)
{ if (nuIntS == 0.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / ( Weffcj * nuIntS);
}
else
{ if (nuIntD == 0.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / ( Weffcj * nuIntD);
}
}
/* End S/D resistance -- geo dependent */
switch(geo)
{ case 0:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 1:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 2:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 3:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 4:
if (Type == 1) BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else Rend = Rsh * DMDG / Weffcj;
break;
case 5:
if (Type == 1) BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndS, rgeo, 1, &Rend);
else Rend = Rsh * DMDG / (Weffcj * nuEndD);
break;
case 6:
if (Type == 1) Rend = Rsh * DMDG / Weffcj;
else BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 7:
if (Type == 1) Rend = Rsh * DMDG / (Weffcj * nuEndS);
else BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG,
nuEndD, rgeo, 0, &Rend);
break;
case 8:
Rend = Rsh * DMDG / Weffcj;
break;
case 9: /* all wide contacts assumed for geo = 9 and 10 */
if (Type == 1)
{ Rend = 0.5 * Rsh * DMCG / Weffcj;
if (nf == 2.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0));
}
else
{ Rend = 0.0;
Rint = Rsh * DMCG / (Weffcj * nf);
}
break;
case 10:
if (Type == 1)
{ Rend = 0.0;
Rint = Rsh * DMCG / (Weffcj * nf);
}
else
{ Rend = 0.5 * Rsh * DMCG / Weffcj;;
if (nf == 2.0)
Rint = 0.0;
else
Rint = Rsh * DMCG / (Weffcj * (nf - 2.0));
}
break;
default:
printf("Warning: Specified GEO = %d not matched\n", geo);
}
if (Rint <= 0.0)
*Rtot = Rend;
else if (Rend <= 0.0)
*Rtot = Rint;
else
*Rtot = Rint * Rend / (Rint + Rend);
if(*Rtot==0.0)
printf("Warning: Zero resistance returned from RdseffGeo\n");
return 0;
}
int
BSIM4RdsEndIso(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)
double Weffcj, Rsh, DMCG, DMCI, DMDG;
int rgeo, Type;
double nuEnd, *Rend;
{
if (Type == 1)
{ switch(rgeo)
{ case 1:
case 2:
case 5:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 3:
case 4:
case 6:
if ((DMCG + DMCI) == 0.0)
printf("(DMCG + DMCI) can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI));
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
else
{ switch(rgeo)
{ case 1:
case 3:
case 7:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 2:
case 4:
case 8:
if ((DMCG + DMCI) == 0.0)
printf("(DMCG + DMCI) can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (3.0 * nuEnd * (DMCG + DMCI));
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
return 0;
}
int
BSIM4RdsEndSha(Weffcj, Rsh, DMCG, DMCI, DMDG, nuEnd, rgeo, Type, Rend)
double Weffcj, Rsh, DMCG, DMCI, DMDG;
int rgeo, Type;
double nuEnd, *Rend;
{
if (Type == 1)
{ switch(rgeo)
{ case 1:
case 2:
case 5:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 3:
case 4:
case 6:
if (DMCG == 0.0)
printf("DMCG can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG);
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
else
{ switch(rgeo)
{ case 1:
case 3:
case 7:
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * DMCG / (Weffcj * nuEnd);
break;
case 2:
case 4:
case 8:
if (DMCG == 0.0)
printf("DMCG can not be equal to zero\n");
if (nuEnd == 0.0)
*Rend = 0.0;
else
*Rend = Rsh * Weffcj / (6.0 * nuEnd * DMCG);
break;
default:
printf("Warning: Specified RGEO = %d not matched\n", rgeo);
}
}
return 0;
}

88
src/spicelib/devices/bsim4/b4getic.c

@ -1,44 +1,44 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4getic.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
int
BSIM4getic(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
for (; model ; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
if (!here->BSIM4icVDSGiven)
{ here->BSIM4icVDS = *(ckt->CKTrhs + here->BSIM4dNode)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
if (!here->BSIM4icVGSGiven)
{ here->BSIM4icVGS = *(ckt->CKTrhs + here->BSIM4gNodeExt)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
if(!here->BSIM4icVBSGiven)
{ here->BSIM4icVBS = *(ckt->CKTrhs + here->BSIM4bNode)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
}
}
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4getic.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4getic(inModel,ckt)
GENmodel *inModel;
CKTcircuit *ckt;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
for (; model ; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if (here->BSIM4owner != ARCHme) continue;
if (!here->BSIM4icVDSGiven)
{ here->BSIM4icVDS = *(ckt->CKTrhs + here->BSIM4dNode)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
if (!here->BSIM4icVGSGiven)
{ here->BSIM4icVGS = *(ckt->CKTrhs + here->BSIM4gNodeExt)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
if(!here->BSIM4icVBSGiven)
{ here->BSIM4icVBS = *(ckt->CKTrhs + here->BSIM4bNode)
- *(ckt->CKTrhs + here->BSIM4sNode);
}
}
}
return(OK);
}

9228
src/spicelib/devices/bsim4/b4ld.c
File diff suppressed because it is too large
View File

3845
src/spicelib/devices/bsim4/b4mask.c
File diff suppressed because it is too large
View File

94
src/spicelib/devices/bsim4/b4mdel.c

@ -1,47 +1,47 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4mdel.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "bsim4def.h"
#include "sperror.h"
int
BSIM4mDelete(inModel,modname,kill)
GENmodel **inModel;
IFuid modname;
GENmodel *kill;
{
BSIM4model **model = (BSIM4model**)inModel;
BSIM4model *modfast = (BSIM4model*)kill;
BSIM4instance *here;
BSIM4instance *prev = NULL;
BSIM4model **oldmod;
oldmod = model;
for (; *model ; model = &((*model)->BSIM4nextModel))
{ if ((*model)->BSIM4modName == modname ||
(modfast && *model == modfast))
goto delgot;
oldmod = model;
}
return(E_NOMOD);
delgot:
*oldmod = (*model)->BSIM4nextModel; /* cut deleted device out of list */
for (here = (*model)->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
FREE(*model);
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4mdel.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4mDelete(inModel,modname,kill)
GENmodel **inModel;
IFuid modname;
GENmodel *kill;
{
BSIM4model **model = (BSIM4model**)inModel;
BSIM4model *modfast = (BSIM4model*)kill;
BSIM4instance *here;
BSIM4instance *prev = NULL;
BSIM4model **oldmod;
oldmod = model;
for (; *model ; model = &((*model)->BSIM4nextModel))
{ if ((*model)->BSIM4modName == modname ||
(modfast && *model == modfast))
goto delgot;
oldmod = model;
}
return(E_NOMOD);
delgot:
*oldmod = (*model)->BSIM4nextModel; /* cut deleted device out of list */
for (here = (*model)->BSIM4instances; here; here = here->BSIM4nextInstance)
{ if(prev) FREE(prev);
prev = here;
}
if(prev) FREE(prev);
FREE(*model);
return(OK);
}

5333
src/spicelib/devices/bsim4/b4mpar.c
File diff suppressed because it is too large
View File

961
src/spicelib/devices/bsim4/b4noi.c

@ -1,473 +1,488 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4noi.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
* Modified by Xuemei Xi, 10/05/2001.
**********/
#include "ngspice.h"
#include <stdio.h>
#include <math.h>
#include "bsim4def.h"
#include "cktdefs.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "const.h"
extern void NevalSrc();
extern double Nintegrate();
/*
* WDL: 1/f noise model has been smoothed out and enhanced with
* bulk charge effect as well as physical N* equ. and necessary
* conversion into the SI unit system.
*/
double
Eval1ovFNoise(Vds, model, here, freq, temp)
double Vds, freq, temp;
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, Ssi;
pParam = here->pParam;
cd = fabs(here->BSIM4cd);
esat = 2.0 * pParam->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));
}
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;
N0 = model->BSIM4coxe * here->BSIM4Vgsteff / CHARGE;
Nl = model->BSIM4coxe * here->BSIM4Vgsteff
* (1.0 - here->BSIM4AbovVgst2Vtm * here->BSIM4Vdseff) / CHARGE;
T3 = model->BSIM4oxideTrapDensityA
* log(MAX(((N0 + here->BSIM4nstar) / (Nl + here->BSIM4nstar)), N_MINLOG));
T4 = model->BSIM4oxideTrapDensityB * (N0 - Nl);
T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
T6 = CONSTboltz * temp * cd * cd;
T7 = 1.0e10 * EffFreq * pParam->BSIM4leff
* pParam->BSIM4leff * pParam->BSIM4weff;
T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl
+ model->BSIM4oxideTrapDensityC * Nl * Nl;
T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar);
Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
return Ssi;
}
int
BSIM4noise (mode, operation, inModel, ckt, data, OnDens)
int mode, operation;
GENmodel *inModel;
CKTcircuit *ckt;
Ndata *data;
double *OnDens;
{
BSIM4model *model = (BSIM4model *)inModel;
BSIM4instance *here;
struct bsim4SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM4NSRCS];
double lnNdens[BSIM4NSRCS];
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;
int i;
/* define the names of the noise sources */
static char *BSIM4nNames[BSIM4NSRCS] =
{ /* Note that we have to keep the order */
".rd", /* noise due to rd */
".rs", /* noise due to rs */
".rg", /* noise due to rgeltd */
".rbps", /* noise due to rbps */
".rbpd", /* noise due to rbpd */
".rbpb", /* noise due to rbpb */
".rbsb", /* noise due to rbsb */
".rbdb", /* noise due to rbdb */
".id", /* noise due to id */
".1overf", /* flicker (1/f) noise */
".igs", /* shot noise due to IGS */
".igd", /* shot noise due to IGD */
".igb", /* shot noise due to IGB */
"" /* total transistor noise */
};
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{ pParam = here->pParam;
switch (operation)
{ case N_OPEN:
/* see if we have to to produce a summary report */
/* if so, name all the noise generators */
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0)
{ switch (mode)
{ case N_DENS:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **) NULL);
/* we've added one more plot */
}
break;
case INT_NOIZ:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **) NULL);
/* we've added one more plot */
(void) sprintf(name, "inoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **)NULL);
/* we've added one more plot */
}
break;
}
}
break;
case N_CALC:
switch (mode)
{ case N_DENS:
if (model->BSIM4tnoiMod == 0)
{ if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
if (here->BSIM4grdsw > 0.0)
tmp = 1.0 / here->BSIM4grdsw; /* tmp used below */
else
tmp = 0.0;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
tmp = 0.0;
}
}
else
{ T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T5 *= T5;
npart_beta = 0.577 * (1.0 + T5
* model->BSIM4tnoia * pParam->BSIM4leff);
npart_theta = 0.37 * (1.0 + T5
* model->BSIM4tnoib * pParam->BSIM4leff);
if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
}
if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0)
gspr = gspr * (1.0 + npart_theta * npart_theta * gspr
/ here->BSIM4IdovVds);
else
gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr
/ here->BSIM4IdovVds);
}
NevalSrc(&noizDens[BSIM4RDNOIZ],
&lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE,
here->BSIM4dNodePrime, here->BSIM4dNode,
gdpr);
NevalSrc(&noizDens[BSIM4RSNOIZ],
&lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE,
here->BSIM4sNodePrime, here->BSIM4sNode,
gspr);
if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2))
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodePrime, here->BSIM4gNodeExt,
here->BSIM4grgeltd);
}
else if (here->BSIM4rgateMod == 3)
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodeMid, here->BSIM4gNodeExt,
here->BSIM4grgeltd);
}
else
{ noizDens[BSIM4RGNOIZ] = 0.0;
lnNdens[BSIM4RGNOIZ] =
log(MAX(noizDens[BSIM4RGNOIZ], N_MINLOG));
}
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);
}
else
{ noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
noizDens[BSIM4RBPBNOIZ] = 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[BSIM4RBPBNOIZ] =
log(MAX(noizDens[BSIM4RBPBNOIZ], N_MINLOG));
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
switch(model->BSIM4tnoiMod)
{ case 0:
T0 = here->BSIM4ueff * fabs(here->BSIM4qinv);
T1 = T0 * tmp + pParam->BSIM4leff
* pParam->BSIM4leff;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime,
(T0 / T1) * model->BSIM4ntnoi);
break;
case 1:
T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds;
T0 *= T0;
igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds;
T1 = npart_beta * (here->BSIM4gm
+ here->BSIM4gmbs) + here->BSIM4gds;
T2 = T1 * T1 / here->BSIM4IdovVds;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (T2 - igsquare));
break;
}
NevalSrc(&noizDens[BSIM4FLNOIZ], (double*) NULL,
ckt, N_GAIN, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (double) 0.0);
switch(model->BSIM4fnoiMod)
{ case 0:
noizDens[BSIM4FLNOIZ] *= model->BSIM4kf
* exp(model->BSIM4af
* log(MAX(fabs(here->BSIM4cd),
N_MINLOG)))
/ (pow(data->freq, model->BSIM4ef)
* pParam->BSIM4leff
* pParam->BSIM4leff
* model->BSIM4coxe);
break;
case 1:
Vds = *(ckt->CKTstates[0] + here->BSIM4vds);
if (Vds < 0.0)
Vds = -Vds;
Ssi = Eval1ovFNoise(Vds, model, here,
data->freq, ckt->CKTtemp);
T10 = model->BSIM4oxideTrapDensityA
* CONSTboltz * ckt->CKTtemp;
T11 = pParam->BSIM4weff * 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;
else
noizDens[BSIM4FLNOIZ] *= 0.0;
break;
}
lnNdens[BSIM4FLNOIZ] =
log(MAX(noizDens[BSIM4FLNOIZ], N_MINLOG));
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
(here->BSIM4Igs + here->BSIM4Igcs));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
(here->BSIM4Igd + here->BSIM4Igcd));
NevalSrc(&noizDens[BSIM4IGBNOIZ],
&lnNdens[BSIM4IGBNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4bNodePrime,
here->BSIM4Igb);
noizDens[BSIM4TOTNOIZ] = noizDens[BSIM4RDNOIZ]
+ noizDens[BSIM4RSNOIZ] + noizDens[BSIM4RGNOIZ]
+ noizDens[BSIM4RBPSNOIZ] + noizDens[BSIM4RBPDNOIZ]
+ noizDens[BSIM4RBPBNOIZ]
+ noizDens[BSIM4RBSBNOIZ] + noizDens[BSIM4RBDBNOIZ]
+ noizDens[BSIM4IDNOIZ] + noizDens[BSIM4FLNOIZ]
+ noizDens[BSIM4IGSNOIZ] + noizDens[BSIM4IGDNOIZ]
+ noizDens[BSIM4IGBNOIZ];
lnNdens[BSIM4TOTNOIZ] =
log(MAX(noizDens[BSIM4TOTNOIZ], N_MINLOG));
*OnDens += noizDens[BSIM4TOTNOIZ];
if (data->delFreq == 0.0)
{ /* if we haven't done any previous
integration, we need to initialize our
"history" variables.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
}
/* clear out our integration variables
if it's the first pass
*/
if (data->freq ==
((NOISEAN*) ckt->CKTcurJob)->NstartFreq)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[OUTNOIZ][i] = 0.0;
here->BSIM4nVar[INNOIZ][i] = 0.0;
}
}
}
else
{ /* data->delFreq != 0.0,
we have to integrate.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ if (i != BSIM4TOTNOIZ)
{ tempOnoise = Nintegrate(noizDens[i],
lnNdens[i],
here->BSIM4nVar[LNLSTDENS][i],
data);
tempInoise = Nintegrate(noizDens[i]
* data->GainSqInv, lnNdens[i]
+ data->lnGainInv,
here->BSIM4nVar[LNLSTDENS][i]
+ data->lnGainInv, data);
here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
data->outNoiz += tempOnoise;
data->inNoise += tempInoise;
if (((NOISEAN*)
ckt->CKTcurJob)->NStpsSm != 0)
{ here->BSIM4nVar[OUTNOIZ][i]
+= tempOnoise;
here->BSIM4nVar[OUTNOIZ][BSIM4TOTNOIZ]
+= tempOnoise;
here->BSIM4nVar[INNOIZ][i]
+= tempInoise;
here->BSIM4nVar[INNOIZ][BSIM4TOTNOIZ]
+= tempInoise;
}
}
}
}
if (data->prtSummary)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ /* print a summary report */
data->outpVector[data->outNumber++]
= noizDens[i];
}
}
break;
case INT_NOIZ:
/* already calculated, just output */
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ data->outpVector[data->outNumber++]
= here->BSIM4nVar[OUTNOIZ][i];
data->outpVector[data->outNumber++]
= here->BSIM4nVar[INNOIZ][i];
}
}
break;
}
break;
case N_CLOSE:
/* do nothing, the main calling routine will close */
return (OK);
break; /* the plots */
} /* switch (operation) */
} /* for here */
} /* for model */
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4noi.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, 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.
**********/
#include "ngspice.h"
#include "bsim4def.h"
#include "cktdefs.h"
#include "iferrmsg.h"
#include "noisedef.h"
#include "suffix.h"
#include "const.h"
extern void NevalSrc();
extern double Nintegrate();
/*
* WDL: 1/f noise model has been smoothed out and enhanced with
* bulk charge effect as well as physical N* equ. and necessary
* conversion into the SI unit system.
*/
double
Eval1ovFNoise(Vds, model, here, freq, temp)
double Vds, freq, temp;
BSIM4model *model;
BSIM4instance *here;
{
struct bsim4SizeDependParam *pParam;
double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq;
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;
pParam = here->pParam;
cd = fabs(here->BSIM4cd);
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));
}
EffFreq = pow(freq, model->BSIM4ef);
T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff;
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;
T3 = model->BSIM4oxideTrapDensityA
* log(MAX(((N0 + here->BSIM4nstar) / (Nl + here->BSIM4nstar)), N_MINLOG));
T4 = model->BSIM4oxideTrapDensityB * (N0 - Nl);
T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
T6 = CONSTboltz * temp * cd * cd;
T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4weff;
T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl
+ model->BSIM4oxideTrapDensityC * Nl * Nl;
T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar);
Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
return Ssi;
}
int
BSIM4noise (mode, operation, inModel, ckt, data, OnDens)
int mode, operation;
GENmodel *inModel;
CKTcircuit *ckt;
Ndata *data;
double *OnDens;
{
BSIM4model *model = (BSIM4model *)inModel;
BSIM4instance *here;
struct bsim4SizeDependParam *pParam;
char name[N_MXVLNTH];
double tempOnoise;
double tempInoise;
double noizDens[BSIM4NSRCS];
double lnNdens[BSIM4NSRCS];
double T0, T1, T2, T5, T10, T11;
double Vds, Ssi, Swi;
double tmp, gdpr, gspr, npart_theta, npart_beta, igsquare;
double m;
int i;
/* define the names of the noise sources */
static char *BSIM4nNames[BSIM4NSRCS] =
{ /* Note that we have to keep the order */
".rd", /* noise due to rd */
".rs", /* noise due to rs */
".rg", /* noise due to rgeltd */
".rbps", /* noise due to rbps */
".rbpd", /* noise due to rbpd */
".rbpb", /* noise due to rbpb */
".rbsb", /* noise due to rbsb */
".rbdb", /* noise due to rbdb */
".id", /* noise due to id */
".1overf", /* flicker (1/f) noise */
".igs", /* shot noise due to IGS */
".igd", /* shot noise due to IGD */
".igb", /* shot noise due to IGB */
"" /* total transistor noise */
};
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{ pParam = here->pParam;
switch (operation)
{ case N_OPEN:
/* see if we have to to produce a summary report */
/* if so, name all the noise generators */
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0)
{ switch (mode)
{ case N_DENS:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **) NULL);
/* we've added one more plot */
}
break;
case INT_NOIZ:
for (i = 0; i < BSIM4NSRCS; i++)
{ (void) sprintf(name, "onoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **) NULL);
/* we've added one more plot */
(void) sprintf(name, "inoise_total.%s%s",
here->BSIM4name,
BSIM4nNames[i]);
data->namelist = (IFuid *) trealloc(
(char *) data->namelist,
(data->numPlots + 1)
* sizeof(IFuid));
if (!data->namelist)
return(E_NOMEM);
(*(SPfrontEnd->IFnewUid)) (ckt,
&(data->namelist[data->numPlots++]),
(IFuid) NULL, name, UID_OTHER,
(void **)NULL);
/* we've added one more plot */
}
break;
}
}
break;
case N_CALC:
m = here->BSIM4m;
switch (mode)
{ case N_DENS:
if (model->BSIM4tnoiMod == 0)
{ if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
if (here->BSIM4grdsw > 0.0)
tmp = 1.0 / here->BSIM4grdsw; /* tmp used below */
else
tmp = 0.0;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
tmp = 0.0;
}
}
else
{ T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;
T5 *= T5;
npart_beta = model->BSIM4rnoia * (1.0 + T5
* model->BSIM4tnoia * pParam->BSIM4leff);
npart_theta = model->BSIM4rnoib * (1.0 + T5
* model->BSIM4tnoib * pParam->BSIM4leff);
if (model->BSIM4rdsMod == 0)
{ gspr = here->BSIM4sourceConductance;
gdpr = here->BSIM4drainConductance;
}
else
{ gspr = here->BSIM4gstot;
gdpr = here->BSIM4gdtot;
}
if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0)
gspr = gspr / (1.0 + npart_theta * npart_theta * gspr
/ here->BSIM4IdovVds); /* bugfix */
else
gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr
/ here->BSIM4IdovVds);
}
NevalSrc(&noizDens[BSIM4RDNOIZ],
&lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE,
here->BSIM4dNodePrime, here->BSIM4dNode,
gdpr * m);
NevalSrc(&noizDens[BSIM4RSNOIZ],
&lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE,
here->BSIM4sNodePrime, here->BSIM4sNode,
gspr * m);
if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2))
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodePrime, here->BSIM4gNodeExt,
here->BSIM4grgeltd * m);
}
else if (here->BSIM4rgateMod == 3)
{ NevalSrc(&noizDens[BSIM4RGNOIZ],
&lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,
here->BSIM4gNodeMid, here->BSIM4gNodeExt,
here->BSIM4grgeltd * m);
}
else
{ noizDens[BSIM4RGNOIZ] = 0.0;
lnNdens[BSIM4RGNOIZ] =
log(MAX(noizDens[BSIM4RGNOIZ], N_MINLOG));
}
if (here->BSIM4rbodyMod)
{ 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);
}
else
{ noizDens[BSIM4RBPSNOIZ] = noizDens[BSIM4RBPDNOIZ] = 0.0;
noizDens[BSIM4RBPBNOIZ] = 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[BSIM4RBPBNOIZ] =
log(MAX(noizDens[BSIM4RBPBNOIZ], N_MINLOG));
lnNdens[BSIM4RBSBNOIZ] =
log(MAX(noizDens[BSIM4RBSBNOIZ], N_MINLOG));
lnNdens[BSIM4RBDBNOIZ] =
log(MAX(noizDens[BSIM4RBDBNOIZ], N_MINLOG));
}
switch(model->BSIM4tnoiMod)
{ case 0:
T0 = m * here->BSIM4ueff * fabs(here->BSIM4qinv);
T1 = T0 * tmp + pParam->BSIM4leff
* pParam->BSIM4leff;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime,
(T0 / T1) * model->BSIM4ntnoi);
break;
case 1:
T0 = m * (here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds);
T0 *= T0;
igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds;
T1 = npart_beta * (here->BSIM4gm
+ here->BSIM4gmbs) + here->BSIM4gds;
T2 = T1 * T1 / here->BSIM4IdovVds;
NevalSrc(&noizDens[BSIM4IDNOIZ],
&lnNdens[BSIM4IDNOIZ], ckt,
THERMNOISE, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (T2 - igsquare));
break;
}
NevalSrc(&noizDens[BSIM4FLNOIZ], (double*) NULL,
ckt, N_GAIN, here->BSIM4dNodePrime,
here->BSIM4sNodePrime, (double) 0.0);
switch(model->BSIM4fnoiMod)
{ case 0:
noizDens[BSIM4FLNOIZ] *= m * model->BSIM4kf
* exp(model->BSIM4af
* log(MAX(fabs(here->BSIM4cd),
N_MINLOG)))
/ (pow(data->freq, model->BSIM4ef)
* pParam->BSIM4leff
* pParam->BSIM4leff
* model->BSIM4coxe);
break;
case 1:
Vds = *(ckt->CKTstates[0] + here->BSIM4vds);
if (Vds < 0.0)
Vds = -Vds;
Ssi = Eval1ovFNoise(Vds, model, here,
data->freq, ckt->CKTtemp);
T10 = model->BSIM4oxideTrapDensityA
* CONSTboltz * ckt->CKTtemp;
T11 = pParam->BSIM4weff * 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] *= m * (Ssi * Swi) / T1;
else
noizDens[BSIM4FLNOIZ] *= 0.0;
break;
}
lnNdens[BSIM4FLNOIZ] =
log(MAX(noizDens[BSIM4FLNOIZ], N_MINLOG));
if(here->BSIM4mode >= 0) { /* bugfix */
NevalSrc(&noizDens[BSIM4IGSNOIZ],
&lnNdens[BSIM4IGSNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4sNodePrime,
m * (here->BSIM4Igs + here->BSIM4Igcs));
NevalSrc(&noizDens[BSIM4IGDNOIZ],
&lnNdens[BSIM4IGDNOIZ], ckt, SHOTNOISE,
here->BSIM4gNodePrime, here->BSIM4dNodePrime,
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,
m * here->BSIM4Igb);
noizDens[BSIM4TOTNOIZ] = noizDens[BSIM4RDNOIZ]
+ noizDens[BSIM4RSNOIZ] + noizDens[BSIM4RGNOIZ]
+ noizDens[BSIM4RBPSNOIZ] + noizDens[BSIM4RBPDNOIZ]
+ noizDens[BSIM4RBPBNOIZ]
+ noizDens[BSIM4RBSBNOIZ] + noizDens[BSIM4RBDBNOIZ]
+ noizDens[BSIM4IDNOIZ] + noizDens[BSIM4FLNOIZ]
+ noizDens[BSIM4IGSNOIZ] + noizDens[BSIM4IGDNOIZ]
+ noizDens[BSIM4IGBNOIZ];
lnNdens[BSIM4TOTNOIZ] =
log(MAX(noizDens[BSIM4TOTNOIZ], N_MINLOG));
*OnDens += noizDens[BSIM4TOTNOIZ];
if (data->delFreq == 0.0)
{ /* if we haven't done any previous
integration, we need to initialize our
"history" variables.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
}
/* clear out our integration variables
if it's the first pass
*/
if (data->freq ==
((NOISEAN*) ckt->CKTcurJob)->NstartFreq)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ here->BSIM4nVar[OUTNOIZ][i] = 0.0;
here->BSIM4nVar[INNOIZ][i] = 0.0;
}
}
}
else
{ /* data->delFreq != 0.0,
we have to integrate.
*/
for (i = 0; i < BSIM4NSRCS; i++)
{ if (i != BSIM4TOTNOIZ)
{ tempOnoise = Nintegrate(noizDens[i],
lnNdens[i],
here->BSIM4nVar[LNLSTDENS][i],
data);
tempInoise = Nintegrate(noizDens[i]
* data->GainSqInv, lnNdens[i]
+ data->lnGainInv,
here->BSIM4nVar[LNLSTDENS][i]
+ data->lnGainInv, data);
here->BSIM4nVar[LNLSTDENS][i] =
lnNdens[i];
data->outNoiz += tempOnoise;
data->inNoise += tempInoise;
if (((NOISEAN*)
ckt->CKTcurJob)->NStpsSm != 0)
{ here->BSIM4nVar[OUTNOIZ][i]
+= tempOnoise;
here->BSIM4nVar[OUTNOIZ][BSIM4TOTNOIZ]
+= tempOnoise;
here->BSIM4nVar[INNOIZ][i]
+= tempInoise;
here->BSIM4nVar[INNOIZ][BSIM4TOTNOIZ]
+= tempInoise;
}
}
}
}
if (data->prtSummary)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ /* print a summary report */
data->outpVector[data->outNumber++]
= noizDens[i];
}
}
break;
case INT_NOIZ:
/* already calculated, just output */
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0)
{ for (i = 0; i < BSIM4NSRCS; i++)
{ data->outpVector[data->outNumber++]
= here->BSIM4nVar[OUTNOIZ][i];
data->outpVector[data->outNumber++]
= here->BSIM4nVar[INNOIZ][i];
}
}
break;
}
break;
case N_CLOSE:
/* do nothing, the main calling routine will close */
return (OK);
break; /* the plots */
} /* switch (operation) */
} /* for here */
} /* for model */
return(OK);
}

309
src/spicelib/devices/bsim4/b4par.c

@ -1,145 +1,164 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4par.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include <stdio.h>
#include "ifsim.h"
#include "bsim4def.h"
#include "sperror.h"
int
BSIM4param(param,value,inst,select)
int param;
IFvalue *value;
GENinstance *inst;
IFvalue *select;
{
BSIM4instance *here = (BSIM4instance*)inst;
switch(param)
{ case BSIM4_W:
here->BSIM4w = value->rValue;
here->BSIM4wGiven = TRUE;
break;
case BSIM4_L:
here->BSIM4l = value->rValue;
here->BSIM4lGiven = TRUE;
break;
case BSIM4_NF:
here->BSIM4nf = value->rValue;
here->BSIM4nfGiven = TRUE;
break;
case BSIM4_MIN:
here->BSIM4min = value->iValue;
here->BSIM4minGiven = TRUE;
break;
case BSIM4_AS:
here->BSIM4sourceArea = value->rValue;
here->BSIM4sourceAreaGiven = TRUE;
break;
case BSIM4_AD:
here->BSIM4drainArea = value->rValue;
here->BSIM4drainAreaGiven = TRUE;
break;
case BSIM4_PS:
here->BSIM4sourcePerimeter = value->rValue;
here->BSIM4sourcePerimeterGiven = TRUE;
break;
case BSIM4_PD:
here->BSIM4drainPerimeter = value->rValue;
here->BSIM4drainPerimeterGiven = TRUE;
break;
case BSIM4_NRS:
here->BSIM4sourceSquares = value->rValue;
here->BSIM4sourceSquaresGiven = TRUE;
break;
case BSIM4_NRD:
here->BSIM4drainSquares = value->rValue;
here->BSIM4drainSquaresGiven = TRUE;
break;
case BSIM4_OFF:
here->BSIM4off = value->iValue;
break;
case BSIM4_RBSB:
here->BSIM4rbsb = value->rValue;
here->BSIM4rbsbGiven = TRUE;
break;
case BSIM4_RBDB:
here->BSIM4rbdb = value->rValue;
here->BSIM4rbdbGiven = TRUE;
break;
case BSIM4_RBPB:
here->BSIM4rbpb = value->rValue;
here->BSIM4rbpbGiven = TRUE;
break;
case BSIM4_RBPS:
here->BSIM4rbps = value->rValue;
here->BSIM4rbpsGiven = TRUE;
break;
case BSIM4_RBPD:
here->BSIM4rbpd = value->rValue;
here->BSIM4rbpdGiven = TRUE;
break;
case BSIM4_TRNQSMOD:
here->BSIM4trnqsMod = value->iValue;
here->BSIM4trnqsModGiven = TRUE;
break;
case BSIM4_ACNQSMOD:
here->BSIM4acnqsMod = value->iValue;
here->BSIM4acnqsModGiven = TRUE;
break;
case BSIM4_RBODYMOD:
here->BSIM4rbodyMod = value->iValue;
here->BSIM4rbodyModGiven = TRUE;
break;
case BSIM4_RGATEMOD:
here->BSIM4rgateMod = value->iValue;
here->BSIM4rgateModGiven = TRUE;
break;
case BSIM4_GEOMOD:
here->BSIM4geoMod = value->iValue;
here->BSIM4geoModGiven = TRUE;
break;
case BSIM4_RGEOMOD:
here->BSIM4rgeoMod = value->iValue;
here->BSIM4rgeoModGiven = TRUE;
break;
case BSIM4_IC_VDS:
here->BSIM4icVDS = value->rValue;
here->BSIM4icVDSGiven = TRUE;
break;
case BSIM4_IC_VGS:
here->BSIM4icVGS = value->rValue;
here->BSIM4icVGSGiven = TRUE;
break;
case BSIM4_IC_VBS:
here->BSIM4icVBS = value->rValue;
here->BSIM4icVBSGiven = TRUE;
break;
case BSIM4_IC:
switch(value->v.numValue)
{ case 3:
here->BSIM4icVBS = *(value->v.vec.rVec+2);
here->BSIM4icVBSGiven = TRUE;
case 2:
here->BSIM4icVGS = *(value->v.vec.rVec+1);
here->BSIM4icVGSGiven = TRUE;
case 1:
here->BSIM4icVDS = *(value->v.vec.rVec);
here->BSIM4icVDSGiven = TRUE;
break;
default:
return(E_BADPARM);
}
break;
default:
return(E_BADPARM);
}
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4par.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, 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.
**********/
#include "ngspice.h"
#include "ifsim.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4param(param,value,inst,select)
int param;
IFvalue *value;
GENinstance *inst;
IFvalue *select;
{
BSIM4instance *here = (BSIM4instance*)inst;
switch(param)
{ case BSIM4_W:
here->BSIM4w = value->rValue;
here->BSIM4wGiven = TRUE;
break;
case BSIM4_L:
here->BSIM4l = value->rValue;
here->BSIM4lGiven = TRUE;
break;
case BSIM4_M:
here->BSIM4m = value->rValue;
here->BSIM4mGiven = TRUE;
break;
case BSIM4_NF:
here->BSIM4nf = value->rValue;
here->BSIM4nfGiven = TRUE;
break;
case BSIM4_MIN:
here->BSIM4min = value->iValue;
here->BSIM4minGiven = TRUE;
break;
case BSIM4_AS:
here->BSIM4sourceArea = value->rValue;
here->BSIM4sourceAreaGiven = TRUE;
break;
case BSIM4_AD:
here->BSIM4drainArea = value->rValue;
here->BSIM4drainAreaGiven = TRUE;
break;
case BSIM4_PS:
here->BSIM4sourcePerimeter = value->rValue;
here->BSIM4sourcePerimeterGiven = TRUE;
break;
case BSIM4_PD:
here->BSIM4drainPerimeter = value->rValue;
here->BSIM4drainPerimeterGiven = TRUE;
break;
case BSIM4_NRS:
here->BSIM4sourceSquares = value->rValue;
here->BSIM4sourceSquaresGiven = TRUE;
break;
case BSIM4_NRD:
here->BSIM4drainSquares = value->rValue;
here->BSIM4drainSquaresGiven = TRUE;
break;
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_RBSB:
here->BSIM4rbsb = value->rValue;
here->BSIM4rbsbGiven = TRUE;
break;
case BSIM4_RBDB:
here->BSIM4rbdb = value->rValue;
here->BSIM4rbdbGiven = TRUE;
break;
case BSIM4_RBPB:
here->BSIM4rbpb = value->rValue;
here->BSIM4rbpbGiven = TRUE;
break;
case BSIM4_RBPS:
here->BSIM4rbps = value->rValue;
here->BSIM4rbpsGiven = TRUE;
break;
case BSIM4_RBPD:
here->BSIM4rbpd = value->rValue;
here->BSIM4rbpdGiven = TRUE;
break;
case BSIM4_TRNQSMOD:
here->BSIM4trnqsMod = value->iValue;
here->BSIM4trnqsModGiven = TRUE;
break;
case BSIM4_ACNQSMOD:
here->BSIM4acnqsMod = value->iValue;
here->BSIM4acnqsModGiven = TRUE;
break;
case BSIM4_RBODYMOD:
here->BSIM4rbodyMod = value->iValue;
here->BSIM4rbodyModGiven = TRUE;
break;
case BSIM4_RGATEMOD:
here->BSIM4rgateMod = value->iValue;
here->BSIM4rgateModGiven = TRUE;
break;
case BSIM4_GEOMOD:
here->BSIM4geoMod = value->iValue;
here->BSIM4geoModGiven = TRUE;
break;
case BSIM4_RGEOMOD:
here->BSIM4rgeoMod = value->iValue;
here->BSIM4rgeoModGiven = TRUE;
break;
case BSIM4_IC_VDS:
here->BSIM4icVDS = value->rValue;
here->BSIM4icVDSGiven = TRUE;
break;
case BSIM4_IC_VGS:
here->BSIM4icVGS = value->rValue;
here->BSIM4icVGSGiven = TRUE;
break;
case BSIM4_IC_VBS:
here->BSIM4icVBS = value->rValue;
here->BSIM4icVBSGiven = TRUE;
break;
case BSIM4_IC:
switch(value->v.numValue)
{ case 3:
here->BSIM4icVBS = *(value->v.vec.rVec+2);
here->BSIM4icVBSGiven = TRUE;
case 2:
here->BSIM4icVGS = *(value->v.vec.rVec+1);
here->BSIM4icVGSGiven = TRUE;
case 1:
here->BSIM4icVDS = *(value->v.vec.rVec);
here->BSIM4icVDSGiven = TRUE;
break;
default:
return(E_BADPARM);
}
break;
default:
return(E_BADPARM);
}
return(OK);
}

1516
src/spicelib/devices/bsim4/b4pzld.c
File diff suppressed because it is too large
View File

3595
src/spicelib/devices/bsim4/b4set.c
File diff suppressed because it is too large
View File

3211
src/spicelib/devices/bsim4/b4temp.c
File diff suppressed because it is too large
View File

118
src/spicelib/devices/bsim4/b4trunc.c

@ -1,60 +1,58 @@
/**** BSIM4.2.1, Released by Xuemei Xi 10/05/2001 ****/
/**********
* Copyright 2001 Regents of the University of California. All rights reserved.
* File: b4trunc.c of BSIM4.2.1.
* Author: 2000 Weidong Liu
* Authors: Xuemei Xi, Kanyu M. Cao, Hui Wan, Mansun Chan, 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"
int
BSIM4trunc(inModel,ckt,timeStep)
GENmodel *inModel;
CKTcircuit *ckt;
double *timeStep;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
#ifdef STEPDEBUG
double debugtemp;
#endif /* STEPDEBUG */
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{
if (here->BSIM4owner != ARCHme) continue;
#ifdef STEPDEBUG
debugtemp = *timeStep;
#endif /* STEPDEBUG */
CKTterr(here->BSIM4qb,ckt,timeStep);
CKTterr(here->BSIM4qg,ckt,timeStep);
CKTterr(here->BSIM4qd,ckt,timeStep);
if (here->BSIM4trnqsMod)
CKTterr(here->BSIM4qcdump,ckt,timeStep);
if (here->BSIM4rbodyMod)
{ CKTterr(here->BSIM4qbs,ckt,timeStep);
CKTterr(here->BSIM4qbd,ckt,timeStep);
}
if (here->BSIM4rgateMod == 3)
CKTterr(here->BSIM4qgmid,ckt,timeStep);
#ifdef STEPDEBUG
if(debugtemp != *timeStep)
{ printf("device %s reduces step from %g to %g\n",
here->BSIM4name,debugtemp,*timeStep);
}
#endif /* STEPDEBUG */
}
}
return(OK);
}
/**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/
/**********
* Copyright 2004 Regents of the University of California. All rights reserved.
* File: b4trunc.c of BSIM4.4.0.
* Author: 2000 Weidong Liu
* Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu.
* Project Director: Prof. Chenming Hu.
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include "bsim4def.h"
#include "sperror.h"
#include "suffix.h"
int
BSIM4trunc(inModel,ckt,timeStep)
GENmodel *inModel;
CKTcircuit *ckt;
double *timeStep;
{
BSIM4model *model = (BSIM4model*)inModel;
BSIM4instance *here;
#ifdef STEPDEBUG
double debugtemp;
#endif /* STEPDEBUG */
for (; model != NULL; model = model->BSIM4nextModel)
{ for (here = model->BSIM4instances; here != NULL;
here = here->BSIM4nextInstance)
{
if (here->BSIM4owner != ARCHme) continue;
#ifdef STEPDEBUG
debugtemp = *timeStep;
#endif /* STEPDEBUG */
CKTterr(here->BSIM4qb,ckt,timeStep);
CKTterr(here->BSIM4qg,ckt,timeStep);
CKTterr(here->BSIM4qd,ckt,timeStep);
if (here->BSIM4trnqsMod)
CKTterr(here->BSIM4qcdump,ckt,timeStep);
if (here->BSIM4rbodyMod)
{ CKTterr(here->BSIM4qbs,ckt,timeStep);
CKTterr(here->BSIM4qbd,ckt,timeStep);
}
if (here->BSIM4rgateMod == 3)
CKTterr(here->BSIM4qgmid,ckt,timeStep);
#ifdef STEPDEBUG
if(debugtemp != *timeStep)
{ printf("device %s reduces step from %g to %g\n",
here->BSIM4name,debugtemp,*timeStep);
}
#endif /* STEPDEBUG */
}
}
return(OK);
}

5580
src/spicelib/devices/bsim4/bsim4def.h
File diff suppressed because it is too large
View File

27
src/spicelib/devices/bsim4/bsim4ext.h

@ -1,11 +1,11 @@
/********** /**********
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: 2000 Weidong Liu
Author: 2001 Xuemei Xi
Author: 2001- Xuemei Xi
File: bsim4ext.h File: bsim4ext.h
**********/ **********/
#ifdef __STDC__
extern int BSIM4acLoad(GENmodel *,CKTcircuit*); extern int BSIM4acLoad(GENmodel *,CKTcircuit*);
extern int BSIM4ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); extern int BSIM4ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*);
extern int BSIM4convTest(GENmodel *,CKTcircuit*); extern int BSIM4convTest(GENmodel *,CKTcircuit*);
@ -30,25 +30,4 @@ extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM4unsetup(GENmodel*,CKTcircuit*); 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 */

163
src/spicelib/devices/bsim4/bsim4init.c

@ -1,80 +1,83 @@
#include <config.h>
#include <devdefs.h>
#include "bsim4itf.h"
#include "bsim4ext.h"
#include "bsim4init.h"
SPICEdev BSIM4info = {
{
"BSIM4",
"Berkeley Short Channel IGFET Model-4",
&BSIM4nSize,
&BSIM4nSize,
BSIM4names,
&BSIM4pTSize,
BSIM4pTable,
&BSIM4mPTSize,
BSIM4mPTable,
#ifdef XSPICE
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
/*--------------------------- End of SDB fix -------------------------*/
#endif
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
};
SPICEdev *
get_bsim4_info(void)
{
return &BSIM4info;
}
#include "config.h"
#include "devdefs.h"
#include "bsim4itf.h"
#include "bsim4ext.h"
#include "bsim4init.h"
SPICEdev BSIM4info = {
{
"BSIM4",
"Berkeley Short Channel IGFET Model-4",
&BSIM4nSize,
&BSIM4nSize,
BSIM4names,
&BSIM4pTSize,
BSIM4pTable,
&BSIM4mPTSize,
BSIM4mPTable,
#ifdef XSPICE
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
0, /* This is a SPICE device, it has no MIF info data */
NULL, /* This is a SPICE device, it has no MIF info data */
/*--------------------------- End of SDB fix -------------------------*/
#endif
DEV_DEFAULT
},
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 */
};
SPICEdev *
get_bsim4_info(void)
{
return &BSIM4info;
}

26
src/spicelib/devices/bsim4/bsim4init.h

@ -1,13 +1,13 @@
#ifndef _BSIM4INIT_H
#define _BSIM4INIT_H
extern IFparm BSIM4pTable[ ];
extern IFparm BSIM4mPTable[ ];
extern char *BSIM4names[ ];
extern int BSIM4pTSize;
extern int BSIM4mPTSize;
extern int BSIM4nSize;
extern int BSIM4iSize;
extern int BSIM4mSize;
#endif
#ifndef _BSIM4INIT_H
#define _BSIM4INIT_H
extern IFparm BSIM4pTable[ ];
extern IFparm BSIM4mPTable[ ];
extern char *BSIM4names[ ];
extern int BSIM4pTSize;
extern int BSIM4mPTSize;
extern int BSIM4nSize;
extern int BSIM4iSize;
extern int BSIM4mSize;
#endif

26
src/spicelib/devices/bsim4/bsim4itf.h

@ -1,13 +1,13 @@
/**********
Copyright 2001 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu.
Author: 2001 Xuemei Xi
File: bsim4itf.h
**********/
#ifndef DEV_BSIM4
#define DEV_BSIM4
SPICEdev *get_bsim4_info(void);
#endif
/**********
Copyright 2004 Regents of the University of California. All rights reserved.
Author: 2000 Weidong Liu.
Author: 2001- Xuemei Xi
File: bsim4itf.h
**********/
#ifndef DEV_BSIM4
#define DEV_BSIM4
SPICEdev *get_bsim4_info(void);
#endif
Loading…
Cancel
Save