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 */ /* weak inversion */
IOP("subthres", VDMOS_MOD_SUBTHRES, IF_REAL, "Current(per volt Vds) to switch from square law to exponential subthreshold conduction"), 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 */ /* body diode */
IOP("bv", VDMOS_MOD_BV, IF_REAL, "Vds breakdown voltage"), 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 VDMOSa;
double VDMOScgs; double VDMOScgs;
double VDMOSsubth; double VDMOSsubth;
double VDMOSsubshift;
double VDMOSmtr; double VDMOSmtr;
/* bulk diode */ /* bulk diode */
@ -377,6 +378,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
unsigned VDMOScgsGiven :1; unsigned VDMOScgsGiven :1;
unsigned VDMOSaGiven :1; unsigned VDMOSaGiven :1;
unsigned VDMOSsubthGiven :1; unsigned VDMOSsubthGiven :1;
unsigned VDMOSsubshiftGiven :1;
unsigned VDMOSmtrGiven :1; unsigned VDMOSmtrGiven :1;
unsigned VDMOSDbvGiven :1; unsigned VDMOSDbvGiven :1;
@ -443,6 +445,7 @@ enum {
VDMOS_MOD_RB, VDMOS_MOD_RB,
VDMOS_MOD_MTRIODE, VDMOS_MOD_MTRIODE,
VDMOS_MOD_SUBTHRES, VDMOS_MOD_SUBTHRES,
VDMOS_MOD_SUBSHIFT,
VDMOS_MOD_BV, VDMOS_MOD_BV,
VDMOS_MOD_IBV, VDMOS_MOD_IBV,
VDMOS_MOD_NBV, VDMOS_MOD_NBV,

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

@ -15,7 +15,7 @@ VDMOS: 2018 Holger Vogt
#include "ngspice/suffix.h" #include "ngspice/suffix.h"
static double 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 int
@ -369,22 +369,22 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
* numerical differentiation for gd and gm with a delta of 2 mV */ * numerical differentiation for gd and gm with a delta of 2 mV */
if (model->VDMOSsubthGiven && (here->VDMOSmode == 1)) { if (model->VDMOSsubthGiven && (here->VDMOSmode == 1)) {
double delta = 0.001; 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); Beta, vt, model->VDMOSmtr);
/* gd */ /* gd */
double vds1 = vds + delta; 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); Beta, vt, model->VDMOSmtr);
vds1 = vds - delta; 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); Beta, vt, model->VDMOSmtr);
here->VDMOSgds = (cdrp - cdrm) / (2. * delta); here->VDMOSgds = (cdrp - cdrm) / (2. * delta);
/* gm */ /* gm */
double vgst1 = vgst + delta; 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); Beta, vt, model->VDMOSmtr);
vgst1 = vgst - delta; 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); Beta, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta); here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
here->VDMOSgmbs = 0.; here->VDMOSgmbs = 0.;
@ -888,14 +888,15 @@ scalef(double nf2, double vgst)
*/ */
static double 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 first = log(1 + exp(vgst / (2 * n1 * vt)));
double second = log(1 + exp((vgst - vds * mtr * n1) / (2 * n1 * vt))); double second = log(1 + exp((vgst - vds * mtr * n1) / (2 * n1 * vt)));
double cds = 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); (first * first - second * second);
return cds; 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: case VDMOS_MOD_SUBTHRES:
value->rValue = model->VDMOSsubth; value->rValue = model->VDMOSsubth;
return(OK); return(OK);
case VDMOS_MOD_SUBSHIFT:
value->rValue = model->VDMOSsubshift;
return(OK);
case VDMOS_MOD_TYPE: case VDMOS_MOD_TYPE:
if (model->VDMOStype > 0) if (model->VDMOStype > 0)
value->sValue = "vdmosn"; 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->VDMOSsubth = value->rValue;
model->VDMOSsubthGiven = TRUE; model->VDMOSsubthGiven = TRUE;
break; break;
case VDMOS_MOD_SUBSHIFT:
model->VDMOSsubshift = value->rValue;
model->VDMOSsubshiftGiven = TRUE;
break;
case VDMOS_MOD_BV: case VDMOS_MOD_BV:
model->VDMOSDbv = value->rValue; model->VDMOSDbv = value->rValue;
model->VDMOSDbvGiven = TRUE; model->VDMOSDbvGiven = TRUE;

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

@ -75,6 +75,9 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
if (!model->VDMOSsubthGiven) { if (!model->VDMOSsubthGiven) {
model->VDMOSsubth = 0; model->VDMOSsubth = 0;
} }
if (!model->VDMOSsubshiftGiven) {
model->VDMOSsubshift = 0;
}
if (!model->VDMOSmtrGiven) { if (!model->VDMOSmtrGiven) {
model->VDMOSmtr = 1.; model->VDMOSmtr = 1.;
} }

Loading…
Cancel
Save