From 8b424dd3d3e0b88e56da4885ec5857b4f5252d65 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sun, 25 Nov 2018 00:53:39 +0100 Subject: [PATCH] Introducing mobility reduction over Vgs. Model parameter: theta --- src/spicelib/devices/vdmos/vdmos.c | 1 + src/spicelib/devices/vdmos/vdmosdefs.h | 4 +++ src/spicelib/devices/vdmos/vdmosload.c | 39 +++++++++++++++----------- src/spicelib/devices/vdmos/vdmosmask.c | 3 ++ src/spicelib/devices/vdmos/vdmosmpar.c | 4 +++ src/spicelib/devices/vdmos/vdmosset.c | 3 ++ 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/spicelib/devices/vdmos/vdmos.c b/src/spicelib/devices/vdmos/vdmos.c index b722a89c5..afe09e7ac 100644 --- a/src/spicelib/devices/vdmos/vdmos.c +++ b/src/spicelib/devices/vdmos/vdmos.c @@ -64,6 +64,7 @@ IFparm VDMOSmPTable[] = { /* model parameters */ IOP("kp", VDMOS_MOD_KP, IF_REAL, "Transconductance parameter"), IOP("phi", VDMOS_MOD_PHI, IF_REAL, "Surface potential"), 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("rs", VDMOS_MOD_RS, IF_REAL, "Source ohmic resistance"), IOP("rg", VDMOS_MOD_RG, IF_REAL, "Gate ohmic resistance"), diff --git a/src/spicelib/devices/vdmos/vdmosdefs.h b/src/spicelib/devices/vdmos/vdmosdefs.h index deb4f2739..e896021c4 100644 --- a/src/spicelib/devices/vdmos/vdmosdefs.h +++ b/src/spicelib/devices/vdmos/vdmosdefs.h @@ -265,8 +265,10 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */ double VDMOSvt0; /* input - use tVto */ double VDMOSphi; /* input - use tPhi */ double VDMOSlambda; + double VDMOStheta; double VDMOSfNcoef; double VDMOSfNexp; + double VDMOScgdmin; double VDMOScgdmax; double VDMOSa; @@ -313,6 +315,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */ unsigned VDIOdepletionCapCoeffGiven :1; unsigned VDMOSphiGiven :1; unsigned VDMOSlambdaGiven :1; + unsigned VDMOSthetaGiven :1; unsigned VDMOStnomGiven :1; unsigned VDMOSfNcoefGiven :1; unsigned VDMOSfNexpGiven :1; @@ -367,6 +370,7 @@ enum { VDMOS_MOD_KP, VDMOS_MOD_PHI, VDMOS_MOD_LAMBDA, + VDMOS_MOD_THETA, VDMOS_MOD_RD, VDMOS_MOD_RS, VDMOS_MOD_RG, diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index 2cfcb78c2..a322cb989 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -282,53 +282,58 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) */ double betap; double vgst; + double onfg, fgate, Betam, dfgdvg; von = (model->VDMOSvt0*model->VDMOStype); vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von; 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 * numerical differentiation for gd and gm with a delta of 2 mV */ if (model->VDMOSksubthresGiven && (here->VDMOSmode == 1)) { double delta = 0.001; cdrain = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); /* gd */ double vds1 = vds + delta; double cdrp = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); vds1 = vds - delta; 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); /* gm */ double vgst1 = vgst + delta; cdrp = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); vgst1 = vgst - delta; 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)) { double delta = 0.001; cdrain = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); /* gd */ double vds1 = vds + delta; double cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst, vds1, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); vds1 = vds - delta; 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); /* gm */ double vgst1 = vgst + delta; cdrp = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda, - Beta, vt, model->VDMOSmtr); + Betam, vt, model->VDMOSmtr); vgst1 = vgst - delta; 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 { if (vgst <= 0) { /* @@ -343,20 +348,20 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) */ /* scale vds with mtr */ 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) { 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 { /* * linear region */ cdrain = betap * (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) + - model->VDMOSlambda * Beta * + model->VDMOSlambda * Betam * (vds * here->VDMOSmode) * mtr * (vgst - .5 * (vds * here->VDMOSmode) * mtr); } diff --git a/src/spicelib/devices/vdmos/vdmosmask.c b/src/spicelib/devices/vdmos/vdmosmask.c index c45edd65e..c5fe055c4 100644 --- a/src/spicelib/devices/vdmos/vdmosmask.c +++ b/src/spicelib/devices/vdmos/vdmosmask.c @@ -36,6 +36,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) case VDMOS_MOD_LAMBDA: value->rValue = model->VDMOSlambda; return(OK); + case VDMOS_MOD_THETA: + value->rValue = model->VDMOStheta; + return(OK); case VDMOS_MOD_RD: value->rValue = model->VDMOSdrainResistance; return(OK); diff --git a/src/spicelib/devices/vdmos/vdmosmpar.c b/src/spicelib/devices/vdmos/vdmosmpar.c index e44d4f730..14ef1fb1c 100644 --- a/src/spicelib/devices/vdmos/vdmosmpar.c +++ b/src/spicelib/devices/vdmos/vdmosmpar.c @@ -35,6 +35,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel) model->VDMOSlambda = value->rValue; model->VDMOSlambdaGiven = TRUE; break; + case VDMOS_MOD_THETA: + model->VDMOStheta = value->rValue; + model->VDMOSthetaGiven = TRUE; + break; case VDMOS_MOD_RD: model->VDMOSdrainResistance = value->rValue; model->VDMOSdrainResistanceGiven = TRUE; diff --git a/src/spicelib/devices/vdmos/vdmosset.c b/src/spicelib/devices/vdmos/vdmosset.c index cc8aefba2..4fb7a2017 100644 --- a/src/spicelib/devices/vdmos/vdmosset.c +++ b/src/spicelib/devices/vdmos/vdmosset.c @@ -54,6 +54,9 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if (!model->VDMOSlambdaGiven) { model->VDMOSlambda = 0; } + if (!model->VDMOSthetaGiven) { + model->VDMOStheta = 0; + } if (!model->VDMOSfNcoefGiven) { model->VDMOSfNcoef = 0; }