Browse Source

Introducing mobility reduction over Vgs. Model parameter: theta

pre-master-46
dwarning 7 years ago
committed by Holger Vogt
parent
commit
8b424dd3d3
  1. 1
      src/spicelib/devices/vdmos/vdmos.c
  2. 4
      src/spicelib/devices/vdmos/vdmosdefs.h
  3. 39
      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

@ -64,6 +64,7 @@ IFparm VDMOSmPTable[] = { /* model parameters */
IOP("kp", VDMOS_MOD_KP, IF_REAL, "Transconductance parameter"), IOP("kp", VDMOS_MOD_KP, IF_REAL, "Transconductance parameter"),
IOP("phi", VDMOS_MOD_PHI, IF_REAL, "Surface potential"), IOP("phi", VDMOS_MOD_PHI, IF_REAL, "Surface potential"),
IOP("lambda",VDMOS_MOD_LAMBDA,IF_REAL, "Channel length modulation"), IOP("lambda",VDMOS_MOD_LAMBDA,IF_REAL, "Channel length modulation"),
IOP("theta", VDMOS_MOD_THETA, IF_REAL, "Vgs dependence on mobility"),
IOP("rd", VDMOS_MOD_RD, IF_REAL, "Drain ohmic resistance"), IOP("rd", VDMOS_MOD_RD, IF_REAL, "Drain ohmic resistance"),
IOP("rs", VDMOS_MOD_RS, IF_REAL, "Source ohmic resistance"), IOP("rs", VDMOS_MOD_RS, IF_REAL, "Source ohmic resistance"),
IOP("rg", VDMOS_MOD_RG, IF_REAL, "Gate ohmic resistance"), IOP("rg", VDMOS_MOD_RG, IF_REAL, "Gate ohmic resistance"),

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

@ -265,8 +265,10 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
double VDMOSvt0; /* input - use tVto */ double VDMOSvt0; /* input - use tVto */
double VDMOSphi; /* input - use tPhi */ double VDMOSphi; /* input - use tPhi */
double VDMOSlambda; double VDMOSlambda;
double VDMOStheta;
double VDMOSfNcoef; double VDMOSfNcoef;
double VDMOSfNexp; double VDMOSfNexp;
double VDMOScgdmin; double VDMOScgdmin;
double VDMOScgdmax; double VDMOScgdmax;
double VDMOSa; double VDMOSa;
@ -313,6 +315,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
unsigned VDIOdepletionCapCoeffGiven :1; unsigned VDIOdepletionCapCoeffGiven :1;
unsigned VDMOSphiGiven :1; unsigned VDMOSphiGiven :1;
unsigned VDMOSlambdaGiven :1; unsigned VDMOSlambdaGiven :1;
unsigned VDMOSthetaGiven :1;
unsigned VDMOStnomGiven :1; unsigned VDMOStnomGiven :1;
unsigned VDMOSfNcoefGiven :1; unsigned VDMOSfNcoefGiven :1;
unsigned VDMOSfNexpGiven :1; unsigned VDMOSfNexpGiven :1;
@ -367,6 +370,7 @@ enum {
VDMOS_MOD_KP, VDMOS_MOD_KP,
VDMOS_MOD_PHI, VDMOS_MOD_PHI,
VDMOS_MOD_LAMBDA, VDMOS_MOD_LAMBDA,
VDMOS_MOD_THETA,
VDMOS_MOD_RD, VDMOS_MOD_RD,
VDMOS_MOD_RS, VDMOS_MOD_RS,
VDMOS_MOD_RG, VDMOS_MOD_RG,

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

@ -282,53 +282,58 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
*/ */
double betap; double betap;
double vgst; double vgst;
double onfg, fgate, Betam, dfgdvg;
von = (model->VDMOSvt0*model->VDMOStype); von = (model->VDMOSvt0*model->VDMOStype);
vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von; vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
vdsat = MAX(vgst, 0); vdsat = MAX(vgst, 0);
onfg = 1.0+model->VDMOStheta*vgst;
fgate = 1.0/onfg;
Betam = Beta * fgate;
dfgdvg = -model->VDMOStheta*fgate*fgate;
/* drain current including subthreshold current /* drain current including subthreshold current
* 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->VDMOSksubthresGiven && (here->VDMOSmode == 1)) { if (model->VDMOSksubthresGiven && (here->VDMOSmode == 1)) {
double delta = 0.001; double delta = 0.001;
cdrain = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda, cdrain = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
/* gd */ /* gd */
double vds1 = vds + delta; double vds1 = vds + delta;
double cdrp = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, double cdrp = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
vds1 = vds - delta; vds1 = vds - delta;
double cdrm = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, double cdrm = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, 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->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, cdrp = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
vgst1 = vgst - delta; vgst1 = vgst - delta;
cdrm = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, cdrm = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
Betam, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta) * fgate + dfgdvg * cdrain;
} }
else if (model->VDMOSsubslGiven && (here->VDMOSmode == 1)) { else if (model->VDMOSsubslGiven && (here->VDMOSmode == 1)) {
double delta = 0.001; double delta = 0.001;
cdrain = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda, cdrain = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
/* gd */ /* gd */
double vds1 = vds + delta; double vds1 = vds + delta;
double cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, double cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
vds1 = vds - delta; vds1 = vds - delta;
double cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, double cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, 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 = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
Betam, vt, model->VDMOSmtr);
vgst1 = vgst - delta; vgst1 = vgst - delta;
cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
Betam, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta) * fgate + dfgdvg * cdrain;
} else { } else {
if (vgst <= 0) { if (vgst <= 0) {
/* /*
@ -343,20 +348,20 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
*/ */
/* scale vds with mtr */ /* scale vds with mtr */
double mtr = model->VDMOSmtr; double mtr = model->VDMOSmtr;
betap = Beta*(1 + model->VDMOSlambda*(vds*here->VDMOSmode));
betap = Betam*(1 + model->VDMOSlambda*(vds*here->VDMOSmode));
if (vgst <= (vds * here->VDMOSmode) * mtr) { if (vgst <= (vds * here->VDMOSmode) * mtr) {
cdrain = betap*vgst*vgst*.5; cdrain = betap*vgst*vgst*.5;
here->VDMOSgm = betap*vgst;
here->VDMOSgds = model->VDMOSlambda*Beta*vgst*vgst*.5;
here->VDMOSgm = betap*vgst * fgate + dfgdvg * cdrain;
here->VDMOSgds = model->VDMOSlambda*Betam*vgst*vgst*.5;
} else { } else {
/* /*
* linear region * linear region
*/ */
cdrain = betap * (vds * here->VDMOSmode) * mtr * cdrain = betap * (vds * here->VDMOSmode) * mtr *
(vgst - .5 * (vds*here->VDMOSmode) * mtr); (vgst - .5 * (vds*here->VDMOSmode) * mtr);
here->VDMOSgm = betap * (vds * here->VDMOSmode) * mtr;
here->VDMOSgm = betap * (vds * here->VDMOSmode) * mtr * fgate + dfgdvg * cdrain;
here->VDMOSgds = betap * (vgst - (vds * here->VDMOSmode) * mtr) + here->VDMOSgds = betap * (vgst - (vds * here->VDMOSmode) * mtr) +
model->VDMOSlambda * Beta *
model->VDMOSlambda * Betam *
(vds * here->VDMOSmode) * mtr * (vds * here->VDMOSmode) * mtr *
(vgst - .5 * (vds * here->VDMOSmode) * mtr); (vgst - .5 * (vds * here->VDMOSmode) * mtr);
} }

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

@ -36,6 +36,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
case VDMOS_MOD_LAMBDA: case VDMOS_MOD_LAMBDA:
value->rValue = model->VDMOSlambda; value->rValue = model->VDMOSlambda;
return(OK); return(OK);
case VDMOS_MOD_THETA:
value->rValue = model->VDMOStheta;
return(OK);
case VDMOS_MOD_RD: case VDMOS_MOD_RD:
value->rValue = model->VDMOSdrainResistance; value->rValue = model->VDMOSdrainResistance;
return(OK); return(OK);

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

@ -35,6 +35,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
model->VDMOSlambda = value->rValue; model->VDMOSlambda = value->rValue;
model->VDMOSlambdaGiven = TRUE; model->VDMOSlambdaGiven = TRUE;
break; break;
case VDMOS_MOD_THETA:
model->VDMOStheta = value->rValue;
model->VDMOSthetaGiven = TRUE;
break;
case VDMOS_MOD_RD: case VDMOS_MOD_RD:
model->VDMOSdrainResistance = value->rValue; model->VDMOSdrainResistance = value->rValue;
model->VDMOSdrainResistanceGiven = TRUE; model->VDMOSdrainResistanceGiven = TRUE;

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

@ -54,6 +54,9 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
if (!model->VDMOSlambdaGiven) { if (!model->VDMOSlambdaGiven) {
model->VDMOSlambda = 0; model->VDMOSlambda = 0;
} }
if (!model->VDMOSthetaGiven) {
model->VDMOStheta = 0;
}
if (!model->VDMOSfNcoefGiven) { if (!model->VDMOSfNcoefGiven) {
model->VDMOSfNcoef = 0; model->VDMOSfNcoef = 0;
} }

Loading…
Cancel
Save