Browse Source

mos1...3: add nlev=3 mode channel thermal noise

pre-master-46
dwarning 2 years ago
parent
commit
6359b7b41f
  1. 3
      src/spicelib/devices/mos1/mos1.c
  2. 3
      src/spicelib/devices/mos1/mos1defs.h
  3. 3
      src/spicelib/devices/mos1/mos1mask.c
  4. 4
      src/spicelib/devices/mos1/mos1mpar.c
  5. 28
      src/spicelib/devices/mos1/mos1noi.c
  6. 3
      src/spicelib/devices/mos1/mos1set.c
  7. 3
      src/spicelib/devices/mos2/mos2.c
  8. 3
      src/spicelib/devices/mos2/mos2defs.h
  9. 3
      src/spicelib/devices/mos2/mos2mask.c
  10. 4
      src/spicelib/devices/mos2/mos2mpar.c
  11. 28
      src/spicelib/devices/mos2/mos2noi.c
  12. 3
      src/spicelib/devices/mos2/mos2set.c
  13. 3
      src/spicelib/devices/mos3/mos3.c
  14. 3
      src/spicelib/devices/mos3/mos3defs.h
  15. 3
      src/spicelib/devices/mos3/mos3mask.c
  16. 4
      src/spicelib/devices/mos3/mos3mpar.c
  17. 28
      src/spicelib/devices/mos3/mos3noi.c
  18. 3
      src/spicelib/devices/mos3/mos3set.c

3
src/spicelib/devices/mos1/mos1.c

@ -149,7 +149,8 @@ IFparm MOS1mPTable[] = { /* model parameters */
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("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection")
IOP("nlev", MOS1_MOD_NLEV, IF_INTEGER ,"Noise model selection"),
IOP("gdsnoi", MOS1_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient")
};
char *MOS1names[] = {

3
src/spicelib/devices/mos1/mos1defs.h

@ -384,6 +384,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
double MOS1fNcoef;
double MOS1fNexp;
int MOS1nlev;
double MOS1gdsnoi;
unsigned MOS1typeGiven :1;
unsigned MOS1latDiffGiven :1;
@ -417,6 +418,7 @@ typedef struct sMOS1model { /* model structure for a resistor */
unsigned MOS1fNcoefGiven :1;
unsigned MOS1fNexpGiven :1;
unsigned MOS1nlevGiven :1;
unsigned MOS1gdsnoiGiven :1;
} MOS1model;
@ -486,6 +488,7 @@ enum {
MOS1_MOD_KF,
MOS1_MOD_AF,
MOS1_MOD_NLEV,
MOS1_MOD_GDSNOI,
MOS1_MOD_TYPE,
};

3
src/spicelib/devices/mos1/mos1mask.c

@ -108,6 +108,9 @@ MOS1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
case MOS1_MOD_NLEV:
value->iValue = model->MOS1nlev;
return(OK);
case MOS1_MOD_GDSNOI:
value->rValue = model->MOS1gdsnoi;
return(OK);
case MOS1_MOD_TYPE:
if (model->MOS1type > 0)
value->sValue = "nmos";

4
src/spicelib/devices/mos1/mos1mpar.c

@ -151,6 +151,10 @@ MOS1mParam(int param, IFvalue *value, GENmodel *inModel)
model->MOS1nlev = value->iValue;
model->MOS1nlevGiven = TRUE;
break;
case MOS1_MOD_GDSNOI:
model->MOS1gdsnoi = value->rValue;
model->MOS1gdsnoiGiven = TRUE;
break;
default:
return(E_BADPARM);
}

28
src/spicelib/devices/mos1/mos1noi.c

@ -35,6 +35,7 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
double noizDens[MOS1NSRCS];
double lnNdens[MOS1NSRCS];
int i;
double vgs, vds, vgd, vgst, alpha, beta, Sid;
/* define the names of the noise sources */
@ -102,9 +103,34 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
ckt, THERMNOISE, inst->MOS1sNodePrime, inst->MOS1sNode,
inst->MOS1sourceConductance);
if (model->MOS1nlev < 3) {
Sid = 2.0 / 3.0 * fabs(inst->MOS1gm);
} else {
vds = *(ckt->CKTstate0 + inst->MOS1vds);
vgs = *(ckt->CKTstate0 + inst->MOS1vgs);
vgd = vgs - vds;
beta = inst->MOS1tTransconductance * inst->MOS1m *
inst->MOS1w/(inst->MOS1l - 2 * model->MOS1latDiff);
vgst=(inst->MOS1mode==1?vgs:vgd) - model->MOS1type*inst->MOS1von;
if (vgst > 0) {
if (vgst <= (vds*inst->MOS1mode)) {
/* saturation region */
alpha = 0.0;
} else {
/* linear region */
alpha = 1.0 - (vds*inst->MOS1mode/(model->MOS1type*inst->MOS1vdsat));
}
}
double betap = beta*(1.0+model->MOS1lambda*(vds*inst->MOS1mode));
Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS1gdsnoi;
}
NevalSrc( & noizDens[MOS1IDNOIZ], & lnNdens[MOS1IDNOIZ],
ckt, THERMNOISE, inst->MOS1dNodePrime, inst->MOS1sNodePrime,
(2.0 / 3.0 * fabs(inst->MOS1gm)));
Sid);
NevalSrc( & noizDens[MOS1FLNOIZ], NULL, ckt,
N_GAIN, inst->MOS1dNodePrime, inst->MOS1sNodePrime,

3
src/spicelib/devices/mos1/mos1set.c

@ -90,6 +90,9 @@ MOS1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
if(!model->MOS1nlevGiven) {
model->MOS1nlev = 2;
}
if(!model->MOS1gdsnoiGiven) {
model->MOS1gdsnoi = 1;
}
/* loop through all the instances of the model */
for (here = MOS1instances(model); here != NULL ;

3
src/spicelib/devices/mos2/mos2.c

@ -157,7 +157,8 @@ IFparm MOS2mPTable[] = { /* model parameters */
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("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection")
IOP("nlev", MOS2_MOD_NLEV, IF_INTEGER ,"Noise model selection"),
IOP("gdsnoi", MOS2_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient")
};
char *MOS2names[] = {

3
src/spicelib/devices/mos2/mos2defs.h

@ -391,6 +391,7 @@ typedef struct sMOS2model { /* model structure for a resistor */
double MOS2fNcoef;
double MOS2fNexp;
int MOS2nlev;
double MOS2gdsnoi;
double MOS2narrowFactor; /* delta */
double MOS2critFieldExp; /* uexp */
@ -439,6 +440,7 @@ typedef struct sMOS2model { /* model structure for a resistor */
unsigned MOS2fNcoefGiven :1;
unsigned MOS2fNexpGiven :1;
unsigned MOS2nlevGiven :1;
unsigned MOS2gdsnoiGiven :1;
} MOS2model;
@ -577,6 +579,7 @@ enum {
MOS2_MOD_KF = 139,
MOS2_MOD_AF,
MOS2_MOD_NLEV,
MOS2_MOD_GDSNOI,
MOS2_MOD_TYPE,
};

3
src/spicelib/devices/mos2/mos2mask.c

@ -133,6 +133,9 @@ MOS2mAsk(CKTcircuit *ckt, GENmodel *inModel, int param,
case MOS2_MOD_NLEV:
value->iValue = model->MOS2nlev;
break;
case MOS2_MOD_GDSNOI:
value->rValue = model->MOS2gdsnoi;
return(OK);
case MOS2_MOD_TYPE:
if (model->MOS2type > 0)
value->sValue = "nmos";

4
src/spicelib/devices/mos2/mos2mpar.c

@ -182,6 +182,10 @@ MOS2mParam(int param, IFvalue *value, GENmodel *inModel)
model->MOS2nlev = value->iValue;
model->MOS2nlevGiven = TRUE;
break;
case MOS2_MOD_GDSNOI:
model->MOS2gdsnoi = value->rValue;
model->MOS2gdsnoiGiven = TRUE;
break;
default:
return(E_BADPARM);
}

28
src/spicelib/devices/mos2/mos2noi.c

@ -34,6 +34,7 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
double noizDens[MOS2NSRCS];
double lnNdens[MOS2NSRCS];
int i;
double vgs, vds, vgd, vgst, alpha, beta, Sid;
/* define the names of the noise sources */
@ -91,9 +92,34 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
ckt, THERMNOISE, inst->MOS2sNodePrime, inst->MOS2sNode,
inst->MOS2sourceConductance);
if (model->MOS2nlev < 3) {
Sid = 2.0 / 3.0 * fabs(inst->MOS2gm);
} else {
vds = *(ckt->CKTstate0 + inst->MOS2vds);
vgs = *(ckt->CKTstate0 + inst->MOS2vgs);
vgd = vgs - vds;
beta = inst->MOS2tTransconductance * inst->MOS2m *
inst->MOS2w/(inst->MOS2l - 2 * model->MOS2latDiff);
vgst=(inst->MOS2mode==1?vgs:vgd) - model->MOS2type*inst->MOS2von;
if (vgst > 0) {
if (vgst <= (vds*inst->MOS2mode)) {
/* saturation region */
alpha = 0.0;
} else {
/* linear region */
alpha = 1.0 - (vds*inst->MOS2mode/(model->MOS2type*inst->MOS2vdsat));
}
}
double betap = beta*(1.0+model->MOS2lambda*(vds*inst->MOS2mode));
Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS2gdsnoi;
}
NevalSrc( & noizDens[MOS2IDNOIZ], & lnNdens[MOS2IDNOIZ],
ckt, THERMNOISE, inst->MOS2dNodePrime, inst->MOS2sNodePrime,
(2.0 / 3.0 * fabs(inst->MOS2gm)));
Sid);
NevalSrc( & noizDens[MOS2FLNOIZ], NULL, ckt,
N_GAIN, inst->MOS2dNodePrime, inst->MOS2sNodePrime,

3
src/spicelib/devices/mos2/mos2set.c

@ -119,6 +119,9 @@ MOS2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if(!model->MOS2nlevGiven) {
model->MOS2nlev = 2;
}
if(!model->MOS2gdsnoiGiven) {
model->MOS2gdsnoi = 1;
}
/* loop through all the instances of the model */
for (here = MOS2instances(model); here != NULL ;

3
src/spicelib/devices/mos3/mos3.c

@ -157,7 +157,8 @@ IFparm MOS3mPTable[] = { /* model parameters */
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("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection")
IOP("nlev", MOS3_MOD_NLEV, IF_INTEGER ,"Noise model selection"),
IOP("gdsnoi", MOS3_MOD_GDSNOI, IF_REAL ,"Channel shot noise coefficient")
};
char *MOS3names[] = {

3
src/spicelib/devices/mos3/mos3defs.h

@ -401,6 +401,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
double MOS3fNcoef;
double MOS3fNexp;
int MOS3nlev;
double MOS3gdsnoi;
unsigned MOS3typeGiven :1;
unsigned MOS3latDiffGiven :1;
@ -444,6 +445,7 @@ typedef struct sMOS3model { /* model structure for a resistor */
unsigned MOS3fNcoefGiven :1;
unsigned MOS3fNexpGiven :1;
unsigned MOS3nlevGiven :1;
unsigned MOS3gdsnoiGiven :1;
} MOS3model;
@ -583,6 +585,7 @@ enum {
MOS3_MOD_KF,
MOS3_MOD_AF,
MOS3_MOD_NLEV,
MOS3_MOD_GDSNOI,
MOS3_MOD_TYPE,
MOS3_MOD_XL,
MOS3_MOD_WD,

3
src/spicelib/devices/mos3/mos3mask.c

@ -157,6 +157,9 @@ MOS3mAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
case MOS3_MOD_NLEV:
value->iValue = model->MOS3nlev;
return(OK);
case MOS3_MOD_GDSNOI:
value->rValue = model->MOS3gdsnoi;
return(OK);
case MOS3_MOD_TYPE:
if (model->MOS3type > 0)
value->sValue = "nmos";

4
src/spicelib/devices/mos3/mos3mpar.c

@ -195,6 +195,10 @@ MOS3mParam(int param, IFvalue *value, GENmodel *inModel)
model->MOS3nlev = value->iValue;
model->MOS3nlevGiven = TRUE;
break;
case MOS3_MOD_GDSNOI:
model->MOS3gdsnoi = value->rValue;
model->MOS3gdsnoiGiven = TRUE;
break;
default:
return(E_BADPARM);
}

28
src/spicelib/devices/mos3/mos3noi.c

@ -34,6 +34,7 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
double noizDens[MOS3NSRCS];
double lnNdens[MOS3NSRCS];
int i;
double vgs, vds, vgd, vgst, alpha, beta, Sid;
/* define the names of the noise sources */
@ -91,9 +92,34 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
ckt, THERMNOISE, inst->MOS3sNodePrime, inst->MOS3sNode,
inst->MOS3sourceConductance);
if (model->MOS3nlev < 3) {
Sid = 2.0 / 3.0 * fabs(inst->MOS3gm);
} else {
vds = *(ckt->CKTstate0 + inst->MOS3vds);
vgs = *(ckt->CKTstate0 + inst->MOS3vgs);
vgd = vgs - vds;
beta = inst->MOS3tTransconductance * inst->MOS3m *
inst->MOS3w/(inst->MOS3l - 2 * model->MOS3latDiff);
vgst=(inst->MOS3mode==1?vgs:vgd) - model->MOS3type*inst->MOS3von;
if (vgst > 0) {
if (vgst <= (vds*inst->MOS3mode)) {
/* saturation region */
alpha = 0.0;
} else {
/* linear region */
alpha = 1.0 - (vds*inst->MOS3mode/(model->MOS3type*inst->MOS3vdsat));
}
}
double betap = beta;
Sid = 2.0 / 3.0 * betap * vgst * (1.0+alpha+alpha*alpha) / (1.0+alpha) * model->MOS3gdsnoi;
}
NevalSrc( & noizDens[MOS3IDNOIZ], & lnNdens[MOS3IDNOIZ],
ckt, THERMNOISE, inst->MOS3dNodePrime, inst->MOS3sNodePrime,
(2.0 / 3.0 * fabs(inst->MOS3gm)));
Sid);
NevalSrc( & noizDens[MOS3FLNOIZ], NULL, ckt,
N_GAIN, inst->MOS3dNodePrime, inst->MOS3sNodePrime,

3
src/spicelib/devices/mos3/mos3set.c

@ -142,6 +142,9 @@ MOS3setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if(!model->MOS3nlevGiven) {
model->MOS3nlev = 2;
}
if(!model->MOS3gdsnoiGiven) {
model->MOS3gdsnoi = 1;
}
/* loop through all the instances of the model */
for (here = MOS3instances(model); here != NULL ;

Loading…
Cancel
Save