vdmos with soft recovery body diode
This commit is contained in:
parent
f7ef88b637
commit
e590b456a8
|
|
@ -31,6 +31,7 @@ IFparm VDMOSpTable[] = { /* parameters */
|
||||||
OP( "cgd", VDMOS_CAPGD, IF_REAL, "Gate-Drain capacitance"),
|
OP( "cgd", VDMOS_CAPGD, IF_REAL, "Gate-Drain capacitance"),
|
||||||
OP( "cds", VDMOS_CAPDS, IF_REAL, "Drain-Source capacitance"),
|
OP( "cds", VDMOS_CAPDS, IF_REAL, "Drain-Source capacitance"),
|
||||||
OP( "idio", VDMOS_CDIO, IF_REAL, "Body diode current"),
|
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( "dnode", VDMOS_DNODE, IF_INTEGER, "Number of the drain node "),
|
||||||
OPU( "gnode", VDMOS_GNODE, IF_INTEGER, "Number of the gate 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("xti", VDIO_MOD_XTI, IF_REAL, "Body diode saturation current temperature exponent"),
|
||||||
IOP("is", VDIO_MOD_IS, IF_REAL, "Body diode saturation current"),
|
IOP("is", VDIO_MOD_IS, IF_REAL, "Body diode saturation current"),
|
||||||
IOP("vj", VDIO_MOD_VJ, IF_REAL, "Body diode junction potential"),
|
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) */
|
/* body diode capacitance (e.g. source-drain capacitance) */
|
||||||
IOPA("cjo", VDIO_MOD_CJ, IF_REAL, "Zero-bias body diode junction 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->VDMOSSPtempPtr + 1) += xcsT;
|
||||||
*(here->VDMOSGPtempPtr + 1) += xcgT;
|
*(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);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,13 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
||||||
return(OK);
|
return(OK);
|
||||||
case VDMOS_CDIO:
|
case VDMOS_CDIO:
|
||||||
value->rValue = *(ckt->CKTstate0 + here->VDIOcurrent);
|
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 += *(ckt->CKTstate0 + here->VDIOsrcapCharge);
|
||||||
return(OK);
|
return(OK);
|
||||||
case VDMOS_CG :
|
case VDMOS_CG :
|
||||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
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(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||||
CREATE_KLU_BINDING_TABLE(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
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(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||||
CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
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(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||||
CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch);
|
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 VDMOSgNodePrime; /* number of the internal gate node of the mosfet */
|
||||||
int VDMOStNodePrime; /* number of the internal temp node between voltage source and Rthca */
|
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 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 */
|
int VDMOSvdevTbranch; /* equation number of branch equation added for cktTemp source */
|
||||||
|
|
||||||
|
|
@ -97,6 +98,9 @@ typedef struct sVDMOSinstance {
|
||||||
double VDIOtF2;
|
double VDIOtF2;
|
||||||
double VDIOtF3;
|
double VDIOtF3;
|
||||||
|
|
||||||
|
/* rev-rec */
|
||||||
|
double VDIOqpGain;/* converts iterated diffcharge current */
|
||||||
|
|
||||||
double VDMOSTempSH; /* for portability of SH temp to noise analysis */
|
double VDMOSTempSH; /* for portability of SH temp to noise analysis */
|
||||||
|
|
||||||
double VDMOSgmT;
|
double VDMOSgmT;
|
||||||
|
|
@ -216,6 +220,13 @@ typedef struct sVDMOSinstance {
|
||||||
(source node, diode prime node) */
|
(source node, diode prime node) */
|
||||||
double *VDIORPsPtr; /* pointer to sparse matrix element at
|
double *VDIORPsPtr; /* pointer to sparse matrix element at
|
||||||
(diode prime node, source node) */
|
(diode prime node, source node) */
|
||||||
|
/* rev-rec */
|
||||||
|
double *VDIOqpQpPtr;
|
||||||
|
double *VDIOqpPosPrimePtr;
|
||||||
|
double *VDIOqpNegPtr;
|
||||||
|
double *VDIOposPrimeQpPtr;
|
||||||
|
double *VDIOnegQpPtr;
|
||||||
|
|
||||||
/* self heating */
|
/* self heating */
|
||||||
double *VDMOSTemptempPtr; /* Transistor thermal contribution */
|
double *VDMOSTemptempPtr; /* Transistor thermal contribution */
|
||||||
double *VDMOSTempdpPtr;
|
double *VDMOSTempdpPtr;
|
||||||
|
|
@ -290,6 +301,12 @@ typedef struct sVDMOSinstance {
|
||||||
BindElement *VDMOSDevTdevTBinding ;
|
BindElement *VDMOSDevTdevTBinding ;
|
||||||
BindElement *VDMOSDevTtpBinding ;
|
BindElement *VDMOSDevTtpBinding ;
|
||||||
BindElement *VDMOSTpdevTBinding ;
|
BindElement *VDMOSTpdevTBinding ;
|
||||||
|
/* rev-rec */
|
||||||
|
BindElement *VDIOqpQpBinding;
|
||||||
|
BindElement *VDIOqpPosPrimeBinding;
|
||||||
|
BindElement *VDIOqpNegBinding;
|
||||||
|
BindElement *VDIOposPrimeQpBinding;
|
||||||
|
BindElement *VDIOnegQpBinding;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} VDMOSinstance ;
|
} VDMOSinstance ;
|
||||||
|
|
@ -319,8 +336,16 @@ typedef struct sVDMOSinstance {
|
||||||
|
|
||||||
#define VDIOdIdio_dT VDMOSstates+ 17
|
#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 */
|
/* per model data */
|
||||||
|
|
||||||
|
|
@ -385,6 +410,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
||||||
double VDIOgradCoeffTemp2;
|
double VDIOgradCoeffTemp2;
|
||||||
double VDIOtrb1;
|
double VDIOtrb1;
|
||||||
double VDIOtrb2;
|
double VDIOtrb2;
|
||||||
|
double VDIOsoftRevRecParam; /* Soft reverse recovery parameter */
|
||||||
|
|
||||||
double VDMOStcvth;
|
double VDMOStcvth;
|
||||||
double VDMOSrthjc;
|
double VDMOSrthjc;
|
||||||
|
|
@ -482,6 +508,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
||||||
unsigned VDMOSid_maxGiven :1;
|
unsigned VDMOSid_maxGiven :1;
|
||||||
unsigned VDMOSidr_maxGiven :1;
|
unsigned VDMOSidr_maxGiven :1;
|
||||||
unsigned VDMOSderatingGiven :1;
|
unsigned VDMOSderatingGiven :1;
|
||||||
|
unsigned VDIOsoftRevRecParamGiven : 1;
|
||||||
} VDMOSmodel;
|
} VDMOSmodel;
|
||||||
|
|
||||||
#ifndef NMOS
|
#ifndef NMOS
|
||||||
|
|
@ -546,6 +573,7 @@ enum {
|
||||||
VDIO_MOD_XTI,
|
VDIO_MOD_XTI,
|
||||||
VDIO_MOD_TRB1,
|
VDIO_MOD_TRB1,
|
||||||
VDIO_MOD_TRB2,
|
VDIO_MOD_TRB2,
|
||||||
|
VDIO_MOD_VP,
|
||||||
VDMOS_MOD_TCVTH,
|
VDMOS_MOD_TCVTH,
|
||||||
VDMOS_MOD_RTHJC,
|
VDMOS_MOD_RTHJC,
|
||||||
VDMOS_MOD_RTHCA,
|
VDMOS_MOD_RTHCA,
|
||||||
|
|
@ -599,6 +627,7 @@ enum {
|
||||||
VDMOS_QGD,
|
VDMOS_QGD,
|
||||||
VDMOS_CQGD,
|
VDMOS_CQGD,
|
||||||
VDMOS_CDIO,
|
VDMOS_CDIO,
|
||||||
|
VDMOS_QDIO,
|
||||||
VDMOS_SOURCERESIST,
|
VDMOS_SOURCERESIST,
|
||||||
VDMOS_DRAINRESIST,
|
VDMOS_DRAINRESIST,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -710,11 +710,17 @@ bypass:
|
||||||
double Ith=0.0, dIth_dT=0.0;
|
double Ith=0.0, dIth_dT=0.0;
|
||||||
double dIdio_dT=0.0, dIth_dVdio=0.0;
|
double dIdio_dT=0.0, dIth_dVdio=0.0;
|
||||||
double vrb=0.0, dIrb_dT=0.0, dIth_dVrb=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
|
#ifndef NOBYPASS
|
||||||
double tol; /* temporary for tolerance calculations */
|
double tol; /* temporary for tolerance calculations */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int revrec = ((here->VDIOqpNode > 0) && (model->VDIOsoftRevRecParam!=0) && (here->VDIOtTransitTime!=0));
|
||||||
|
|
||||||
gbpr = here->VDIOtConductance;
|
gbpr = here->VDIOtConductance;
|
||||||
|
|
||||||
vt = CONSTKoverQ * Temp;
|
vt = CONSTKoverQ * Temp;
|
||||||
|
|
@ -725,13 +731,17 @@ bypass:
|
||||||
Check_dio = 1;
|
Check_dio = 1;
|
||||||
if (ckt->CKTmode & MODEINITSMSIG) {
|
if (ckt->CKTmode & MODEINITSMSIG) {
|
||||||
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||||
|
vqp = *(ckt->CKTstate0 + here->VDIOqp);
|
||||||
} else if (ckt->CKTmode & MODEINITTRAN) {
|
} else if (ckt->CKTmode & MODEINITTRAN) {
|
||||||
vd = *(ckt->CKTstate1 + here->VDIOvoltage);
|
vd = *(ckt->CKTstate1 + here->VDIOvoltage);
|
||||||
|
vqp = *(ckt->CKTstate1 + here->VDIOqp);
|
||||||
} else if ((ckt->CKTmode & MODEINITJCT) &&
|
} else if ((ckt->CKTmode & MODEINITJCT) &&
|
||||||
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {
|
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {
|
||||||
vd = here->VDIOinitCond;
|
vd = here->VDIOinitCond;
|
||||||
|
vqp=0;
|
||||||
} else if (ckt->CKTmode & MODEINITJCT) {
|
} else if (ckt->CKTmode & MODEINITJCT) {
|
||||||
vd = here->VDIOtVcrit;
|
vd = here->VDIOtVcrit;
|
||||||
|
vqp=0;
|
||||||
} else {
|
} else {
|
||||||
#ifndef PREDICTOR
|
#ifndef PREDICTOR
|
||||||
if (ckt->CKTmode & MODEINITPRED) {
|
if (ckt->CKTmode & MODEINITPRED) {
|
||||||
|
|
@ -744,10 +754,20 @@ bypass:
|
||||||
*(ckt->CKTstate1 + here->VDIOconduct);
|
*(ckt->CKTstate1 + here->VDIOconduct);
|
||||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) =
|
*(ckt->CKTstate0 + here->VDIOdIdio_dT) =
|
||||||
*(ckt->CKTstate1 + 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 {
|
} else {
|
||||||
#endif /* PREDICTOR */
|
#endif /* PREDICTOR */
|
||||||
vd = model->VDMOStype * (*(ckt->CKTrhsOld + here->VDIOposPrimeNode) -
|
vd = model->VDMOStype * (*(ckt->CKTrhsOld + here->VDIOposPrimeNode) -
|
||||||
*(ckt->CKTrhsOld + here->VDMOSdNode));
|
*(ckt->CKTrhsOld + here->VDMOSdNode));
|
||||||
|
vqp = *(ckt->CKTrhsOld+here->VDIOqpNode);
|
||||||
#ifndef PREDICTOR
|
#ifndef PREDICTOR
|
||||||
}
|
}
|
||||||
#endif /* PREDICTOR */
|
#endif /* PREDICTOR */
|
||||||
|
|
@ -776,6 +796,11 @@ bypass:
|
||||||
cd = *(ckt->CKTstate0 + here->VDIOcurrent);
|
cd = *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||||
gd = *(ckt->CKTstate0 + here->VDIOconduct);
|
gd = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||||
dIdio_dT= *(ckt->CKTstate0 + here->VDIOdIdio_dT);
|
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;
|
goto load;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -833,6 +858,10 @@ bypass:
|
||||||
|
|
||||||
cd = cdb + ckt->CKTgmin*vd;
|
cd = cdb + ckt->CKTgmin*vd;
|
||||||
gd = gdb + ckt->CKTgmin;
|
gd = gdb + ckt->CKTgmin;
|
||||||
|
cdres = cd;
|
||||||
|
gdres = gd;
|
||||||
|
cqcsr = 0;
|
||||||
|
gqcsr = 0;
|
||||||
|
|
||||||
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) ||
|
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) ||
|
||||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
|
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
|
||||||
|
|
@ -853,14 +882,34 @@ bypass:
|
||||||
(here->VDIOtGradingCoeff / (here->VDIOtJctPot + here->VDIOtJctPot))*(vd*vd - here->VDIOtDepCap*here->VDIOtDepCap));
|
(here->VDIOtGradingCoeff / (here->VDIOtJctPot + here->VDIOtJctPot))*(vd*vd - here->VDIOtDepCap*here->VDIOtDepCap));
|
||||||
deplcap = czof2*(here->VDIOtF3 + here->VDIOtGradingCoeff*vd / here->VDIOtJctPot);
|
deplcap = czof2*(here->VDIOtF3 + here->VDIOtGradingCoeff*vd / here->VDIOtJctPot);
|
||||||
}
|
}
|
||||||
diffcharge = here->VDIOtTransitTime*cdb;
|
|
||||||
*(ckt->CKTstate0 + here->VDIOcapCharge) =
|
|
||||||
diffcharge + deplcharge;
|
|
||||||
|
|
||||||
diffcap = here->VDIOtTransitTime*gdb;
|
if (revrec) {
|
||||||
capd = diffcap + deplcap;
|
/*
|
||||||
|
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.
|
||||||
|
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 of soft recovery with TT=0 (i.e. 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
|
* store small-signal parameters
|
||||||
|
|
@ -869,6 +918,7 @@ bypass:
|
||||||
(!(ckt->CKTmode & MODEUIC))) {
|
(!(ckt->CKTmode & MODEUIC))) {
|
||||||
if (ckt->CKTmode & MODEINITSMSIG) {
|
if (ckt->CKTmode & MODEINITSMSIG) {
|
||||||
*(ckt->CKTstate0 + here->VDIOcapCurrent) = capd;
|
*(ckt->CKTstate0 + here->VDIOcapCurrent) = capd;
|
||||||
|
*(ckt->CKTstate0 + here->VDIOresConduct) = gdres;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -889,6 +939,21 @@ bypass:
|
||||||
*(ckt->CKTstate1 + here->VDIOcapCurrent) =
|
*(ckt->CKTstate1 + here->VDIOcapCurrent) =
|
||||||
*(ckt->CKTstate0 + 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 +970,11 @@ bypass:
|
||||||
*(ckt->CKTstate0 + here->VDIOcurrent) = cd;
|
*(ckt->CKTstate0 + here->VDIOcurrent) = cd;
|
||||||
*(ckt->CKTstate0 + here->VDIOconduct) = gd;
|
*(ckt->CKTstate0 + here->VDIOconduct) = gd;
|
||||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) = dIdio_dT;
|
*(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
|
#ifndef NOBYPASS
|
||||||
load:
|
load:
|
||||||
|
|
@ -926,14 +996,10 @@ load:
|
||||||
/*
|
/*
|
||||||
* load current vector
|
* load current vector
|
||||||
*/
|
*/
|
||||||
cdeq = cd - gd*vd;
|
cdeq = model->VDMOStype * (cd - gd*vd);
|
||||||
if (model->VDMOStype == 1) {
|
*(ckt->CKTrhs + here->VDMOSdNode) += cdeq;
|
||||||
*(ckt->CKTrhs + here->VDMOSdNode) += cdeq;
|
*(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq;
|
||||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq;
|
|
||||||
} else {
|
|
||||||
*(ckt->CKTrhs + here->VDMOSdNode) -= cdeq;
|
|
||||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += cdeq;
|
|
||||||
}
|
|
||||||
if (selfheat) {
|
if (selfheat) {
|
||||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += dIdio_dT*delTemp - dIrb_dT*delTemp;
|
*(ckt->CKTrhs + here->VDIOposPrimeNode) += dIdio_dT*delTemp - dIrb_dT*delTemp;
|
||||||
*(ckt->CKTrhs + here->VDMOSdNode) += -dIdio_dT*delTemp;
|
*(ckt->CKTrhs + here->VDMOSdNode) += -dIdio_dT*delTemp;
|
||||||
|
|
@ -959,6 +1025,26 @@ load:
|
||||||
(*(here->VDMOSStempPtr) += dIrb_dT);
|
(*(here->VDMOSStempPtr) += dIrb_dT);
|
||||||
(*(here->VDMOSDtempPtr) += -dIdio_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) -= 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);
|
return(OK);
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
||||||
case VDMOS_MOD_TKSUBTHRES2:
|
case VDMOS_MOD_TKSUBTHRES2:
|
||||||
value->rValue = model->VDMOStksubthres2;
|
value->rValue = model->VDMOStksubthres2;
|
||||||
return(OK);
|
return(OK);
|
||||||
|
case VDIO_MOD_VP:
|
||||||
|
value->rValue = model->VDIOsoftRevRecParam;
|
||||||
|
return(OK);
|
||||||
/* SOA */
|
/* SOA */
|
||||||
case VDMOS_MOD_VGS_MAX:
|
case VDMOS_MOD_VGS_MAX:
|
||||||
value->rValue = model->VDMOSvgsMax;
|
value->rValue = model->VDMOSvgsMax;
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||||
model->VDIOtranTimeTemp1 = 0;
|
model->VDIOtranTimeTemp1 = 0;
|
||||||
model->VDIOtranTimeTemp2 = 0;
|
model->VDIOtranTimeTemp2 = 0;
|
||||||
break;
|
break;
|
||||||
|
case VDIO_MOD_VP:
|
||||||
|
model->VDIOsoftRevRecParam = value->rValue;
|
||||||
|
model->VDIOsoftRevRecParamGiven = TRUE;
|
||||||
|
break;
|
||||||
case VDIO_MOD_EG:
|
case VDIO_MOD_EG:
|
||||||
model->VDIOeg = value->rValue;
|
model->VDIOeg = value->rValue;
|
||||||
model->VDIOegGiven = TRUE;
|
model->VDIOegGiven = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,10 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
||||||
if (model->VDIOjctSatCur < ckt->CKTepsmin)
|
if (model->VDIOjctSatCur < ckt->CKTepsmin)
|
||||||
model->VDIOjctSatCur = ckt->CKTepsmin;
|
model->VDIOjctSatCur = ckt->CKTepsmin;
|
||||||
|
|
||||||
|
if (!model->VDIOsoftRevRecParamGiven) {
|
||||||
|
model->VDIOsoftRevRecParam = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
/* loop through all the instances of the model */
|
||||||
for (here = VDMOSinstances(model); here != NULL;
|
for (here = VDMOSinstances(model); here != NULL;
|
||||||
here = VDMOSnextInstance(here)) {
|
here = VDMOSnextInstance(here)) {
|
||||||
|
|
@ -431,6 +435,16 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
||||||
here->VDMOStcaseNode = 0;
|
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 */
|
/* macro to make elements with built in test for out of memory */
|
||||||
#define TSTALLOC(ptr,first,second) \
|
#define TSTALLOC(ptr,first,second) \
|
||||||
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
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(VDMOSTemptcasePtr, VDMOStempNode, VDMOStcaseNode);
|
||||||
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
||||||
TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStcaseNode);
|
TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStcaseNode);
|
||||||
TSTALLOC(VDMOSTcasetpPtr, VDMOStcaseNode, VDMOStNodePrime);
|
TSTALLOC(VDMOSTcasetpPtr, VDMOStcaseNode, VDMOStNodePrime);
|
||||||
TSTALLOC(VDMOSDevTdevTPtr, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=cktTemp to gnd */
|
TSTALLOC(VDMOSDevTdevTPtr, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=cktTemp to gnd */
|
||||||
TSTALLOC(VDMOSDevTtpPtr, VDMOSvdevTbranch, VDMOStNodePrime);
|
TSTALLOC(VDMOSDevTtpPtr, VDMOSvdevTbranch, VDMOStNodePrime);
|
||||||
TSTALLOC(VDMOSTpdevTPtr, VDMOStNodePrime, VDMOSvdevTbranch);
|
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);
|
return(OK);
|
||||||
|
|
@ -538,6 +561,10 @@ VDMOSunsetup(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
here->VDMOSvdevTbranch = 0;
|
here->VDMOSvdevTbranch = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* rev-rec */
|
||||||
|
if (here->VDIOqpNode > 0)
|
||||||
|
CKTdltNNum(ckt, here->VDIOqpNode);
|
||||||
|
here->VDIOqpNode = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ VDMOStrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||||
CKTterr(here->VDMOSqgs,ckt,timeStep);
|
CKTterr(here->VDMOSqgs,ckt,timeStep);
|
||||||
CKTterr(here->VDMOSqgd,ckt,timeStep);
|
CKTterr(here->VDMOSqgd,ckt,timeStep);
|
||||||
CKTterr(here->VDIOcapCharge,ckt,timeStep);
|
CKTterr(here->VDIOcapCharge,ckt,timeStep);
|
||||||
|
if (model->VDIOsoftRevRecParam!=0 && here->VDIOtTransitTime!=0)
|
||||||
|
CKTterr(here->VDIOsrcapCharge,ckt,timeStep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(OK);
|
return(OK);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue