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
This commit is contained in:
rlar 2017-10-14 14:41:12 +02:00
parent f868418d13
commit ca57447f6c
2 changed files with 82 additions and 24 deletions

View File

@ -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");

View File

@ -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");