Browse Source

cweakinv, add model parameter model->VDMOSsubshift

pre-master-46
Holger Vogt 8 years ago
committed by rlar
parent
commit
729eac4e84
  1. 1
      src/spicelib/devices/vdmos/vdmos.c
  2. 3
      src/spicelib/devices/vdmos/vdmosdefs.h
  3. 21
      src/spicelib/devices/vdmos/vdmosload.c
  4. 3
      src/spicelib/devices/vdmos/vdmosmask.c
  5. 4
      src/spicelib/devices/vdmos/vdmosmpar.c
  6. 3
      src/spicelib/devices/vdmos/vdmosset.c

1
src/spicelib/devices/vdmos/vdmos.c

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

3
src/spicelib/devices/vdmos/vdmosdefs.h

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

21
src/spicelib/devices/vdmos/vdmosload.c

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

3
src/spicelib/devices/vdmos/vdmosmask.c

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

4
src/spicelib/devices/vdmos/vdmosmpar.c

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

3
src/spicelib/devices/vdmos/vdmosset.c

@ -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…
Cancel
Save