devices/bsim3: apply Area Calculation Method (ACM) to the bsim3v3.3 model

This commit is contained in:
dwarning 2013-05-21 16:33:57 +02:00 committed by rlar
parent c7c89c28a9
commit 708fcbaed1
10 changed files with 290 additions and 8 deletions

View File

@ -26,6 +26,7 @@ IOP( "nrs", BSIM3_NRS, IF_REAL , "Number of squares in source"),
IOP( "off", BSIM3_OFF, IF_FLAG , "Device is initially off"),
IOP( "nqsmod", BSIM3_NQSMOD, IF_INTEGER, "Non-quasi-static model selector"),
IOP( "acnqsmod", BSIM3_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
IOP( "geo", BSIM3_GEO, IF_INTEGER, "ACM model drain/source connection"),
IOP( "delvto", BSIM3_DELVTO, IF_REAL, "Zero bias threshold voltage variation"),
IOP( "mulu0", BSIM3_MULU0, IF_REAL, "Low field mobility multiplier"),
IP( "ic", BSIM3_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"),
@ -66,6 +67,8 @@ IOP( "capmod", BSIM3_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"),
IOP( "mobmod", BSIM3_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"),
IOP( "noimod", BSIM3_MOD_NOIMOD, IF_INTEGER, "Noise model selector"),
IOP( "acnqsmod", BSIM3_MOD_ACNQSMOD, IF_INTEGER, "AC NQS model selector"),
IOP( "acm", BSIM3_MOD_ACMMOD, IF_INTEGER, "Area calculation method selector"),
IOP( "calcacm", BSIM3_MOD_CALCACM, IF_INTEGER, "Area calculation method ACM=12"),
IOP( "paramchk", BSIM3_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"),
IOP( "binunit", BSIM3_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"),
IOP( "version", BSIM3_MOD_VERSION, IF_STRING, " parameter for model version"),
@ -210,6 +213,15 @@ IOP( "cle", BSIM3_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"),
IOP( "dwc", BSIM3_MOD_DWC, IF_REAL, "Delta W for C-V model"),
IOP( "dlc", BSIM3_MOD_DLC, IF_REAL, "Delta L for C-V model"),
IOP( "hdif", BSIM3_MOD_HDIF, IF_REAL, "ACM Parameter: Distance Gate - contact"),
IOP( "ldif", BSIM3_MOD_LDIF, IF_REAL, "ACM Parameter: Length of LDD Gate-Source/Drain"),
IOP( "ld", BSIM3_MOD_LD, IF_REAL, "ACM Parameter: Length of LDD under Gate"),
IOP( "rd", BSIM3_MOD_RD, IF_REAL, "ACM Parameter: Resistance of LDD drain side"),
IOP( "rs", BSIM3_MOD_RS, IF_REAL, "ACM Parameter: Resistance of LDD source side"),
IOP( "rdc", BSIM3_MOD_RDC, IF_REAL, "ACM Parameter: Resistance contact drain side"),
IOP( "rsc", BSIM3_MOD_RSC, IF_REAL, "ACM Parameter: Resistance contact source side"),
IOP( "wmlt", BSIM3_MOD_WMLT, IF_REAL, "ACM Parameter: Width shrink factor"),
IOP( "alpha0", BSIM3_MOD_ALPHA0, IF_REAL, "substrate current model parameter"),
IOP( "alpha1", BSIM3_MOD_ALPHA1, IF_REAL, "substrate current model parameter"),
IOP( "beta0", BSIM3_MOD_BETA0, IF_REAL, "substrate current model parameter"),

View File

@ -65,6 +65,9 @@ BSIM3instance *here = (BSIM3instance*)inst;
case BSIM3_ACNQSMOD:
value->iValue = here->BSIM3acnqsMod;
return(OK);
case BSIM3_GEO:
value->iValue = here->BSIM3geo;
return(OK);
case BSIM3_DELVTO:
value->rValue = here->BSIM3delvto;
return(OK);

View File

@ -175,6 +175,8 @@ FILE *fplog;
printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2);
}
/* ACM model */
if (model->BSIM3acmMod == 0) {
if (model->BSIM3unitLengthSidewallJctCap > 0.0 ||
model->BSIM3unitLengthGateSidewallJctCap > 0.0)
{
@ -191,6 +193,14 @@ FILE *fplog;
here->BSIM3sourcePerimeter);
}
}
}
if ((model->BSIM3calcacm > 0) && (model->BSIM3acmMod != 12))
{ fprintf(fplog, "Warning: CALCACM = %d is wrong. Set back to 0.\n",
model->BSIM3calcacm);
printf("Warning: CALCACM = %d is wrong. Set back to 0.\n", model->BSIM3calcacm);
model->BSIM3calcacm = 0;
}
if (pParam->BSIM3noff < 0.1)
{ fprintf(fplog, "Warning: Noff = %g is too small.\n",

View File

@ -378,6 +378,9 @@ for (; model != NULL; model = model->BSIM3nextModel)
/* Source/drain junction diode DC model begins */
Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff;
/* acm model */
if (model->BSIM3acmMod == 0)
{
if ((here->BSIM3sourceArea <= 0.0) && (here->BSIM3sourcePerimeter <= 0.0))
{ SourceSatCurrent = 1.0e-14;
}
@ -396,6 +399,34 @@ for (; model != NULL; model = model->BSIM3nextModel)
+ here->BSIM3drainPerimeter
* model->BSIM3jctSidewallTempSatCurDensity;
}
}
else
{
error = ACM_saturationCurrents(
model->BSIM3acmMod,
model->BSIM3calcacm,
here->BSIM3geo,
model->BSIM3hdif,
model->BSIM3wmlt,
here->BSIM3w,
model->BSIM3xw,
model->BSIM3jctTempSatCurDensity,
model->BSIM3jctSidewallTempSatCurDensity,
here->BSIM3drainAreaGiven,
here->BSIM3drainArea,
here->BSIM3drainPerimeterGiven,
here->BSIM3drainPerimeter,
here->BSIM3sourceAreaGiven,
here->BSIM3sourceArea,
here->BSIM3sourcePerimeterGiven,
here->BSIM3sourcePerimeter,
&DrainSatCurrent,
&SourceSatCurrent
);
if (error)
return(error);
}
if (SourceSatCurrent <= 0.0)
{ here->BSIM3gbs = ckt->CKTgmin;
here->BSIM3cbs = here->BSIM3gbs * vbs;
@ -2237,6 +2268,8 @@ finished:
along gate side
*/
if (model->BSIM3acmMod == 0)
{
czbd = model->BSIM3unitAreaTempJctCap * here->BSIM3drainArea; /*bug fix */
czbs = model->BSIM3unitAreaTempJctCap * here->BSIM3sourceArea;
if (here->BSIM3drainPerimeter < pParam->BSIM3weff)
@ -2265,6 +2298,36 @@ finished:
czbsswg = model->BSIM3unitLengthGateSidewallTempJctCap
* pParam->BSIM3weff;
}
} else {
error = ACM_junctionCapacitances(
model->BSIM3acmMod,
model->BSIM3calcacm,
here->BSIM3geo,
model->BSIM3hdif,
model->BSIM3wmlt,
here->BSIM3w,
model->BSIM3xw,
here->BSIM3drainAreaGiven,
here->BSIM3drainArea,
here->BSIM3drainPerimeterGiven,
here->BSIM3drainPerimeter,
here->BSIM3sourceAreaGiven,
here->BSIM3sourceArea,
here->BSIM3sourcePerimeterGiven,
here->BSIM3sourcePerimeter,
model->BSIM3unitAreaTempJctCap,
model->BSIM3unitLengthSidewallTempJctCap,
model->BSIM3unitLengthGateSidewallJctCap,
&czbd,
&czbdsw,
&czbdswg,
&czbs,
&czbssw,
&czbsswg
);
if (error)
return(error);
}
MJ = model->BSIM3bulkJctBotGradingCoeff;
MJSW = model->BSIM3bulkJctSideGradingCoeff;

View File

@ -46,6 +46,12 @@ IFvalue *value)
case BSIM3_MOD_ACNQSMOD:
value->iValue = model->BSIM3acnqsMod;
return(OK);
case BSIM3_MOD_ACMMOD:
value->iValue = model->BSIM3acmMod;
return(OK);
case BSIM3_MOD_CALCACM:
value->iValue = model->BSIM3calcacm;
return(OK);
case BSIM3_MOD_VERSION :
value->sValue = model->BSIM3version;
return(OK);
@ -337,6 +343,32 @@ IFvalue *value)
value->rValue = model->BSIM3tpbswg;
return(OK);
/* ACM model */
case BSIM3_MOD_HDIF:
value->rValue = model->BSIM3hdif;
return(OK);
case BSIM3_MOD_LDIF:
value->rValue = model->BSIM3ldif;
return(OK);
case BSIM3_MOD_LD:
value->rValue = model->BSIM3ld;
return(OK);
case BSIM3_MOD_RD:
value->rValue = model->BSIM3rd;
return(OK);
case BSIM3_MOD_RS:
value->rValue = model->BSIM3rs;
return(OK);
case BSIM3_MOD_RDC:
value->rValue = model->BSIM3rdc;
return(OK);
case BSIM3_MOD_RSC:
value->rValue = model->BSIM3rsc;
return(OK);
case BSIM3_MOD_WMLT:
value->rValue = model->BSIM3wmlt;
return(OK);
/* Length dependence */
case BSIM3_MOD_LCDSC :
value->rValue = model->BSIM3lcdsc;

View File

@ -39,6 +39,14 @@ GENmodel *inMod)
mod->BSIM3capMod = value->iValue;
mod->BSIM3capModGiven = TRUE;
break;
case BSIM3_MOD_ACMMOD:
mod->BSIM3acmMod = value->iValue;
mod->BSIM3acmModGiven = TRUE;
break;
case BSIM3_MOD_CALCACM:
mod->BSIM3calcacm = value->iValue;
mod->BSIM3calcacmGiven = TRUE;
break;
case BSIM3_MOD_NOIMOD :
mod->BSIM3noiMod = value->iValue;
mod->BSIM3noiModGiven = TRUE;
@ -438,6 +446,40 @@ GENmodel *inMod)
mod->BSIM3tpbswgGiven = TRUE;
break;
/* acm model */
case BSIM3_MOD_HDIF:
mod->BSIM3hdif = value->rValue;
mod->BSIM3hdifGiven = TRUE;
break;
case BSIM3_MOD_LDIF:
mod->BSIM3ldif = value->rValue;
mod->BSIM3ldifGiven = TRUE;
break;
case BSIM3_MOD_LD:
mod->BSIM3ld = value->rValue;
mod->BSIM3ldGiven = TRUE;
break;
case BSIM3_MOD_RD:
mod->BSIM3rd = value->rValue;
mod->BSIM3rdGiven = TRUE;
break;
case BSIM3_MOD_RS:
mod->BSIM3rs = value->rValue;
mod->BSIM3rsGiven = TRUE;
break;
case BSIM3_MOD_RDC:
mod->BSIM3rdc = value->rValue;
mod->BSIM3rdcGiven = TRUE;
break;
case BSIM3_MOD_RSC:
mod->BSIM3rsc = value->rValue;
mod->BSIM3rscGiven = TRUE;
break;
case BSIM3_MOD_WMLT:
mod->BSIM3wmlt = value->rValue;
mod->BSIM3wmltGiven = TRUE;
break;
/* Length dependence */
case BSIM3_MOD_LCDSC :
mod->BSIM3lcdsc = value->rValue;

View File

@ -91,6 +91,10 @@ IFvalue *select)
here->BSIM3acnqsMod = value->iValue;
here->BSIM3acnqsModGiven = TRUE;
break;
case BSIM3_GEO:
here->BSIM3geo = value->iValue;
here->BSIM3geoGiven = TRUE;
break;
case BSIM3_DELVTO:
here->BSIM3delvto = value->rValue;
here->BSIM3delvtoGiven = TRUE;

View File

@ -61,6 +61,10 @@ BSIM3instance **InstArray;
model->BSIM3paramChk = 0;
if (!model->BSIM3capModGiven)
model->BSIM3capMod = 3;
if (!model->BSIM3acmModGiven)
model->BSIM3acmMod = 0;
if (!model->BSIM3calcacmGiven)
model->BSIM3calcacm = 0;
if (!model->BSIM3noiModGiven)
model->BSIM3noiMod = 1;
if (!model->BSIM3acnqsModGiven)
@ -247,6 +251,24 @@ BSIM3instance **InstArray;
if (!model->BSIM3tpbswgGiven)
model->BSIM3tpbswg = 0.0;
/* ACM model */
if (!model->BSIM3hdifGiven)
model->BSIM3hdif = 0.0;
if (!model->BSIM3ldifGiven)
model->BSIM3ldif = 0.0;
if (!model->BSIM3ldGiven)
model->BSIM3ld = 0.0;
if (!model->BSIM3rdGiven)
model->BSIM3rd = 0.0;
if (!model->BSIM3rsGiven)
model->BSIM3rs = 0.0;
if (!model->BSIM3rdcGiven)
model->BSIM3rdc = 0.0;
if (!model->BSIM3rscGiven)
model->BSIM3rsc = 0.0;
if (!model->BSIM3wmltGiven)
model->BSIM3wmlt = 1.0;
/* Length dependence */
if (!model->BSIM3lcdscGiven)
model->BSIM3lcdsc = 0.0;
@ -874,7 +896,12 @@ BSIM3instance **InstArray;
if (!here->BSIM3drainPerimeterGiven)
here->BSIM3drainPerimeter = 0.0;
if (!here->BSIM3drainSquaresGiven)
here->BSIM3drainSquares = 1.0;
{
if (model->BSIM3acmMod == 0)
here->BSIM3drainSquares = 1.0;
else
here->BSIM3drainSquares = 0.0;
}
if (!here->BSIM3delvtoGiven)
here->BSIM3delvto = 0.0;
if (!here->BSIM3mulu0Given)
@ -892,7 +919,12 @@ BSIM3instance **InstArray;
if (!here->BSIM3sourcePerimeterGiven)
here->BSIM3sourcePerimeter = 0.0;
if (!here->BSIM3sourceSquaresGiven)
here->BSIM3sourceSquares = 1.0;
{
if (model->BSIM3acmMod == 0)
here->BSIM3sourceSquares = 1.0;
else
here->BSIM3sourceSquares = 0.0;
}
if (!here->BSIM3wGiven)
here->BSIM3w = 5.0e-6;
if (!here->BSIM3nqsModGiven)
@ -905,13 +937,19 @@ BSIM3instance **InstArray;
model->BSIM3acnqsMod);
}
if (!here->BSIM3geoGiven)
here->BSIM3geo = 0;
if (!here->BSIM3mGiven)
here->BSIM3m = 1;
/* process drain series resistance */
if ((model->BSIM3sheetResistance > 0.0) &&
(here->BSIM3drainSquares > 0.0 ))
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3drainSquares > 0.0))
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
||((model->BSIM3rd > 0.0) && (model->BSIM3ldif > 0.0))
||((model->BSIM3rd > 0.0) && (model->BSIM3ld > 0.0))
||((model->BSIM3rdc > 0.0))
)
{
if(here->BSIM3dNodePrime == 0) {
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain");
@ -932,8 +970,12 @@ BSIM3instance **InstArray;
}
/* process source series resistance */
if ((model->BSIM3sheetResistance > 0.0) &&
(here->BSIM3sourceSquares > 0.0 ))
if ( ((model->BSIM3sheetResistance > 0.0) && (here->BSIM3sourceSquares > 0.0))
||((model->BSIM3sheetResistance > 0.0) && (model->BSIM3hdif > 0.0))
||((model->BSIM3rs > 0.0) && (model->BSIM3ldif > 0.0))
||((model->BSIM3rs > 0.0) && (model->BSIM3ld > 0.0))
||((model->BSIM3rsc > 0.0))
)
{
if(here->BSIM3sNodePrime == 0) {
error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source");

View File

@ -16,6 +16,7 @@
#include "bsim3def.h"
#include "ngspice/const.h"
#include "ngspice/sperror.h"
#include "ngspice/devdefs.h"
#include "ngspice/suffix.h"
#define Kb 1.3806226e-23
@ -40,7 +41,7 @@ struct bsim3SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam=NULL;
double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;
double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom;
double Nvtm, SourceSatCurrent, DrainSatCurrent;
int Size_Not_Found;
int Size_Not_Found, error;
/* loop through all the BSIM3 device models */
for (; model != NULL; model = model->BSIM3nextModel)
@ -806,10 +807,39 @@ int Size_Not_Found;
* pParam->BSIM3weffCV * pParam->BSIM3leffCV * T0);
/* process source/drain series resistance */
/* ACM model */
if (model->BSIM3acmMod == 0)
{
here->BSIM3drainConductance = model->BSIM3sheetResistance
* here->BSIM3drainSquares;
here->BSIM3sourceConductance = model->BSIM3sheetResistance
* here->BSIM3sourceSquares;
}
else /* ACM > 0 */
{
error = ACM_SourceDrainResistances(
model->BSIM3acmMod,
model->BSIM3ld,
model->BSIM3ldif,
model->BSIM3hdif,
model->BSIM3wmlt,
here->BSIM3w,
model->BSIM3xw,
model->BSIM3sheetResistance,
here->BSIM3drainSquaresGiven,
model->BSIM3rd,
model->BSIM3rdc,
here->BSIM3drainSquares,
here->BSIM3sourceSquaresGiven,
model->BSIM3rs,
model->BSIM3rsc,
here->BSIM3sourceSquares,
&(here->BSIM3drainConductance),
&(here->BSIM3sourceConductance)
);
if (error)
return(error);
}
if (here->BSIM3drainConductance > 0.0)
here->BSIM3drainConductance = 1.0
/ here->BSIM3drainConductance;

View File

@ -68,6 +68,7 @@ typedef struct sBSIM3instance
int BSIM3mode;
int BSIM3nqsMod;
int BSIM3acnqsMod;
int BSIM3geo;
/* OP point */
double BSIM3qinv;
@ -138,6 +139,7 @@ typedef struct sBSIM3instance
unsigned BSIM3icVGSGiven :1;
unsigned BSIM3nqsModGiven :1;
unsigned BSIM3acnqsModGiven :1;
unsigned BSIM3geoGiven :1;
double *BSIM3DdPtr;
double *BSIM3GgPtr;
@ -405,6 +407,8 @@ typedef struct sBSIM3model
int BSIM3mobMod;
int BSIM3capMod;
int BSIM3acmMod;
int BSIM3calcacm;
int BSIM3noiMod;
int BSIM3acnqsMod;
int BSIM3binUnit;
@ -507,6 +511,18 @@ typedef struct sBSIM3model
double BSIM3tpbsw;
double BSIM3tpbswg;
/* ACM model */
double BSIM3xl;
double BSIM3xw;
double BSIM3hdif;
double BSIM3ldif;
double BSIM3ld;
double BSIM3rd;
double BSIM3rs;
double BSIM3rdc;
double BSIM3rsc;
double BSIM3wmlt;
/* Length Dependence */
double BSIM3lcdsc;
double BSIM3lcdscb;
@ -856,6 +872,8 @@ typedef struct sBSIM3model
unsigned BSIM3mobModGiven :1;
unsigned BSIM3binUnitGiven :1;
unsigned BSIM3capModGiven :1;
unsigned BSIM3acmModGiven :1;
unsigned BSIM3calcacmGiven :1;
unsigned BSIM3paramChkGiven :1;
unsigned BSIM3noiModGiven :1;
unsigned BSIM3acnqsModGiven :1;
@ -958,6 +976,17 @@ typedef struct sBSIM3model
unsigned BSIM3tpbswGiven :1;
unsigned BSIM3tpbswgGiven :1;
/* ACM model */
unsigned BSIM3xlGiven :1;
unsigned BSIM3xwGiven :1;
unsigned BSIM3hdifGiven :1;
unsigned BSIM3ldifGiven :1;
unsigned BSIM3ldGiven :1;
unsigned BSIM3rdGiven :1;
unsigned BSIM3rsGiven :1;
unsigned BSIM3rdcGiven :1;
unsigned BSIM3rscGiven :1;
unsigned BSIM3wmltGiven :1;
/* Length dependence */
unsigned BSIM3lcdscGiven :1;
@ -1303,9 +1332,12 @@ typedef struct sBSIM3model
#define BSIM3_M 16
#define BSIM3_DELVTO 17
#define BSIM3_MULU0 18
#define BSIM3_GEO 19
/* model parameters */
#define BSIM3_MOD_CAPMOD 101
#define BSIM3_MOD_CAPMOD 100
#define BSIM3_MOD_ACMMOD 101
#define BSIM3_MOD_CALCACM 102
#define BSIM3_MOD_MOBMOD 103
#define BSIM3_MOD_NOIMOD 104
@ -1772,6 +1804,18 @@ typedef struct sBSIM3model
#define BSIM3_MOD_WWC 701
#define BSIM3_MOD_WWLC 702
/* ACM parameters */
#define BSIM3_MOD_XL 703
#define BSIM3_MOD_XW 704
#define BSIM3_MOD_HDIF 711
#define BSIM3_MOD_LDIF 712
#define BSIM3_MOD_LD 713
#define BSIM3_MOD_RD 714
#define BSIM3_MOD_RS 715
#define BSIM3_MOD_RDC 716
#define BSIM3_MOD_RSC 717
#define BSIM3_MOD_WMLT 718
/* device questions */
#define BSIM3_DNODE 751
#define BSIM3_GNODE 752