vdmos bulk diode with smart recovery model

This commit is contained in:
dwarning 2026-05-09 15:55:27 +02:00
parent 19217bf018
commit b4ecedc616
10 changed files with 216 additions and 16 deletions

View File

@ -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"),

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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,
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);