cweakinv, add model parameter model->VDMOSsubshift

This commit is contained in:
Holger Vogt 2018-04-22 22:22:47 +02:00 committed by rlar
parent f0d131fb8a
commit 729eac4e84
6 changed files with 25 additions and 10 deletions

View File

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

View File

@ -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,

View File

@ -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;
}

View File

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

View File

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

View File

@ -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.;
}