selectable flicker noise models for mos1...3
This commit is contained in:
parent
2a6db71726
commit
1381d71cb1
|
|
@ -148,7 +148,8 @@ IFparm MOS1mPTable[] = { /* model parameters */
|
|||
IOP("nss", MOS1_MOD_NSS, IF_REAL ,"Surface state density"),
|
||||
IOP("tnom", MOS1_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"),
|
||||
IOP("kf", MOS1_MOD_KF, IF_REAL ,"Flicker noise coefficient"),
|
||||
IOP("af", MOS1_MOD_AF, IF_REAL ,"Flicker noise exponent")
|
||||
IOP("af", MOS1_MOD_AF, IF_REAL ,"Flicker noise exponent"),
|
||||
IOP("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection")
|
||||
};
|
||||
|
||||
char *MOS1names[] = {
|
||||
|
|
|
|||
|
|
@ -383,6 +383,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
|
|||
double MOS1surfaceMobility; /* input - use tSurfMob */
|
||||
double MOS1fNcoef;
|
||||
double MOS1fNexp;
|
||||
int MOS1nlev;
|
||||
|
||||
unsigned MOS1typeGiven :1;
|
||||
unsigned MOS1latDiffGiven :1;
|
||||
|
|
@ -415,6 +416,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
|
|||
unsigned MOS1tnomGiven :1;
|
||||
unsigned MOS1fNcoefGiven :1;
|
||||
unsigned MOS1fNexpGiven :1;
|
||||
unsigned MOS1nlevGiven :1;
|
||||
|
||||
} MOS1model;
|
||||
|
||||
|
|
@ -483,6 +485,7 @@ enum {
|
|||
MOS1_MOD_TNOM,
|
||||
MOS1_MOD_KF,
|
||||
MOS1_MOD_AF,
|
||||
MOS1_MOD_NLEV,
|
||||
MOS1_MOD_TYPE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ MOS1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case MOS1_MOD_NSS:
|
||||
value->rValue = model->MOS1surfaceStateDensity;
|
||||
return(OK);
|
||||
case MOS1_MOD_NLEV:
|
||||
value->iValue = model->MOS1nlev;
|
||||
return(OK);
|
||||
case MOS1_MOD_TYPE:
|
||||
if (model->MOS1type > 0)
|
||||
value->sValue = "nmos";
|
||||
|
|
|
|||
|
|
@ -147,6 +147,10 @@ MOS1mParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->MOS1fNexp = value->rValue;
|
||||
model->MOS1fNexpGiven = TRUE;
|
||||
break;
|
||||
case MOS1_MOD_NLEV:
|
||||
model->MOS1nlev = value->iValue;
|
||||
model->MOS1nlevGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/iferrmsg.h"
|
||||
#include "ngspice/noisedef.h"
|
||||
#include "ngspice/suffix.h"
|
||||
#include "ngspice/compatmode.h"
|
||||
|
||||
/*
|
||||
* MOS1noise (mode, operation, firstModel, ckt, data, OnDens)
|
||||
|
|
@ -108,13 +109,44 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt,
|
||||
N_GAIN, inst -> MOS1dNodePrime, inst -> MOS1sNodePrime,
|
||||
(double) 0.0);
|
||||
noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef *
|
||||
exp(model -> MOS1fNexp *
|
||||
log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS1w *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
coxSquared);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef *
|
||||
exp(model -> MOS1fNexp *
|
||||
log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS1w *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
coxSquared);
|
||||
} else {
|
||||
switch (model -> MOS1nlev) {
|
||||
case 0:
|
||||
noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef *
|
||||
exp(model -> MOS1fNexp *
|
||||
log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
sqrt(coxSquared));
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef *
|
||||
exp(model -> MOS1fNexp *
|
||||
log(MAX(fabs(inst -> MOS1cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS1w *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
sqrt(coxSquared));
|
||||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS1FLNOIZ] *= model -> MOS1fNcoef *
|
||||
inst -> MOS1gm * inst -> MOS1gm /
|
||||
(pow(data -> freq, model -> MOS1fNexp) *
|
||||
inst -> MOS1w *
|
||||
(inst -> MOS1l - 2 * model -> MOS1latDiff) *
|
||||
sqrt(coxSquared));
|
||||
break;
|
||||
}
|
||||
}
|
||||
lnNdens[MOS1FLNOIZ] =
|
||||
log(MAX(noizDens[MOS1FLNOIZ], N_MINLOG));
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if(!model->MOS1fNexpGiven) {
|
||||
model->MOS1fNexp = 1;
|
||||
}
|
||||
if(!model->MOS1nlevGiven) {
|
||||
model->MOS1nlev = 2;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = MOS1instances(model); here != NULL ;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ IFparm MOS2mPTable[] = { /* model parameters */
|
|||
IOP("nfs", MOS2_MOD_NFS, IF_REAL ,"Fast surface state density"),
|
||||
IOPU("tnom", MOS2_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"),
|
||||
IOP("kf", MOS2_MOD_KF, IF_REAL ,"Flicker noise coefficient"),
|
||||
IOP("af", MOS2_MOD_AF, IF_REAL ,"Flicker noise exponent")
|
||||
IOP("af", MOS2_MOD_AF, IF_REAL ,"Flicker noise exponent"),
|
||||
IOP("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection")
|
||||
};
|
||||
|
||||
char *MOS2names[] = {
|
||||
|
|
|
|||
|
|
@ -390,6 +390,7 @@ typedef struct sMOS2model { /* model structure for a resistor */
|
|||
double MOS2surfaceMobility;
|
||||
double MOS2fNcoef;
|
||||
double MOS2fNexp;
|
||||
int MOS2nlev;
|
||||
|
||||
double MOS2narrowFactor; /* delta */
|
||||
double MOS2critFieldExp; /* uexp */
|
||||
|
|
@ -437,6 +438,7 @@ typedef struct sMOS2model { /* model structure for a resistor */
|
|||
unsigned MOS2channelChargeGiven :1; /* neff */
|
||||
unsigned MOS2fNcoefGiven :1;
|
||||
unsigned MOS2fNexpGiven :1;
|
||||
unsigned MOS2nlevGiven :1;
|
||||
|
||||
} MOS2model;
|
||||
|
||||
|
|
@ -574,6 +576,7 @@ enum {
|
|||
enum {
|
||||
MOS2_MOD_KF = 139,
|
||||
MOS2_MOD_AF,
|
||||
MOS2_MOD_NLEV,
|
||||
MOS2_MOD_TYPE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ MOS2mAsk(CKTcircuit *ckt, GENmodel *inModel, int param,
|
|||
case MOS2_MOD_AF:
|
||||
value->rValue = model->MOS2fNexp;
|
||||
break;
|
||||
case MOS2_MOD_NLEV:
|
||||
value->iValue = model->MOS2nlev;
|
||||
break;
|
||||
case MOS2_MOD_TYPE:
|
||||
if (model->MOS2type > 0)
|
||||
value->sValue = "nmos";
|
||||
|
|
|
|||
|
|
@ -178,6 +178,10 @@ MOS2mParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->MOS2fNexp = value->rValue;
|
||||
model->MOS2fNexpGiven = TRUE;
|
||||
break;
|
||||
case MOS2_MOD_NLEV:
|
||||
model->MOS2nlev = value->iValue;
|
||||
model->MOS2nlevGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/iferrmsg.h"
|
||||
#include "ngspice/noisedef.h"
|
||||
#include "ngspice/suffix.h"
|
||||
#include "ngspice/compatmode.h"
|
||||
|
||||
/*
|
||||
* MOS2noise (mode, operation, firstModel, ckt, data, OnDens)
|
||||
|
|
@ -97,13 +98,44 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt,
|
||||
N_GAIN, inst -> MOS2dNodePrime, inst -> MOS2sNodePrime,
|
||||
(double) 0.0);
|
||||
noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef *
|
||||
exp(model -> MOS2fNexp *
|
||||
log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS2w *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef *
|
||||
exp(model -> MOS2fNexp *
|
||||
log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS2w *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
model -> MOS2oxideCapFactor * model -> MOS2oxideCapFactor);
|
||||
} else {
|
||||
switch (model -> MOS2nlev) {
|
||||
case 0:
|
||||
noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef *
|
||||
exp(model -> MOS2fNexp *
|
||||
log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
model -> MOS2oxideCapFactor);
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef *
|
||||
exp(model -> MOS2fNexp *
|
||||
log(MAX(fabs(inst -> MOS2cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
inst -> MOS2w *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
model -> MOS2oxideCapFactor);
|
||||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS2FLNOIZ] *= model -> MOS2fNcoef *
|
||||
inst -> MOS2gm * inst -> MOS2gm /
|
||||
(pow(data -> freq, model -> MOS2fNexp) *
|
||||
inst -> MOS2w *
|
||||
(inst -> MOS2l - 2 * model -> MOS2latDiff) *
|
||||
model -> MOS2oxideCapFactor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lnNdens[MOS2FLNOIZ] =
|
||||
log(MAX(noizDens[MOS2FLNOIZ], N_MINLOG));
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->MOS2fNexpGiven) {
|
||||
model->MOS2fNexp = 1;
|
||||
}
|
||||
if(!model->MOS2nlevGiven) {
|
||||
model->MOS2nlev = 2;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = MOS2instances(model); here != NULL ;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ IFparm MOS3mPTable[] = { /* model parameters */
|
|||
IOP("kappa", MOS3_MOD_KAPPA, IF_REAL ,"Kappa"),
|
||||
IOPU("tnom", MOS3_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"),
|
||||
IOP("kf", MOS3_MOD_KF, IF_REAL ,"Flicker noise coefficient"),
|
||||
IOP("af", MOS3_MOD_AF, IF_REAL ,"Flicker noise exponent")
|
||||
IOP("af", MOS3_MOD_AF, IF_REAL ,"Flicker noise exponent"),
|
||||
IOP("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection")
|
||||
};
|
||||
|
||||
char *MOS3names[] = {
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
double MOS3kappa; /* kappa */
|
||||
double MOS3fNcoef;
|
||||
double MOS3fNexp;
|
||||
int MOS3nlev;
|
||||
|
||||
unsigned MOS3typeGiven :1;
|
||||
unsigned MOS3latDiffGiven :1;
|
||||
|
|
@ -442,6 +443,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
|
|||
unsigned MOS3tnomGiven :1; /* Tnom was given? */
|
||||
unsigned MOS3fNcoefGiven :1;
|
||||
unsigned MOS3fNexpGiven :1;
|
||||
unsigned MOS3nlevGiven :1;
|
||||
|
||||
} MOS3model;
|
||||
|
||||
|
|
@ -580,6 +582,7 @@ enum {
|
|||
MOS3_MOD_TNOM,
|
||||
MOS3_MOD_KF,
|
||||
MOS3_MOD_AF,
|
||||
MOS3_MOD_NLEV,
|
||||
MOS3_MOD_TYPE,
|
||||
MOS3_MOD_XL,
|
||||
MOS3_MOD_WD,
|
||||
|
|
|
|||
|
|
@ -154,6 +154,9 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case MOS3_MOD_AF:
|
||||
value->rValue = here->MOS3fNexp;
|
||||
return(OK);
|
||||
case MOS3_MOD_NLEV:
|
||||
value->iValue = here->MOS3nlev;
|
||||
return(OK);
|
||||
case MOS3_MOD_TYPE:
|
||||
if (here->MOS3type > 0)
|
||||
value->sValue = "nmos";
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->MOS3fNexp = value->rValue;
|
||||
model->MOS3fNexpGiven = TRUE;
|
||||
break;
|
||||
case MOS3_MOD_NLEV:
|
||||
model->MOS3nlev = value->iValue;
|
||||
model->MOS3nlevGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/iferrmsg.h"
|
||||
#include "ngspice/noisedef.h"
|
||||
#include "ngspice/suffix.h"
|
||||
#include "ngspice/compatmode.h"
|
||||
|
||||
/*
|
||||
* MOS3noise (mode, operation, firstModel, ckt, data, OnDens)
|
||||
|
|
@ -97,13 +98,44 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt,
|
||||
N_GAIN, inst -> MOS3dNodePrime, inst -> MOS3sNodePrime,
|
||||
(double) 0.0);
|
||||
noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef *
|
||||
exp(model -> MOS3fNexp *
|
||||
log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS3w - 2 * model -> MOS3widthNarrow) *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef *
|
||||
exp(model -> MOS3fNexp *
|
||||
log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS3w - 2 * model -> MOS3widthNarrow) *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
model -> MOS3oxideCapFactor * model -> MOS3oxideCapFactor);
|
||||
} else {
|
||||
switch (model -> MOS3nlev) {
|
||||
case 0:
|
||||
noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef *
|
||||
exp(model -> MOS3fNexp *
|
||||
log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
model -> MOS3oxideCapFactor);
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef *
|
||||
exp(model -> MOS3fNexp *
|
||||
log(MAX(fabs(inst -> MOS3cd), N_MINLOG))) /
|
||||
(data -> freq *
|
||||
(inst -> MOS3w - 2 * model -> MOS3widthNarrow) *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
model -> MOS3oxideCapFactor);
|
||||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS3FLNOIZ] *= model -> MOS3fNcoef *
|
||||
inst -> MOS3gm * inst -> MOS3gm /
|
||||
(pow(data -> freq, model -> MOS3fNexp) *
|
||||
(inst -> MOS3w - 2 * model -> MOS3widthNarrow) *
|
||||
(inst -> MOS3l - 2 * model -> MOS3latDiff) *
|
||||
model -> MOS3oxideCapFactor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lnNdens[MOS3FLNOIZ] =
|
||||
log(MAX(noizDens[MOS3FLNOIZ], N_MINLOG));
|
||||
|
||||
|
|
|
|||
|
|
@ -139,6 +139,9 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->MOS3fNexpGiven) {
|
||||
model->MOS3fNexp = 1;
|
||||
}
|
||||
if(!model->MOS3nlevGiven) {
|
||||
model->MOS3nlev = 2;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = MOS3instances(model); here != NULL ;
|
||||
|
|
|
|||
Loading…
Reference in New Issue