From e725cd25d048ddf68d5ef734073e9287ed711717 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 21 May 2013 16:33:57 +0200 Subject: [PATCH] Area Calculation Method (ACM) applied to bsim3v3.3 model --- src/spicelib/devices/bsim3/b3.c | 12 +++ src/spicelib/devices/bsim3/b3ask.c | 3 + src/spicelib/devices/bsim3/b3check.c | 37 ++++--- src/spicelib/devices/bsim3/b3ld.c | 145 ++++++++++++++++++-------- src/spicelib/devices/bsim3/b3mask.c | 32 ++++++ src/spicelib/devices/bsim3/b3mpar.c | 42 ++++++++ src/spicelib/devices/bsim3/b3par.c | 4 + src/spicelib/devices/bsim3/b3set.c | 55 ++++++++-- src/spicelib/devices/bsim3/b3temp.c | 40 ++++++- src/spicelib/devices/bsim3/bsim3def.h | 46 +++++++- 10 files changed, 348 insertions(+), 68 deletions(-) diff --git a/src/spicelib/devices/bsim3/b3.c b/src/spicelib/devices/bsim3/b3.c index 35a39c44e..babeb7658 100644 --- a/src/spicelib/devices/bsim3/b3.c +++ b/src/spicelib/devices/bsim3/b3.c @@ -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"), diff --git a/src/spicelib/devices/bsim3/b3ask.c b/src/spicelib/devices/bsim3/b3ask.c index be0631acc..21c1775b6 100644 --- a/src/spicelib/devices/bsim3/b3ask.c +++ b/src/spicelib/devices/bsim3/b3ask.c @@ -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); diff --git a/src/spicelib/devices/bsim3/b3check.c b/src/spicelib/devices/bsim3/b3check.c index d2551b22f..2ec2aad54 100644 --- a/src/spicelib/devices/bsim3/b3check.c +++ b/src/spicelib/devices/bsim3/b3check.c @@ -175,22 +175,31 @@ FILE *fplog; printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM3pscbe2); } - if (model->BSIM3unitLengthSidewallJctCap > 0.0 || - model->BSIM3unitLengthGateSidewallJctCap > 0.0) - { - if (here->BSIM3drainPerimeter < pParam->BSIM3weff) - { fprintf(fplog, "Warning: Pd = %g is less than W.\n", - here->BSIM3drainPerimeter); - printf("Warning: Pd = %g is less than W.\n", - here->BSIM3drainPerimeter); + /* ACM model */ + if (model->BSIM3acmMod == 0) { + if (model->BSIM3unitLengthSidewallJctCap > 0.0 || + model->BSIM3unitLengthGateSidewallJctCap > 0.0) + { + if (here->BSIM3drainPerimeter < pParam->BSIM3weff) + { fprintf(fplog, "Warning: Pd = %g is less than W.\n", + here->BSIM3drainPerimeter); + printf("Warning: Pd = %g is less than W.\n", + here->BSIM3drainPerimeter); + } + if (here->BSIM3sourcePerimeter < pParam->BSIM3weff) + { fprintf(fplog, "Warning: Ps = %g is less than W.\n", + here->BSIM3sourcePerimeter); + printf("Warning: Ps = %g is less than W.\n", + here->BSIM3sourcePerimeter); + } + } } - if (here->BSIM3sourcePerimeter < pParam->BSIM3weff) - { fprintf(fplog, "Warning: Ps = %g is less than W.\n", - here->BSIM3sourcePerimeter); - printf("Warning: Ps = %g is less than W.\n", - here->BSIM3sourcePerimeter); + if ((model->BSIM3calcacm > 0) && (model->BSIM3acmMod != 12)) + { fprintf(fplog, "Warning: CALCACM = %d is wrong. Set back to 0.\n", + model->BSIM3calcacm); + printf("Warning: CALCACM = %d is wrong. Set back to 0.\n", model->BSIM3calcacm); + model->BSIM3calcacm = 0; } - } if (pParam->BSIM3noff < 0.1) { fprintf(fplog, "Warning: Noff = %g is too small.\n", diff --git a/src/spicelib/devices/bsim3/b3ld.c b/src/spicelib/devices/bsim3/b3ld.c index 2cf4bcd4e..8d352d607 100644 --- a/src/spicelib/devices/bsim3/b3ld.c +++ b/src/spicelib/devices/bsim3/b3ld.c @@ -378,15 +378,55 @@ for (; model != NULL; model = model->BSIM3nextModel) /* Source/drain junction diode DC model begins */ Nvtm = model->BSIM3vtm * model->BSIM3jctEmissionCoeff; - if ((here->BSIM3sourceArea <= 0.0) && (here->BSIM3sourcePerimeter <= 0.0)) - { SourceSatCurrent = 1.0e-14; + /* acm model */ + if (model->BSIM3acmMod == 0) + { + if ((here->BSIM3sourceArea <= 0.0) && (here->BSIM3sourcePerimeter <= 0.0)) + { SourceSatCurrent = 1.0e-14; + } + else + { SourceSatCurrent = here->BSIM3sourceArea + * model->BSIM3jctTempSatCurDensity + + here->BSIM3sourcePerimeter + * model->BSIM3jctSidewallTempSatCurDensity; + } + if ((here->BSIM3drainArea <= 0.0) && (here->BSIM3drainPerimeter <= 0.0)) + { DrainSatCurrent = 1.0e-14; + } + else + { DrainSatCurrent = here->BSIM3drainArea + * model->BSIM3jctTempSatCurDensity + + here->BSIM3drainPerimeter + * model->BSIM3jctSidewallTempSatCurDensity; + } } else - { SourceSatCurrent = here->BSIM3sourceArea - * model->BSIM3jctTempSatCurDensity - + here->BSIM3sourcePerimeter - * model->BSIM3jctSidewallTempSatCurDensity; + { + 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; @@ -415,15 +455,6 @@ for (; model != NULL; model = model->BSIM3nextModel) } } - if ((here->BSIM3drainArea <= 0.0) && (here->BSIM3drainPerimeter <= 0.0)) - { DrainSatCurrent = 1.0e-14; - } - else - { DrainSatCurrent = here->BSIM3drainArea - * model->BSIM3jctTempSatCurDensity - + here->BSIM3drainPerimeter - * model->BSIM3jctSidewallTempSatCurDensity; - } if (DrainSatCurrent <= 0.0) { here->BSIM3gbd = ckt->CKTgmin; here->BSIM3cbd = here->BSIM3gbd * vbd; @@ -2237,33 +2268,65 @@ finished: along gate side */ - czbd = model->BSIM3unitAreaTempJctCap * here->BSIM3drainArea; /*bug fix */ - czbs = model->BSIM3unitAreaTempJctCap * here->BSIM3sourceArea; - if (here->BSIM3drainPerimeter < pParam->BSIM3weff) + if (model->BSIM3acmMod == 0) { - czbdswg = model->BSIM3unitLengthGateSidewallTempJctCap - * here->BSIM3drainPerimeter; - czbdsw = 0.0; - } - else - { - czbdsw = model->BSIM3unitLengthSidewallTempJctCap - * (here->BSIM3drainPerimeter - pParam->BSIM3weff); - czbdswg = model->BSIM3unitLengthGateSidewallTempJctCap - * pParam->BSIM3weff; - } - if (here->BSIM3sourcePerimeter < pParam->BSIM3weff) - { - czbssw = 0.0; - czbsswg = model->BSIM3unitLengthGateSidewallTempJctCap - * here->BSIM3sourcePerimeter; - } - else - { - czbssw = model->BSIM3unitLengthSidewallTempJctCap - * (here->BSIM3sourcePerimeter - pParam->BSIM3weff); - czbsswg = model->BSIM3unitLengthGateSidewallTempJctCap - * pParam->BSIM3weff; + czbd = model->BSIM3unitAreaTempJctCap * here->BSIM3drainArea; /*bug fix */ + czbs = model->BSIM3unitAreaTempJctCap * here->BSIM3sourceArea; + if (here->BSIM3drainPerimeter < pParam->BSIM3weff) + { + czbdswg = model->BSIM3unitLengthGateSidewallTempJctCap + * here->BSIM3drainPerimeter; + czbdsw = 0.0; + } + else + { + czbdsw = model->BSIM3unitLengthSidewallTempJctCap + * (here->BSIM3drainPerimeter - pParam->BSIM3weff); + czbdswg = model->BSIM3unitLengthGateSidewallTempJctCap + * pParam->BSIM3weff; + } + if (here->BSIM3sourcePerimeter < pParam->BSIM3weff) + { + czbssw = 0.0; + czbsswg = model->BSIM3unitLengthGateSidewallTempJctCap + * here->BSIM3sourcePerimeter; + } + else + { + czbssw = model->BSIM3unitLengthSidewallTempJctCap + * (here->BSIM3sourcePerimeter - pParam->BSIM3weff); + 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; diff --git a/src/spicelib/devices/bsim3/b3mask.c b/src/spicelib/devices/bsim3/b3mask.c index c90e15aec..533732499 100644 --- a/src/spicelib/devices/bsim3/b3mask.c +++ b/src/spicelib/devices/bsim3/b3mask.c @@ -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; diff --git a/src/spicelib/devices/bsim3/b3mpar.c b/src/spicelib/devices/bsim3/b3mpar.c index 0218c3eb5..103537884 100644 --- a/src/spicelib/devices/bsim3/b3mpar.c +++ b/src/spicelib/devices/bsim3/b3mpar.c @@ -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; diff --git a/src/spicelib/devices/bsim3/b3par.c b/src/spicelib/devices/bsim3/b3par.c index 632c2c4b0..c9c7ddfc1 100644 --- a/src/spicelib/devices/bsim3/b3par.c +++ b/src/spicelib/devices/bsim3/b3par.c @@ -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; diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c index e58320828..f85b3f3e2 100644 --- a/src/spicelib/devices/bsim3/b3set.c +++ b/src/spicelib/devices/bsim3/b3set.c @@ -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) @@ -904,14 +936,19 @@ BSIM3instance **InstArray; printf("Warning: acnqsMod has been set to its global value %d.\n", 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 +969,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"); diff --git a/src/spicelib/devices/bsim3/b3temp.c b/src/spicelib/devices/bsim3/b3temp.c index 2f6582f01..c3b7c3594 100644 --- a/src/spicelib/devices/bsim3/b3temp.c +++ b/src/spicelib/devices/bsim3/b3temp.c @@ -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,16 +807,45 @@ int Size_Not_Found; * pParam->BSIM3weffCV * pParam->BSIM3leffCV * T0); /* process source/drain series resistance */ - here->BSIM3drainConductance = model->BSIM3sheetResistance - * here->BSIM3drainSquares; + /* 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; else here->BSIM3drainConductance = 0.0; - here->BSIM3sourceConductance = model->BSIM3sheetResistance - * here->BSIM3sourceSquares; if (here->BSIM3sourceConductance > 0.0) here->BSIM3sourceConductance = 1.0 / here->BSIM3sourceConductance; diff --git a/src/spicelib/devices/bsim3/bsim3def.h b/src/spicelib/devices/bsim3/bsim3def.h index fbe6e1c02..e480358b7 100644 --- a/src/spicelib/devices/bsim3/bsim3def.h +++ b/src/spicelib/devices/bsim3/bsim3def.h @@ -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