cweakinv, add model parameter model->VDMOSsubshift
This commit is contained in:
parent
f0d131fb8a
commit
729eac4e84
|
|
@ -83,6 +83,7 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
|
||||
/* weak inversion */
|
||||
IOP("subthres", VDMOS_MOD_SUBTHRES, IF_REAL, "Current(per volt Vds) to switch from square law to exponential subthreshold conduction"),
|
||||
IOP("subshift", VDMOS_MOD_SUBSHIFT, IF_REAL, "Shift of weak inversion plot on the vgs axis"),
|
||||
|
||||
/* body diode */
|
||||
IOP("bv", VDMOS_MOD_BV, IF_REAL, "Vds breakdown voltage"),
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
double VDMOSa;
|
||||
double VDMOScgs;
|
||||
double VDMOSsubth;
|
||||
double VDMOSsubshift;
|
||||
double VDMOSmtr;
|
||||
|
||||
/* bulk diode */
|
||||
|
|
@ -377,6 +378,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
unsigned VDMOScgsGiven :1;
|
||||
unsigned VDMOSaGiven :1;
|
||||
unsigned VDMOSsubthGiven :1;
|
||||
unsigned VDMOSsubshiftGiven :1;
|
||||
unsigned VDMOSmtrGiven :1;
|
||||
|
||||
unsigned VDMOSDbvGiven :1;
|
||||
|
|
@ -443,6 +445,7 @@ enum {
|
|||
VDMOS_MOD_RB,
|
||||
VDMOS_MOD_MTRIODE,
|
||||
VDMOS_MOD_SUBTHRES,
|
||||
VDMOS_MOD_SUBSHIFT,
|
||||
VDMOS_MOD_BV,
|
||||
VDMOS_MOD_IBV,
|
||||
VDMOS_MOD_NBV,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ VDMOS: 2018 Holger Vogt
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
static double
|
||||
cweakinv(double n, double vgst, double vds, double lambda, double beta, double vt, double mtr);
|
||||
cweakinv(double n, double shift, double vgst, double vds, double lambda, double beta, double vt, double mtr);
|
||||
|
||||
|
||||
int
|
||||
|
|
@ -369,22 +369,22 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
* numerical differentiation for gd and gm with a delta of 2 mV */
|
||||
if (model->VDMOSsubthGiven && (here->VDMOSmode == 1)) {
|
||||
double delta = 0.001;
|
||||
cdrain = cweakinv(model->VDMOSsubth, vgst, vds, model->VDMOSlambda,
|
||||
cdrain = cweakinv(model->VDMOSsubth, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr);
|
||||
/* gd */
|
||||
double vds1 = vds + delta;
|
||||
double cdrp = cweakinv(model->VDMOSsubth, vgst, vds1, model->VDMOSlambda,
|
||||
double cdrp = cweakinv(model->VDMOSsubth, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr);
|
||||
vds1 = vds - delta;
|
||||
double cdrm = cweakinv(model->VDMOSsubth, vgst, vds1, model->VDMOSlambda,
|
||||
double cdrm = cweakinv(model->VDMOSsubth, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr);
|
||||
here->VDMOSgds = (cdrp - cdrm) / (2. * delta);
|
||||
/* gm */
|
||||
double vgst1 = vgst + delta;
|
||||
cdrp = cweakinv(model->VDMOSsubth, vgst1, vds, model->VDMOSlambda,
|
||||
cdrp = cweakinv(model->VDMOSsubth, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr);
|
||||
vgst1 = vgst - delta;
|
||||
cdrm = cweakinv(model->VDMOSsubth, vgst1, vds, model->VDMOSlambda,
|
||||
cdrm = cweakinv(model->VDMOSsubth, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
|
||||
Beta, vt, model->VDMOSmtr);
|
||||
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
|
||||
here->VDMOSgmbs = 0.;
|
||||
|
|
@ -888,14 +888,15 @@ scalef(double nf2, double vgst)
|
|||
*/
|
||||
|
||||
static double
|
||||
cweakinv(double n, double vgst, double vds, double lambda, double beta, double vt, double mtr)
|
||||
cweakinv(double slope, double shift, double vgst, double vds, double lambda, double beta, double vt, double mtr)
|
||||
{
|
||||
double nf2 = 0.1; /* empirical setting of sin 'speed' */
|
||||
double n1 = n + (1 - n) * scalef(nf2, vgst); /* n < n1 < 1 */
|
||||
vgst += shift * (1 - scalef(2, vgst));
|
||||
double n = slope / 2.3 / 0.0256; /* Tsividis, p. 208 */
|
||||
double n1 = n + (1 - n) * scalef(2, vgst); /* n < n1 < 1 */
|
||||
double first = log(1 + exp(vgst / (2 * n1 * vt)));
|
||||
double second = log(1 + exp((vgst - vds * mtr * n1) / (2 * n1 * vt)));
|
||||
double cds =
|
||||
beta * n1 * 2 * vt * vt * (1 + scalef(nf2, vgst) * lambda * vds) *
|
||||
beta * n1 * 2 * vt * vt * (1 + scalef(2, vgst) * lambda * vds) *
|
||||
(first * first - second * second);
|
||||
return cds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_SUBTHRES:
|
||||
value->rValue = model->VDMOSsubth;
|
||||
return(OK);
|
||||
case VDMOS_MOD_SUBSHIFT:
|
||||
value->rValue = model->VDMOSsubshift;
|
||||
return(OK);
|
||||
case VDMOS_MOD_TYPE:
|
||||
if (model->VDMOStype > 0)
|
||||
value->sValue = "vdmosn";
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOSsubth = value->rValue;
|
||||
model->VDMOSsubthGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_SUBSHIFT:
|
||||
model->VDMOSsubshift = value->rValue;
|
||||
model->VDMOSsubshiftGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_BV:
|
||||
model->VDMOSDbv = value->rValue;
|
||||
model->VDMOSDbvGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if (!model->VDMOSsubthGiven) {
|
||||
model->VDMOSsubth = 0;
|
||||
}
|
||||
if (!model->VDMOSsubshiftGiven) {
|
||||
model->VDMOSsubshift = 0;
|
||||
}
|
||||
if (!model->VDMOSmtrGiven) {
|
||||
model->VDMOSmtr = 1.;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue