vdmos bulk diode with smart recovery model
This commit is contained in:
parent
19217bf018
commit
b4ecedc616
|
|
@ -31,6 +31,7 @@ IFparm VDMOSpTable[] = { /* parameters */
|
|||
OP( "cgd", VDMOS_CAPGD, IF_REAL, "Gate-Drain capacitance"),
|
||||
OP( "cds", VDMOS_CAPDS, IF_REAL, "Drain-Source capacitance"),
|
||||
OP( "idio", VDMOS_CDIO, IF_REAL, "Body diode current"),
|
||||
OP( "qdio", VDMOS_QDIO, IF_REAL, "Body diode charge"),
|
||||
|
||||
OPU( "dnode", VDMOS_DNODE, IF_INTEGER, "Number of the drain node "),
|
||||
OPU( "gnode", VDMOS_GNODE, IF_INTEGER, "Number of the gate node "),
|
||||
|
|
@ -115,6 +116,8 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
IOP("xti", VDIO_MOD_XTI, IF_REAL, "Body diode saturation current temperature exponent"),
|
||||
IOP("is", VDIO_MOD_IS, IF_REAL, "Body diode saturation current"),
|
||||
IOP("vj", VDIO_MOD_VJ, IF_REAL, "Body diode junction potential"),
|
||||
IOP("vp", VDIO_MOD_VP, IF_REAL, "Soft reverse recovery parameter"),
|
||||
|
||||
|
||||
/* body diode capacitance (e.g. source-drain capacitance) */
|
||||
IOPA("cjo", VDIO_MOD_CJ, IF_REAL, "Zero-bias body diode junction capacitance"),
|
||||
|
|
|
|||
|
|
@ -156,6 +156,20 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->VDMOSSPtempPtr + 1) += xcsT;
|
||||
*(here->VDMOSGPtempPtr + 1) += xcgT;
|
||||
}
|
||||
if ((here->VDIOqpNode > 0) && (model->VDIOsoftRevRecParam!=0) && (here->VDIOtTransitTime!=0)) {
|
||||
/* QP subcircuit */
|
||||
double gdres= *(ckt->CKTstate0 + here->VDIOresConduct);
|
||||
double fac = here->VDIOtTransitTime / model->VDIOsoftRevRecParam;
|
||||
double dcrrdvd = fac * gdres;
|
||||
*(here->VDIOqpQpPtr) += 1/model->VDIOsoftRevRecParam;
|
||||
*(here->VDIOqpQpPtr + 1) += here->VDIOtTransitTime * ckt->CKTomega;
|
||||
*(here->VDIOqpPosPrimePtr) += -dcrrdvd;
|
||||
*(here->VDIOqpNegPtr) += dcrrdvd;
|
||||
/* Gain of VCVS (1-vp)/tau * j*omega*tau = (1-vp) * j*omega */
|
||||
double xgain = (1 - model->VDIOsoftRevRecParam) * ckt->CKTomega;
|
||||
*(here->VDIOposPrimeQpPtr + 1) += xgain;
|
||||
*(here->VDIOnegQpPtr + 1) += -xgain;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,13 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
return(OK);
|
||||
case VDMOS_CDIO:
|
||||
value->rValue = *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||
if ((here->VDIOqpNode > 0) && (here->VDIOtTransitTime!=0))
|
||||
value->rValue += here->VDIOqpGain * *(ckt->CKTstate0 + here->VDIOcqcsr);
|
||||
return(OK);
|
||||
case VDMOS_QDIO:
|
||||
value->rValue = *(ckt->CKTstate0+here->VDIOcapCharge);
|
||||
if ((here->VDIOqpNode > 0) && (here->VDIOtTransitTime!=0))
|
||||
value->rValue += here->VDIOqpGain * *(ckt->CKTstate0 + here->VDIOsrcapCharge);
|
||||
return(OK);
|
||||
case VDMOS_CG :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,14 @@ VDMOSbindCSC (GENmodel *inModel, CKTcircuit *ckt)
|
|||
CREATE_KLU_BINDING_TABLE(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||
CREATE_KLU_BINDING_TABLE(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
||||
}
|
||||
/* rev-rec */
|
||||
if (model->VDIOsoftRevRecParamGiven && model->VDIOsoftRevRecParam!=0 && model->VDIOtransitTime!=0) {
|
||||
CREATE_KLU_BINDING_TABLE(VDIOqpQpPtr , VDIOqpQpBinding , VDIOqpNode, VDIOqpNode);
|
||||
CREATE_KLU_BINDING_TABLE(VDIOqpPosPrimePtr, VDIOqpPosPrimeBinding, VDIOqpNode, VDIOposPrimeNode);
|
||||
CREATE_KLU_BINDING_TABLE(VDIOqpNegPtr , VDIOqpNegBinding , VDIOqpNode, VDMOSdNode);
|
||||
CREATE_KLU_BINDING_TABLE(VDIOposPrimeQpPtr, VDIOposPrimeQpBinding, VDIOposPrimeNode, VDIOqpNode);
|
||||
CREATE_KLU_BINDING_TABLE(VDIOnegQpPtr , VDIOnegQpBinding , VDMOSdNode, VDIOqpNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +163,14 @@ VDMOSbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt)
|
|||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
||||
}
|
||||
/* rev-rec */
|
||||
if (model->VDIOsoftRevRecParamGiven && model->VDIOsoftRevRecParam!=0 && model->VDIOtransitTime!=0) {
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOqpQpPtr , VDIOqpQpBinding , VDIOqpNode, VDIOqpNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOqpPosPrimePtr, VDIOqpPosPrimeBinding, VDIOqpNode, VDIOposPrimeNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOqpNegPtr , VDIOqpNegBinding , VDIOqpNode, VDMOSdNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOposPrimeQpPtr, VDIOposPrimeQpBinding, VDIOposPrimeNode, VDIOqpNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOnegQpPtr , VDIOnegQpBinding , VDMOSdNode, VDIOqpNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +246,14 @@ VDMOSbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt)
|
|||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
||||
}
|
||||
/* rev-rec */
|
||||
if (model->VDIOsoftRevRecParamGiven && model->VDIOsoftRevRecParam!=0 && model->VDIOtransitTime!=0) {
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOqpQpPtr , VDIOqpQpBinding , VDIOqpNode, VDIOqpNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOqpPosPrimePtr, VDIOqpPosPrimeBinding, VDIOqpNode, VDIOposPrimeNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOqpNegPtr , VDIOqpNegBinding , VDIOqpNode, VDMOSdNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOposPrimeQpPtr, VDIOposPrimeQpBinding, VDIOposPrimeNode, VDIOqpNode);
|
||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOnegQpPtr , VDIOnegQpBinding , VDMOSdNode, VDIOqpNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ typedef struct sVDMOSinstance {
|
|||
int VDMOSgNodePrime; /* number of the internal gate node of the mosfet */
|
||||
int VDMOStNodePrime; /* number of the internal temp node between voltage source and Rthca */
|
||||
int VDIOposPrimeNode; /* number of the internal node of the body diode */
|
||||
int VDIOqpNode; /* number of soft recovery charge node */
|
||||
|
||||
int VDMOSvdevTbranch; /* equation number of branch equation added for cktTemp source */
|
||||
|
||||
|
|
@ -97,6 +98,9 @@ typedef struct sVDMOSinstance {
|
|||
double VDIOtF2;
|
||||
double VDIOtF3;
|
||||
|
||||
/* rev-rec */
|
||||
double VDIOqpGain;/* converts iterated diffcharge current */
|
||||
|
||||
double VDMOSTempSH; /* for portability of SH temp to noise analysis */
|
||||
|
||||
double VDMOSgmT;
|
||||
|
|
@ -216,6 +220,13 @@ typedef struct sVDMOSinstance {
|
|||
(source node, diode prime node) */
|
||||
double *VDIORPsPtr; /* pointer to sparse matrix element at
|
||||
(diode prime node, source node) */
|
||||
/* rev-rec */
|
||||
double *VDIOqpQpPtr;
|
||||
double *VDIOqpPosPrimePtr;
|
||||
double *VDIOqpNegPtr;
|
||||
double *VDIOposPrimeQpPtr;
|
||||
double *VDIOnegQpPtr;
|
||||
|
||||
/* self heating */
|
||||
double *VDMOSTemptempPtr; /* Transistor thermal contribution */
|
||||
double *VDMOSTempdpPtr;
|
||||
|
|
@ -290,6 +301,12 @@ typedef struct sVDMOSinstance {
|
|||
BindElement *VDMOSDevTdevTBinding ;
|
||||
BindElement *VDMOSDevTtpBinding ;
|
||||
BindElement *VDMOSTpdevTBinding ;
|
||||
/* rev-rec */
|
||||
BindElement *VDIOqpQpBinding;
|
||||
BindElement *VDIOqpPosPrimeBinding;
|
||||
BindElement *VDIOqpNegBinding;
|
||||
BindElement *VDIOposPrimeQpBinding;
|
||||
BindElement *VDIOnegQpBinding;
|
||||
#endif
|
||||
|
||||
} VDMOSinstance ;
|
||||
|
|
@ -319,8 +336,16 @@ typedef struct sVDMOSinstance {
|
|||
|
||||
#define VDIOdIdio_dT VDMOSstates+ 17
|
||||
|
||||
#define VDMOSnumStates 18
|
||||
/* rev-rec */
|
||||
#define VDIOsrcapCharge VDMOSstates+18
|
||||
#define VDIOsrcapCurrent VDMOSstates+19
|
||||
#define VDIOqp VDMOSstates+20
|
||||
#define VDIOresCurrent VDMOSstates+21
|
||||
#define VDIOresConduct VDMOSstates+22
|
||||
#define VDIOcqcsr VDMOSstates+23
|
||||
#define VDIOgqcsr VDMOSstates+24
|
||||
|
||||
#define VDMOSnumStates 25
|
||||
|
||||
/* per model data */
|
||||
|
||||
|
|
@ -385,6 +410,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
double VDIOgradCoeffTemp2;
|
||||
double VDIOtrb1;
|
||||
double VDIOtrb2;
|
||||
double VDIOsoftRevRecParam; /* Soft reverse recovery parameter VP */
|
||||
|
||||
double VDMOStcvth;
|
||||
double VDMOSrthjc;
|
||||
|
|
@ -482,6 +508,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
unsigned VDMOSid_maxGiven :1;
|
||||
unsigned VDMOSidr_maxGiven :1;
|
||||
unsigned VDMOSderatingGiven :1;
|
||||
unsigned VDIOsoftRevRecParamGiven : 1;
|
||||
} VDMOSmodel;
|
||||
|
||||
#ifndef NMOS
|
||||
|
|
@ -546,6 +573,7 @@ enum {
|
|||
VDIO_MOD_XTI,
|
||||
VDIO_MOD_TRB1,
|
||||
VDIO_MOD_TRB2,
|
||||
VDIO_MOD_VP,
|
||||
VDMOS_MOD_TCVTH,
|
||||
VDMOS_MOD_RTHJC,
|
||||
VDMOS_MOD_RTHCA,
|
||||
|
|
@ -599,6 +627,7 @@ enum {
|
|||
VDMOS_QGD,
|
||||
VDMOS_CQGD,
|
||||
VDMOS_CDIO,
|
||||
VDMOS_QDIO,
|
||||
VDMOS_SOURCERESIST,
|
||||
VDMOS_DRAINRESIST,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -710,11 +710,17 @@ bypass:
|
|||
double Ith=0.0, dIth_dT=0.0;
|
||||
double dIdio_dT=0.0, dIth_dVdio=0.0;
|
||||
double vrb=0.0, dIrb_dT=0.0, dIth_dVrb=0.0;
|
||||
/* rev-rec */
|
||||
double cdres, gdres;
|
||||
double vqp;
|
||||
double capsr, gqcsr, cqcsr;
|
||||
|
||||
#ifndef NOBYPASS
|
||||
double tol; /* temporary for tolerance calculations */
|
||||
#endif
|
||||
|
||||
int revrec = ((here->VDIOqpNode > 0) && (model->VDIOsoftRevRecParam!=0) && (here->VDIOtTransitTime!=0));
|
||||
|
||||
gbpr = here->VDIOtConductance;
|
||||
|
||||
vt = CONSTKoverQ * Temp;
|
||||
|
|
@ -725,13 +731,17 @@ bypass:
|
|||
Check_dio = 1;
|
||||
if (ckt->CKTmode & MODEINITSMSIG) {
|
||||
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
vqp = *(ckt->CKTstate0 + here->VDIOqp);
|
||||
} else if (ckt->CKTmode & MODEINITTRAN) {
|
||||
vd = *(ckt->CKTstate1 + here->VDIOvoltage);
|
||||
vqp = *(ckt->CKTstate1 + here->VDIOqp);
|
||||
} else if ((ckt->CKTmode & MODEINITJCT) &&
|
||||
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {
|
||||
vd = here->VDIOinitCond;
|
||||
vqp=0;
|
||||
} else if (ckt->CKTmode & MODEINITJCT) {
|
||||
vd = here->VDIOtVcrit;
|
||||
vqp=0;
|
||||
} else {
|
||||
#ifndef PREDICTOR
|
||||
if (ckt->CKTmode & MODEINITPRED) {
|
||||
|
|
@ -744,10 +754,20 @@ bypass:
|
|||
*(ckt->CKTstate1 + here->VDIOconduct);
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) =
|
||||
*(ckt->CKTstate1 + here->VDIOdIdio_dT);
|
||||
vqp = DEVpred(ckt,here->VDIOqp);
|
||||
*(ckt->CKTstate0 + here->VDIOresCurrent) =
|
||||
*(ckt->CKTstate1 + here->VDIOresCurrent);
|
||||
*(ckt->CKTstate0 + here->VDIOresConduct) =
|
||||
*(ckt->CKTstate1 + here->VDIOresConduct);
|
||||
*(ckt->CKTstate0 + here->VDIOcqcsr) =
|
||||
*(ckt->CKTstate1 + here->VDIOcqcsr);
|
||||
*(ckt->CKTstate0 + here->VDIOgqcsr) =
|
||||
*(ckt->CKTstate1 + here->VDIOgqcsr);
|
||||
} else {
|
||||
#endif /* PREDICTOR */
|
||||
vd = model->VDMOStype * (*(ckt->CKTrhsOld + here->VDIOposPrimeNode) -
|
||||
*(ckt->CKTrhsOld + here->VDMOSdNode));
|
||||
vqp = model->VDMOStype * *(ckt->CKTrhsOld+here->VDIOqpNode);
|
||||
#ifndef PREDICTOR
|
||||
}
|
||||
#endif /* PREDICTOR */
|
||||
|
|
@ -776,6 +796,11 @@ bypass:
|
|||
cd = *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||
gd = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||
dIdio_dT= *(ckt->CKTstate0 + here->VDIOdIdio_dT);
|
||||
vqp= *(ckt->CKTstate0 + here->VDIOqp);
|
||||
cdres= *(ckt->CKTstate0 + here->VDIOresCurrent);
|
||||
gdres= *(ckt->CKTstate0 + here->VDIOresConduct);
|
||||
cqcsr= *(ckt->CKTstate0 + here->VDIOcqcsr);
|
||||
gqcsr= *(ckt->CKTstate0 + here->VDIOgqcsr);
|
||||
goto load;
|
||||
}
|
||||
}
|
||||
|
|
@ -833,6 +858,10 @@ bypass:
|
|||
|
||||
cd = cdb + ckt->CKTgmin*vd;
|
||||
gd = gdb + ckt->CKTgmin;
|
||||
cdres = cd;
|
||||
gdres = gd;
|
||||
cqcsr = 0;
|
||||
gqcsr = 0;
|
||||
|
||||
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) ||
|
||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
|
||||
|
|
@ -853,14 +882,35 @@ bypass:
|
|||
(here->VDIOtGradingCoeff / (here->VDIOtJctPot + here->VDIOtJctPot))*(vd*vd - here->VDIOtDepCap*here->VDIOtDepCap));
|
||||
deplcap = czof2*(here->VDIOtF3 + here->VDIOtGradingCoeff*vd / here->VDIOtJctPot);
|
||||
}
|
||||
diffcharge = here->VDIOtTransitTime*cdb;
|
||||
*(ckt->CKTstate0 + here->VDIOcapCharge) =
|
||||
diffcharge + deplcharge;
|
||||
|
||||
diffcap = here->VDIOtTransitTime*gdb;
|
||||
capd = diffcap + deplcap;
|
||||
if (revrec) {
|
||||
/*
|
||||
soft recovery with TT!=0 - add only depletion capacitance.
|
||||
*/
|
||||
*(ckt->CKTstate0 + here->VDIOcapCharge) = deplcharge;
|
||||
|
||||
here->VDIOcap = capd;
|
||||
capd = deplcap;
|
||||
here->VDIOcap = capd;
|
||||
/*
|
||||
DIOcap is now equal only to depletion capacitance + overlap capacitance.
|
||||
Diffusion capacitance is modelled via Qp so there is no clear way to define it here.
|
||||
Now prepare the charge for the capacitor connected to the QP node
|
||||
*/
|
||||
*(ckt->CKTstate0 + here->VDIOsrcapCharge) = here->VDIOtTransitTime * vqp;
|
||||
capsr = here->VDIOtTransitTime;
|
||||
} else {
|
||||
/*
|
||||
no soft recovery due to TT=0
|
||||
*/
|
||||
diffcharge = here->VDIOtTransitTime*cdb;
|
||||
diffcap = here->VDIOtTransitTime*gdb;
|
||||
*(ckt->CKTstate0 + here->VDIOcapCharge) = diffcharge + deplcharge;
|
||||
capd = diffcap + deplcap;
|
||||
here->VDIOcap = capd;
|
||||
|
||||
*(ckt->CKTstate0 + here->VDIOsrcapCharge) = 0;
|
||||
capsr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* store small-signal parameters
|
||||
|
|
@ -869,6 +919,7 @@ bypass:
|
|||
(!(ckt->CKTmode & MODEUIC))) {
|
||||
if (ckt->CKTmode & MODEINITSMSIG) {
|
||||
*(ckt->CKTstate0 + here->VDIOcapCurrent) = capd;
|
||||
*(ckt->CKTstate0 + here->VDIOresConduct) = gdres;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -889,6 +940,21 @@ bypass:
|
|||
*(ckt->CKTstate1 + here->VDIOcapCurrent) =
|
||||
*(ckt->CKTstate0 + here->VDIOcapCurrent);
|
||||
}
|
||||
if (revrec) {
|
||||
/* soft recovery subcircuit */
|
||||
if (ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->VDIOsrcapCharge) =
|
||||
*(ckt->CKTstate0 + here->VDIOsrcapCharge);
|
||||
}
|
||||
error = NIintegrate(ckt,&geq,&ceq,capsr,here->VDIOsrcapCharge);
|
||||
if(error) return(error);
|
||||
gqcsr = geq;
|
||||
cqcsr = *(ckt->CKTstate0 + here->VDIOsrcapCurrent);
|
||||
if (ckt->CKTmode & MODEINITTRAN) {
|
||||
*(ckt->CKTstate1 + here->VDIOsrcapCurrent) =
|
||||
*(ckt->CKTstate0 + here->VDIOsrcapCurrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -905,6 +971,11 @@ bypass:
|
|||
*(ckt->CKTstate0 + here->VDIOcurrent) = cd;
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) = gd;
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) = dIdio_dT;
|
||||
*(ckt->CKTstate0 + here->VDIOqp) = vqp;
|
||||
*(ckt->CKTstate0 + here->VDIOresCurrent) = cdres;
|
||||
*(ckt->CKTstate0 + here->VDIOresConduct) = gdres;
|
||||
*(ckt->CKTstate0 + here->VDIOcqcsr) = cqcsr;
|
||||
*(ckt->CKTstate0 + here->VDIOgqcsr) = gqcsr;
|
||||
|
||||
#ifndef NOBYPASS
|
||||
load:
|
||||
|
|
@ -926,14 +997,10 @@ load:
|
|||
/*
|
||||
* load current vector
|
||||
*/
|
||||
cdeq = cd - gd*vd;
|
||||
if (model->VDMOStype == 1) {
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) += cdeq;
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq;
|
||||
} else {
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) -= cdeq;
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += cdeq;
|
||||
}
|
||||
cdeq = model->VDMOStype * (cd - gd*vd);
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) += cdeq;
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq;
|
||||
|
||||
if (selfheat) {
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += dIdio_dT*delTemp - dIrb_dT*delTemp;
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) += -dIdio_dT*delTemp;
|
||||
|
|
@ -959,6 +1026,26 @@ load:
|
|||
(*(here->VDMOSStempPtr) += dIrb_dT);
|
||||
(*(here->VDMOSDtempPtr) += -dIdio_dT);
|
||||
}
|
||||
if (revrec) {
|
||||
/* QP subcircuit */
|
||||
double fac = here->VDIOtTransitTime / model->VDIOsoftRevRecParam;
|
||||
double dcrrdvd = fac*gdres;
|
||||
double ceqrr = -fac*cdres + cqcsr + dcrrdvd*vd - gqcsr*vqp;
|
||||
double grr = 1/model->VDIOsoftRevRecParam;
|
||||
*(ckt->CKTrhs + here->VDIOqpNode) -= model->VDMOStype * ceqrr;
|
||||
*(here->VDIOqpQpPtr) += grr + gqcsr;
|
||||
*(here->VDIOqpPosPrimePtr) += -dcrrdvd;
|
||||
*(here->VDIOqpNegPtr) += dcrrdvd;
|
||||
/* Contribution to diode current */
|
||||
here->VDIOqpGain = (1 - model->VDIOsoftRevRecParam) / here->VDIOtTransitTime;
|
||||
/* Linear contribution -(1-vp)/tau*ddt(Qp) */
|
||||
double geqrrd = here->VDIOqpGain*gqcsr;
|
||||
double ceqrrd = model->VDMOStype * (here->VDIOqpGain*cqcsr - geqrrd*vqp);
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += -ceqrrd;
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) += ceqrrd;
|
||||
*(here->VDIOposPrimeQpPtr) += geqrrd;
|
||||
*(here->VDIOnegQpPtr) += -geqrrd;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -182,6 +182,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_TKSUBTHRES2:
|
||||
value->rValue = model->VDMOStksubthres2;
|
||||
return(OK);
|
||||
case VDIO_MOD_VP:
|
||||
value->rValue = model->VDIOsoftRevRecParam;
|
||||
return(OK);
|
||||
/* SOA */
|
||||
case VDMOS_MOD_VGS_MAX:
|
||||
value->rValue = model->VDMOSvgsMax;
|
||||
|
|
|
|||
|
|
@ -166,6 +166,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDIOtranTimeTemp1 = 0;
|
||||
model->VDIOtranTimeTemp2 = 0;
|
||||
break;
|
||||
case VDIO_MOD_VP:
|
||||
model->VDIOsoftRevRecParam = value->rValue;
|
||||
model->VDIOsoftRevRecParamGiven = TRUE;
|
||||
break;
|
||||
case VDIO_MOD_EG:
|
||||
model->VDIOeg = value->rValue;
|
||||
model->VDIOegGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -251,6 +251,10 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if (model->VDIOjctSatCur < ckt->CKTepsmin)
|
||||
model->VDIOjctSatCur = ckt->CKTepsmin;
|
||||
|
||||
if (!model->VDIOsoftRevRecParamGiven) {
|
||||
model->VDIOsoftRevRecParam = 0.0;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = VDMOSinstances(model); here != NULL;
|
||||
here = VDMOSnextInstance(here)) {
|
||||
|
|
@ -431,6 +435,16 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
here->VDMOStcaseNode = 0;
|
||||
}
|
||||
|
||||
/* rev-rec */
|
||||
if (model->VDIOsoftRevRecParamGiven && model->VDIOsoftRevRecParam!=0 && model->VDIOtransitTime!=0) {
|
||||
if(here->VDIOqpNode == 0) {
|
||||
error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "qp");
|
||||
if(error) return(error);
|
||||
here->VDIOqpNode = tmp->number;
|
||||
}
|
||||
} else {
|
||||
here->VDIOqpNode = 0;
|
||||
}
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||
|
|
@ -487,11 +501,20 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
TSTALLOC(VDMOSTemptcasePtr, VDMOStempNode, VDMOStcaseNode);
|
||||
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
||||
TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStcaseNode);
|
||||
TSTALLOC(VDMOSTcasetpPtr, VDMOStcaseNode, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSTcasetpPtr, VDMOStcaseNode, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSDevTdevTPtr, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=cktTemp to gnd */
|
||||
TSTALLOC(VDMOSDevTtpPtr, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSTpdevTPtr, VDMOStNodePrime, VDMOSvdevTbranch);
|
||||
}
|
||||
|
||||
/* rev-rec */
|
||||
if (model->VDIOsoftRevRecParamGiven && model->VDIOsoftRevRecParam!=0 && model->VDIOtransitTime!=0) {
|
||||
TSTALLOC(VDIOqpQpPtr , VDIOqpNode, VDIOqpNode);
|
||||
TSTALLOC(VDIOqpPosPrimePtr, VDIOqpNode, VDIOposPrimeNode);
|
||||
TSTALLOC(VDIOqpNegPtr , VDIOqpNode, VDMOSdNode);
|
||||
TSTALLOC(VDIOposPrimeQpPtr, VDIOposPrimeNode, VDIOqpNode);
|
||||
TSTALLOC(VDIOnegQpPtr, VDMOSdNode, VDIOqpNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
@ -538,6 +561,10 @@ VDMOSunsetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
here->VDMOSvdevTbranch = 0;
|
||||
}
|
||||
|
||||
/* rev-rec */
|
||||
if (here->VDIOqpNode > 0)
|
||||
CKTdltNNum(ckt, here->VDIOqpNode);
|
||||
here->VDIOqpNode = 0;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ VDMOStrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
|||
CKTterr(here->VDMOSqgs,ckt,timeStep);
|
||||
CKTterr(here->VDMOSqgd,ckt,timeStep);
|
||||
CKTterr(here->VDIOcapCharge,ckt,timeStep);
|
||||
if (model->VDIOsoftRevRecParam!=0 && here->VDIOtTransitTime!=0)
|
||||
CKTterr(here->VDIOsrcapCharge,ckt,timeStep);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
Loading…
Reference in New Issue