From ca57447f6cf98727bc829d09694d5aa74bcc55cf Mon Sep 17 00:00:00 2001 From: rlar Date: Sat, 14 Oct 2017 14:41:12 +0200 Subject: [PATCH] fix commit "devices/bsim3v32: apply Area Calculation Method (ACM) to the bsim3v3.2.4 model" which moved processing of several parameters into a new function ACM_SourceDrainResistances() but did so incompletely. As a consequence the matrix footprint was not correctly modified when source or drainresistance is zero Thanks for the bug report by "Sto" in message > bug: mosfet models with deliberate NRD=0 (ngspice-27) https://sourceforge.net/p/ngspice/discussion/133842/thread/fa39228d --- src/spicelib/devices/bsim3/b3set.c | 53 ++++++++++++++++++------ src/spicelib/devices/bsim3v32/b3v32set.c | 53 ++++++++++++++++++------ 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c index 2b104bb59..da14dd8dc 100644 --- a/src/spicelib/devices/bsim3/b3set.c +++ b/src/spicelib/devices/bsim3/b3set.c @@ -15,6 +15,7 @@ #include "bsim3def.h" #include "ngspice/const.h" #include "ngspice/sperror.h" +#include "ngspice/devdefs.h" #include "ngspice/suffix.h" #define MAX_EXP 5.834617425e14 @@ -984,13 +985,46 @@ BSIM3instance **InstArray; if (!here->BSIM3mGiven) here->BSIM3m = 1; + /* process source/drain series resistance */ + /* ACM model */ + + double drainResistance, sourceResistance; + + if (model->BSIM3acmMod == 0) + { + drainResistance = model->BSIM3sheetResistance + * here->BSIM3drainSquares; + sourceResistance = model->BSIM3sheetResistance + * here->BSIM3sourceSquares; + } + else /* ACM > 0 */ + { + error = ACM_SourceDrainResistances( + model->BSIM3acmMod, + model->BSIM3ld, + model->BSIM3ldif, + model->BSIM3hdif, + model->BSIM3wmlt, + here->BSIM3w, + model->BSIM3xw, + model->BSIM3sheetResistance, + here->BSIM3drainSquaresGiven, + model->BSIM3rd, + model->BSIM3rdc, + here->BSIM3drainSquares, + here->BSIM3sourceSquaresGiven, + model->BSIM3rs, + model->BSIM3rsc, + here->BSIM3sourceSquares, + &drainResistance, + &sourceResistance + ); + if (error) + return(error); + } + /* process drain series resistance */ - 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 (drainResistance != 0.0) { if(here->BSIM3dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"drain"); @@ -1011,12 +1045,7 @@ BSIM3instance **InstArray; } /* process source series resistance */ - 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 (sourceResistance != 0.0) { if(here->BSIM3sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3name,"source"); diff --git a/src/spicelib/devices/bsim3v32/b3v32set.c b/src/spicelib/devices/bsim3v32/b3v32set.c index 76bcda994..6025934ac 100644 --- a/src/spicelib/devices/bsim3v32/b3v32set.c +++ b/src/spicelib/devices/bsim3v32/b3v32set.c @@ -14,6 +14,7 @@ #include "bsim3v32def.h" #include "ngspice/const.h" #include "ngspice/sperror.h" +#include "ngspice/devdefs.h" #include "ngspice/suffix.h" #define MAX_EXP 5.834617425e14 @@ -992,13 +993,46 @@ BSIM3v32instance **InstArray; if (!here->BSIM3v32mGiven) here->BSIM3v32m = 1; + /* process source/drain series resistance */ + /* ACM model */ + + double DrainResistance, SourceResistance; + + if (model->BSIM3v32acmMod == 0) + { + DrainResistance = model->BSIM3v32sheetResistance + * here->BSIM3v32drainSquares; + SourceResistance = model->BSIM3v32sheetResistance + * here->BSIM3v32sourceSquares; + } + else /* ACM > 0 */ + { + error = ACM_SourceDrainResistances( + model->BSIM3v32acmMod, + model->BSIM3v32ld, + model->BSIM3v32ldif, + model->BSIM3v32hdif, + model->BSIM3v32wmlt, + here->BSIM3v32w, + model->BSIM3v32xw, + model->BSIM3v32sheetResistance, + here->BSIM3v32drainSquaresGiven, + model->BSIM3v32rd, + model->BSIM3v32rdc, + here->BSIM3v32drainSquares, + here->BSIM3v32sourceSquaresGiven, + model->BSIM3v32rs, + model->BSIM3v32rsc, + here->BSIM3v32sourceSquares, + &DrainResistance, + &SourceResistance + ); + if (error) + return(error); + } + /* process drain series resistance */ - if ( ((model->BSIM3v32sheetResistance > 0.0) && (here->BSIM3v32drainSquares > 0.0)) - ||((model->BSIM3v32sheetResistance > 0.0) && (model->BSIM3v32hdif > 0.0)) - ||((model->BSIM3v32rd > 0.0) && (model->BSIM3v32ldif > 0.0)) - ||((model->BSIM3v32rd > 0.0) && (model->BSIM3v32ld > 0.0)) - ||((model->BSIM3v32rdc > 0.0)) - ) + if (DrainResistance != 0) { if(here->BSIM3v32dNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3v32name,"drain"); @@ -1019,12 +1053,7 @@ BSIM3v32instance **InstArray; } /* process source series resistance */ - if ( ((model->BSIM3v32sheetResistance > 0.0) && (here->BSIM3v32sourceSquares > 0.0)) - ||((model->BSIM3v32sheetResistance > 0.0) && (model->BSIM3v32hdif > 0.0)) - ||((model->BSIM3v32rs > 0.0) && (model->BSIM3v32ldif > 0.0)) - ||((model->BSIM3v32rs > 0.0) && (model->BSIM3v32ld > 0.0)) - ||((model->BSIM3v32rsc > 0.0)) - ) + if (SourceResistance != 0) { if(here->BSIM3v32sNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM3v32name,"source");