another re-formatting for better readability (whitespace only)

This commit is contained in:
Holger Vogt 2018-04-03 21:43:45 +02:00 committed by rlar
parent d63123a269
commit 1aa3196ed9
4 changed files with 477 additions and 477 deletions

View File

@ -34,10 +34,10 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
return(OK);
case VDMOS_CGD:
value->rValue = 2* *(ckt->CKTstate0 + here->VDMOScapgd);
return(OK);
return(OK);
case VDMOS_M:
value->rValue = here->VDMOSm;
return(OK);
return(OK);
case VDMOS_L:
value->rValue = here->VDMOSl;
return(OK);
@ -96,19 +96,19 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
value->rValue = here->VDMOSsourceConductance;
return(OK);
case VDMOS_SOURCERESIST:
if (here->VDMOSsNodePrime != here->VDMOSsNode)
value->rValue = 1.0 / here->VDMOSsourceConductance;
else
value->rValue = 0.0;
if (here->VDMOSsNodePrime != here->VDMOSsNode)
value->rValue = 1.0 / here->VDMOSsourceConductance;
else
value->rValue = 0.0;
return(OK);
case VDMOS_DRAINCONDUCT:
value->rValue = here->VDMOSdrainConductance;
return(OK);
case VDMOS_DRAINRESIST:
if (here->VDMOSdNodePrime != here->VDMOSdNode)
value->rValue = 1.0 / here->VDMOSdrainConductance;
else
value->rValue = 0.0;
if (here->VDMOSdNodePrime != here->VDMOSdNode)
value->rValue = 1.0 / here->VDMOSdrainConductance;
else
value->rValue = 0.0;
return(OK);
case VDMOS_VON:
value->rValue = here->VDMOSvon;

View File

@ -87,16 +87,16 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
vt = CONSTKoverQ * here->VDMOStemp;
EffectiveLength=here->VDMOSl - 2*model->VDMOSlatDiff;
if( (here->VDMOStSatCurDens == 0) ||
if( (here->VDMOStSatCurDens == 0) ||
(here->VDMOSdrainArea == 0) ||
(here->VDMOSsourceArea == 0)) {
DrainSatCur = here->VDMOSm * here->VDMOStSatCur;
SourceSatCur = here->VDMOSm * here->VDMOStSatCur;
} else {
DrainSatCur = here->VDMOStSatCurDens *
DrainSatCur = here->VDMOStSatCurDens *
here->VDMOSm * here->VDMOSdrainArea;
SourceSatCur = here->VDMOStSatCurDens *
SourceSatCur = here->VDMOStSatCurDens *
here->VDMOSm * here->VDMOSsourceArea;
}
GateSourceOverlapCap = model->VDMOSgateSourceOverlapCapFactor *

View File

@ -372,495 +372,495 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
* here we just evaluate the ideal diode current and the
* corresponding derivative (conductance).
*/
if (vbs <= -3 * vt) {
here->VDMOSgbs = ckt->CKTgmin;
here->VDMOScbs = here->VDMOSgbs*vbs - SourceSatCur;
}
else {
evbs = exp(MIN(MAX_EXP_ARG, vbs / vt));
here->VDMOSgbs = SourceSatCur*evbs / vt + ckt->CKTgmin;
here->VDMOScbs = SourceSatCur*(evbs - 1) + ckt->CKTgmin*vbs;
}
if (vbd <= -3 * vt) {
here->VDMOSgbd = ckt->CKTgmin;
here->VDMOScbd = here->VDMOSgbd*vbd - DrainSatCur;
}
else {
evbd = exp(MIN(MAX_EXP_ARG, vbd / vt));
here->VDMOSgbd = DrainSatCur*evbd / vt + ckt->CKTgmin;
here->VDMOScbd = DrainSatCur*(evbd - 1) + ckt->CKTgmin*vbd;
}
/* now to determine whether the user was able to correctly
* identify the source and drain of his device
if (vbs <= -3 * vt) {
here->VDMOSgbs = ckt->CKTgmin;
here->VDMOScbs = here->VDMOSgbs*vbs - SourceSatCur;
}
else {
evbs = exp(MIN(MAX_EXP_ARG, vbs / vt));
here->VDMOSgbs = SourceSatCur*evbs / vt + ckt->CKTgmin;
here->VDMOScbs = SourceSatCur*(evbs - 1) + ckt->CKTgmin*vbs;
}
if (vbd <= -3 * vt) {
here->VDMOSgbd = ckt->CKTgmin;
here->VDMOScbd = here->VDMOSgbd*vbd - DrainSatCur;
}
else {
evbd = exp(MIN(MAX_EXP_ARG, vbd / vt));
here->VDMOSgbd = DrainSatCur*evbd / vt + ckt->CKTgmin;
here->VDMOScbd = DrainSatCur*(evbd - 1) + ckt->CKTgmin*vbd;
}
/* now to determine whether the user was able to correctly
* identify the source and drain of his device
*/
if (vds >= 0) {
/* normal mode */
here->VDMOSmode = 1;
}
else {
/* inverse mode */
here->VDMOSmode = -1;
}
/*
*/
{
/*
* this block of code evaluates the drain current and its
* derivatives using the shichman-hodges model and the
* charges associated with the gate, channel and bulk for
* mosfets
*
*/
/* the following 4 variables are local to this code block until
* it is obvious that they can be made global
*/
double arg;
double betap;
double sarg;
double vgst;
if ((here->VDMOSmode == 1 ? vbs : vbd) <= 0) {
sarg = sqrt(here->VDMOStPhi - (here->VDMOSmode == 1 ? vbs : vbd));
}
else {
sarg = sqrt(here->VDMOStPhi);
sarg = sarg - (here->VDMOSmode == 1 ? vbs : vbd) / (sarg + sarg);
sarg = MAX(0, sarg);
}
von = (here->VDMOStVbi*model->VDMOStype) + model->VDMOSgamma*sarg;
vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
vdsat = MAX(vgst, 0);
if (sarg <= 0) {
arg = 0;
}
else {
arg = model->VDMOSgamma / (sarg + sarg);
}
if (vgst <= 0) {
/*
* cutoff region
*/
if (vds >= 0) {
/* normal mode */
here->VDMOSmode = 1;
cdrain = 0;
here->VDMOSgm = 0;
here->VDMOSgds = 0;
here->VDMOSgmbs = 0;
}
else {
/*
* saturation region
*/
betap = Beta*(1 + model->VDMOSlambda*(vds*here->VDMOSmode));
if (vgst <= (vds*here->VDMOSmode)) {
cdrain = betap*vgst*vgst*.5;
here->VDMOSgm = betap*vgst;
here->VDMOSgds = model->VDMOSlambda*Beta*vgst*vgst*.5;
here->VDMOSgmbs = here->VDMOSgm*arg;
}
else {
/* inverse mode */
here->VDMOSmode = -1;
/*
* linear region
*/
cdrain = betap*(vds*here->VDMOSmode)*
(vgst - .5*(vds*here->VDMOSmode));
here->VDMOSgm = betap*(vds*here->VDMOSmode);
here->VDMOSgds = betap*(vgst - (vds*here->VDMOSmode)) +
model->VDMOSlambda*Beta*
(vds*here->VDMOSmode)*
(vgst - .5*(vds*here->VDMOSmode));
here->VDMOSgmbs = here->VDMOSgm*arg;
}
/*
*/
}
/*
* finished
*/
}
/*
*/
{
/*
* this block of code evaluates the drain current and its
* derivatives using the shichman-hodges model and the
* charges associated with the gate, channel and bulk for
* mosfets
*
*/
/* now deal with n vs p polarity */
/* the following 4 variables are local to this code block until
* it is obvious that they can be made global
*/
double arg;
double betap;
double sarg;
double vgst;
here->VDMOSvon = model->VDMOStype * von;
here->VDMOSvdsat = model->VDMOStype * vdsat;
/* line 490 */
/*
* COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
*/
here->VDMOScd = here->VDMOSmode * cdrain - here->VDMOScbd;
if ((here->VDMOSmode == 1 ? vbs : vbd) <= 0) {
sarg = sqrt(here->VDMOStPhi - (here->VDMOSmode == 1 ? vbs : vbd));
}
else {
sarg = sqrt(here->VDMOStPhi);
sarg = sarg - (here->VDMOSmode == 1 ? vbs : vbd) / (sarg + sarg);
sarg = MAX(0, sarg);
}
von = (here->VDMOStVbi*model->VDMOStype) + model->VDMOSgamma*sarg;
vgst = (here->VDMOSmode == 1 ? vgs : vgd) - von;
vdsat = MAX(vgst, 0);
if (sarg <= 0) {
arg = 0;
}
else {
arg = model->VDMOSgamma / (sarg + sarg);
}
if (vgst <= 0) {
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
/*
* now we do the hard part of the bulk-drain and bulk-source
* diode - we evaluate the non-linear capacitance and
* charge
*
* the basic equations are not hard, but the implementation
* is somewhat long in an attempt to avoid log/exponential
* evaluations
*/
/*
* charge storage elements
*
*.. bulk-drain and bulk-source depletion capacitances
*/
{
/* can't bypass the diode capacitance calculations */
if (here->VDMOSCbs != 0 || here->VDMOSCbssw != 0) {
if (vbs < here->VDMOStDepCap) {
arg = 1 - vbs / here->VDMOStBulkPot;
/*
* cutoff region
* the following block looks somewhat long and messy,
* but since most users use the default grading
* coefficients of .5, and sqrt is MUCH faster than an
* exp(log()) we use this special case code to buy time.
* (as much as 10% of total job time!)
*/
cdrain = 0;
here->VDMOSgm = 0;
here->VDMOSgds = 0;
here->VDMOSgmbs = 0;
}
else {
/*
* saturation region
*/
betap = Beta*(1 + model->VDMOSlambda*(vds*here->VDMOSmode));
if (vgst <= (vds*here->VDMOSmode)) {
cdrain = betap*vgst*vgst*.5;
here->VDMOSgm = betap*vgst;
here->VDMOSgds = model->VDMOSlambda*Beta*vgst*vgst*.5;
here->VDMOSgmbs = here->VDMOSgm*arg;
}
else {
/*
* linear region
*/
cdrain = betap*(vds*here->VDMOSmode)*
(vgst - .5*(vds*here->VDMOSmode));
here->VDMOSgm = betap*(vds*here->VDMOSmode);
here->VDMOSgds = betap*(vgst - (vds*here->VDMOSmode)) +
model->VDMOSlambda*Beta*
(vds*here->VDMOSmode)*
(vgst - .5*(vds*here->VDMOSmode));
here->VDMOSgmbs = here->VDMOSgm*arg;
}
}
/*
* finished
*/
}
/*
*/
/* now deal with n vs p polarity */
here->VDMOSvon = model->VDMOStype * von;
here->VDMOSvdsat = model->VDMOStype * vdsat;
/* line 490 */
/*
* COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
*/
here->VDMOScd = here->VDMOSmode * cdrain - here->VDMOScbd;
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
/*
* now we do the hard part of the bulk-drain and bulk-source
* diode - we evaluate the non-linear capacitance and
* charge
*
* the basic equations are not hard, but the implementation
* is somewhat long in an attempt to avoid log/exponential
* evaluations
*/
/*
* charge storage elements
*
*.. bulk-drain and bulk-source depletion capacitances
*/
{
/* can't bypass the diode capacitance calculations */
if (here->VDMOSCbs != 0 || here->VDMOSCbssw != 0) {
if (vbs < here->VDMOStDepCap) {
arg = 1 - vbs / here->VDMOStBulkPot;
/*
* the following block looks somewhat long and messy,
* but since most users use the default grading
* coefficients of .5, and sqrt is MUCH faster than an
* exp(log()) we use this special case code to buy time.
* (as much as 10% of total job time!)
*/
if (model->VDMOSbulkJctBotGradingCoeff ==
model->VDMOSbulkJctSideGradingCoeff) {
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = sargsw = 1 / sqrt(arg);
}
else {
sarg = sargsw =
exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
}
else {
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = 1 / sqrt(arg);
}
else {
sarg = exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
if (model->VDMOSbulkJctSideGradingCoeff == .5) {
sargsw = 1 / sqrt(arg);
}
else {
sargsw = exp(-model->VDMOSbulkJctSideGradingCoeff*
log(arg));
}
}
*(ckt->CKTstate0 + here->VDMOSqbs) =
here->VDMOStBulkPot*(here->VDMOSCbs*
(1 - arg*sarg) / (1 - model->VDMOSbulkJctBotGradingCoeff)
+ here->VDMOSCbssw*
(1 - arg*sargsw) /
(1 - model->VDMOSbulkJctSideGradingCoeff));
here->VDMOScapbs = here->VDMOSCbs*sarg +
here->VDMOSCbssw*sargsw;
if (model->VDMOSbulkJctBotGradingCoeff ==
model->VDMOSbulkJctSideGradingCoeff) {
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = sargsw = 1 / sqrt(arg);
}
else {
*(ckt->CKTstate0 + here->VDMOSqbs) = here->VDMOSf4s +
vbs*(here->VDMOSf2s + vbs*(here->VDMOSf3s / 2));
here->VDMOScapbs = here->VDMOSf2s + here->VDMOSf3s*vbs;
sarg = sargsw =
exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
}
else {
*(ckt->CKTstate0 + here->VDMOSqbs) = 0;
here->VDMOScapbs = 0;
}
}
{
if (here->VDMOSCbd != 0 || here->VDMOSCbdsw != 0) {
if (vbd < here->VDMOStDepCap) {
arg = 1 - vbd / here->VDMOStBulkPot;
/*
* the following block looks somewhat long and messy,
* but since most users use the default grading
* coefficients of .5, and sqrt is MUCH faster than an
* exp(log()) we use this special case code to buy time.
* (as much as 10% of total job time!)
*/
if (model->VDMOSbulkJctBotGradingCoeff == .5 &&
model->VDMOSbulkJctSideGradingCoeff == .5) {
sarg = sargsw = 1 / sqrt(arg);
}
else {
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = 1 / sqrt(arg);
}
else {
sarg = exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
if (model->VDMOSbulkJctSideGradingCoeff == .5) {
sargsw = 1 / sqrt(arg);
}
else {
sargsw = exp(-model->VDMOSbulkJctSideGradingCoeff*
log(arg));
}
}
*(ckt->CKTstate0 + here->VDMOSqbd) =
here->VDMOStBulkPot*(here->VDMOSCbd*
(1 - arg*sarg)
/ (1 - model->VDMOSbulkJctBotGradingCoeff)
+ here->VDMOSCbdsw*
(1 - arg*sargsw)
/ (1 - model->VDMOSbulkJctSideGradingCoeff));
here->VDMOScapbd = here->VDMOSCbd*sarg +
here->VDMOSCbdsw*sargsw;
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = 1 / sqrt(arg);
}
else {
*(ckt->CKTstate0 + here->VDMOSqbd) = here->VDMOSf4d +
vbd * (here->VDMOSf2d + vbd * here->VDMOSf3d / 2);
here->VDMOScapbd = here->VDMOSf2d + vbd * here->VDMOSf3d;
sarg = exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
if (model->VDMOSbulkJctSideGradingCoeff == .5) {
sargsw = 1 / sqrt(arg);
}
else {
sargsw = exp(-model->VDMOSbulkJctSideGradingCoeff*
log(arg));
}
}
else {
*(ckt->CKTstate0 + here->VDMOSqbd) = 0;
here->VDMOScapbd = 0;
}
*(ckt->CKTstate0 + here->VDMOSqbs) =
here->VDMOStBulkPot*(here->VDMOSCbs*
(1 - arg*sarg) / (1 - model->VDMOSbulkJctBotGradingCoeff)
+ here->VDMOSCbssw*
(1 - arg*sargsw) /
(1 - model->VDMOSbulkJctSideGradingCoeff));
here->VDMOScapbs = here->VDMOSCbs*sarg +
here->VDMOSCbssw*sargsw;
}
/*
*/
if ((ckt->CKTmode & MODETRAN) || ((ckt->CKTmode&MODEINITTRAN)
&& !(ckt->CKTmode&MODEUIC))) {
/* (above only excludes tranop, since we're only at this
* point if tran or tranop )
else {
*(ckt->CKTstate0 + here->VDMOSqbs) = here->VDMOSf4s +
vbs*(here->VDMOSf2s + vbs*(here->VDMOSf3s / 2));
here->VDMOScapbs = here->VDMOSf2s + here->VDMOSf3s*vbs;
}
}
else {
*(ckt->CKTstate0 + here->VDMOSqbs) = 0;
here->VDMOScapbs = 0;
}
}
{
if (here->VDMOSCbd != 0 || here->VDMOSCbdsw != 0) {
if (vbd < here->VDMOStDepCap) {
arg = 1 - vbd / here->VDMOStBulkPot;
/*
* the following block looks somewhat long and messy,
* but since most users use the default grading
* coefficients of .5, and sqrt is MUCH faster than an
* exp(log()) we use this special case code to buy time.
* (as much as 10% of total job time!)
*/
/*
* calculate equivalent conductances and currents for
* depletion capacitors
*/
/* integrate the capacitors and save results */
error = NIintegrate(ckt, &geq, &ceq, here->VDMOScapbd,
here->VDMOSqbd);
if (error) return(error);
here->VDMOSgbd += geq;
here->VDMOScbd += *(ckt->CKTstate0 + here->VDMOScqbd);
here->VDMOScd -= *(ckt->CKTstate0 + here->VDMOScqbd);
error = NIintegrate(ckt, &geq, &ceq, here->VDMOScapbs,
here->VDMOSqbs);
if (error) return(error);
here->VDMOSgbs += geq;
here->VDMOScbs += *(ckt->CKTstate0 + here->VDMOScqbs);
}
}
/*
*/
/*
* check convergence
*/
if ((here->VDMOSoff == 0) ||
(!(ckt->CKTmode & (MODEINITFIX | MODEINITSMSIG)))) {
if (Check == 1) {
ckt->CKTnoncon++;
ckt->CKTtroubleElt = (GENinstance *)here;
}
}
/*
*/
/* save things away for next time */
*(ckt->CKTstate0 + here->VDMOSvbs) = vbs;
*(ckt->CKTstate0 + here->VDMOSvbd) = vbd;
*(ckt->CKTstate0 + here->VDMOSvgs) = vgs;
*(ckt->CKTstate0 + here->VDMOSvds) = vds;
/*
*/
/*
* vdmos capacitor model
*/
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
/*
* calculate gate - drain, gate - source capacitors
* drain-source capacitor is evaluated with the bulk diode below
*/
/*
* this just evaluates at the current time,
* expects you to remember values from previous time
* returns 1/2 of non-constant portion of capacitance
* you must add in the other half from previous time
* and the constant part
*/
DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs,
(ckt->CKTstate0 + here->VDMOScapgs),
(ckt->CKTstate0 + here->VDMOScapgd),
(ckt->CKTstate0 + here->VDMOScapgb));
vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs);
vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds);
vgb1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvbs);
if (ckt->CKTmode & (MODETRANOP | MODEINITSMSIG)) {
capgs = 2 * *(ckt->CKTstate0 + here->VDMOScapgs) +
GateSourceOverlapCap;
capgd = 2 * *(ckt->CKTstate0 + here->VDMOScapgd) +
GateDrainOverlapCap;
capgb = 2 * *(ckt->CKTstate0 + here->VDMOScapgb) +
GateBulkOverlapCap;
}
else {
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
*(ckt->CKTstate1 + here->VDMOScapgs) +
GateSourceOverlapCap);
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
*(ckt->CKTstate1 + here->VDMOScapgd) +
GateDrainOverlapCap);
capgb = (*(ckt->CKTstate0 + here->VDMOScapgb) +
*(ckt->CKTstate1 + here->VDMOScapgb) +
GateBulkOverlapCap);
}
/*
*/
#ifndef PREDICTOR
if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {
*(ckt->CKTstate0 + here->VDMOSqgs) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgs)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgs);
*(ckt->CKTstate0 + here->VDMOSqgd) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgd)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgb)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgb);
}
else {
#endif /*PREDICTOR*/
if (ckt->CKTmode & MODETRAN) {
*(ckt->CKTstate0 + here->VDMOSqgs) = (vgs - vgs1)*capgs +
*(ckt->CKTstate1 + here->VDMOSqgs);
*(ckt->CKTstate0 + here->VDMOSqgd) = (vgd - vgd1)*capgd +
*(ckt->CKTstate1 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) = (vgb - vgb1)*capgb +
*(ckt->CKTstate1 + here->VDMOSqgb);
if (model->VDMOSbulkJctBotGradingCoeff == .5 &&
model->VDMOSbulkJctSideGradingCoeff == .5) {
sarg = sargsw = 1 / sqrt(arg);
}
else {
/* TRANOP only */
*(ckt->CKTstate0 + here->VDMOSqgs) = vgs*capgs;
*(ckt->CKTstate0 + here->VDMOSqgd) = vgd*capgd;
*(ckt->CKTstate0 + here->VDMOSqgb) = vgb*capgb;
if (model->VDMOSbulkJctBotGradingCoeff == .5) {
sarg = 1 / sqrt(arg);
}
else {
sarg = exp(-model->VDMOSbulkJctBotGradingCoeff*
log(arg));
}
if (model->VDMOSbulkJctSideGradingCoeff == .5) {
sargsw = 1 / sqrt(arg);
}
else {
sargsw = exp(-model->VDMOSbulkJctSideGradingCoeff*
log(arg));
}
}
#ifndef PREDICTOR
*(ckt->CKTstate0 + here->VDMOSqbd) =
here->VDMOStBulkPot*(here->VDMOSCbd*
(1 - arg*sarg)
/ (1 - model->VDMOSbulkJctBotGradingCoeff)
+ here->VDMOSCbdsw*
(1 - arg*sargsw)
/ (1 - model->VDMOSbulkJctSideGradingCoeff));
here->VDMOScapbd = here->VDMOSCbd*sarg +
here->VDMOSCbdsw*sargsw;
}
else {
*(ckt->CKTstate0 + here->VDMOSqbd) = here->VDMOSf4d +
vbd * (here->VDMOSf2d + vbd * here->VDMOSf3d / 2);
here->VDMOScapbd = here->VDMOSf2d + vbd * here->VDMOSf3d;
}
#endif /*PREDICTOR*/
}
else {
*(ckt->CKTstate0 + here->VDMOSqbd) = 0;
here->VDMOScapbd = 0;
}
}
/*
*/
if ((ckt->CKTmode & MODETRAN) || ((ckt->CKTmode&MODEINITTRAN)
&& !(ckt->CKTmode&MODEUIC))) {
/* (above only excludes tranop, since we're only at this
* point if tran or tranop )
*/
/*
* calculate equivalent conductances and currents for
* depletion capacitors
*/
/* integrate the capacitors and save results */
error = NIintegrate(ckt, &geq, &ceq, here->VDMOScapbd,
here->VDMOSqbd);
if (error) return(error);
here->VDMOSgbd += geq;
here->VDMOScbd += *(ckt->CKTstate0 + here->VDMOScqbd);
here->VDMOScd -= *(ckt->CKTstate0 + here->VDMOScqbd);
error = NIintegrate(ckt, &geq, &ceq, here->VDMOScapbs,
here->VDMOSqbs);
if (error) return(error);
here->VDMOSgbs += geq;
here->VDMOScbs += *(ckt->CKTstate0 + here->VDMOScqbs);
}
}
/*
*/
/*
* check convergence
*/
if ((here->VDMOSoff == 0) ||
(!(ckt->CKTmode & (MODEINITFIX | MODEINITSMSIG)))) {
if (Check == 1) {
ckt->CKTnoncon++;
ckt->CKTtroubleElt = (GENinstance *)here;
}
}
/*
*/
/* save things away for next time */
*(ckt->CKTstate0 + here->VDMOSvbs) = vbs;
*(ckt->CKTstate0 + here->VDMOSvbd) = vbd;
*(ckt->CKTstate0 + here->VDMOSvgs) = vgs;
*(ckt->CKTstate0 + here->VDMOSvds) = vds;
/*
*/
/*
* vdmos capacitor model
*/
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
/*
* calculate gate - drain, gate - source capacitors
* drain-source capacitor is evaluated with the bulk diode below
*/
/*
* this just evaluates at the current time,
* expects you to remember values from previous time
* returns 1/2 of non-constant portion of capacitance
* you must add in the other half from previous time
* and the constant part
*/
DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs,
(ckt->CKTstate0 + here->VDMOScapgs),
(ckt->CKTstate0 + here->VDMOScapgd),
(ckt->CKTstate0 + here->VDMOScapgb));
vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs);
vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds);
vgb1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvbs);
if (ckt->CKTmode & (MODETRANOP | MODEINITSMSIG)) {
capgs = 2 * *(ckt->CKTstate0 + here->VDMOScapgs) +
GateSourceOverlapCap;
capgd = 2 * *(ckt->CKTstate0 + here->VDMOScapgd) +
GateDrainOverlapCap;
capgb = 2 * *(ckt->CKTstate0 + here->VDMOScapgb) +
GateBulkOverlapCap;
}
else {
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
*(ckt->CKTstate1 + here->VDMOScapgs) +
GateSourceOverlapCap);
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
*(ckt->CKTstate1 + here->VDMOScapgd) +
GateDrainOverlapCap);
capgb = (*(ckt->CKTstate0 + here->VDMOScapgb) +
*(ckt->CKTstate1 + here->VDMOScapgb) +
GateBulkOverlapCap);
}
/*
*/
#ifndef PREDICTOR
if (ckt->CKTmode & (MODEINITPRED | MODEINITTRAN)) {
*(ckt->CKTstate0 + here->VDMOSqgs) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgs)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgs);
*(ckt->CKTstate0 + here->VDMOSqgd) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgd)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgb)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgb);
}
else {
#endif /*PREDICTOR*/
if (ckt->CKTmode & MODETRAN) {
*(ckt->CKTstate0 + here->VDMOSqgs) = (vgs - vgs1)*capgs +
*(ckt->CKTstate1 + here->VDMOSqgs);
*(ckt->CKTstate0 + here->VDMOSqgd) = (vgd - vgd1)*capgd +
*(ckt->CKTstate1 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) = (vgb - vgb1)*capgb +
*(ckt->CKTstate1 + here->VDMOSqgb);
}
else {
/* TRANOP only */
*(ckt->CKTstate0 + here->VDMOSqgs) = vgs*capgs;
*(ckt->CKTstate0 + here->VDMOSqgd) = vgd*capgd;
*(ckt->CKTstate0 + here->VDMOSqgb) = vgb*capgb;
}
#ifndef PREDICTOR
}
#endif /*PREDICTOR*/
}
#ifndef NOBYPASS
bypass :
bypass :
#endif
if ((ckt->CKTmode & (MODEINITTRAN)) ||
(!(ckt->CKTmode & (MODETRAN)))) {
/*
* initialize to zero charge conductances
* and current
*/
gcgs = 0;
ceqgs = 0;
gcgd = 0;
ceqgd = 0;
gcgb = 0;
ceqgb = 0;
}
else {
if (capgs == 0) *(ckt->CKTstate0 + here->VDMOScqgs) = 0;
if (capgd == 0) *(ckt->CKTstate0 + here->VDMOScqgd) = 0;
if (capgb == 0) *(ckt->CKTstate0 + here->VDMOScqgb) = 0;
/*
* calculate equivalent conductances and currents for
* meyer"s capacitors
*/
error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs);
if (error) return(error);
error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd);
if (error) return(error);
error = NIintegrate(ckt, &gcgb, &ceqgb, capgb, here->VDMOSqgb);
if (error) return(error);
ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgs);
ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgd);
ceqgb = ceqgb - gcgb*vgb + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgb);
}
/*
* store charge storage info for meyer's cap in lx table
*/
if ((ckt->CKTmode & (MODEINITTRAN)) ||
(!(ckt->CKTmode & (MODETRAN)))) {
/*
* initialize to zero charge conductances
* and current
*/
gcgs = 0;
ceqgs = 0;
gcgd = 0;
ceqgd = 0;
gcgb = 0;
ceqgb = 0;
}
else {
if (capgs == 0) *(ckt->CKTstate0 + here->VDMOScqgs) = 0;
if (capgd == 0) *(ckt->CKTstate0 + here->VDMOScqgd) = 0;
if (capgb == 0) *(ckt->CKTstate0 + here->VDMOScqgb) = 0;
/*
* calculate equivalent conductances and currents for
* meyer"s capacitors
*/
error = NIintegrate(ckt, &gcgs, &ceqgs, capgs, here->VDMOSqgs);
if (error) return(error);
error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd);
if (error) return(error);
error = NIintegrate(ckt, &gcgb, &ceqgb, capgb, here->VDMOSqgb);
if (error) return(error);
ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgs);
ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgd);
ceqgb = ceqgb - gcgb*vgb + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgb);
}
/*
* store charge storage info for meyer's cap in lx table
*/
/*
* load current vector
*/
ceqbs = model->VDMOStype *
(here->VDMOScbs - (here->VDMOSgbs)*vbs);
ceqbd = model->VDMOStype *
(here->VDMOScbd - (here->VDMOSgbd)*vbd);
if (here->VDMOSmode >= 0) {
xnrm = 1;
xrev = 0;
cdreq = model->VDMOStype*(cdrain - here->VDMOSgds*vds -
here->VDMOSgm*vgs - here->VDMOSgmbs*vbs);
}
else {
xnrm = 0;
xrev = 1;
cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds) -
here->VDMOSgm*vgd - here->VDMOSgmbs*vbd);
}
*(ckt->CKTrhs + here->VDMOSgNodePrime) -=
(model->VDMOStype * (ceqgs + ceqgb + ceqgd));
*(ckt->CKTrhs + here->VDMOSbNode) -=
(ceqbs + ceqbd - model->VDMOStype * ceqgb);
*(ckt->CKTrhs + here->VDMOSdNodePrime) +=
(ceqbd - cdreq + model->VDMOStype * ceqgd);
*(ckt->CKTrhs + here->VDMOSsNodePrime) +=
cdreq + ceqbs + model->VDMOStype * ceqgs;
/*
* load y matrix
*/
/*
* load current vector
*/
ceqbs = model->VDMOStype *
(here->VDMOScbs - (here->VDMOSgbs)*vbs);
ceqbd = model->VDMOStype *
(here->VDMOScbd - (here->VDMOSgbd)*vbd);
if (here->VDMOSmode >= 0) {
xnrm = 1;
xrev = 0;
cdreq = model->VDMOStype*(cdrain - here->VDMOSgds*vds -
here->VDMOSgm*vgs - here->VDMOSgmbs*vbs);
}
else {
xnrm = 0;
xrev = 1;
cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds) -
here->VDMOSgm*vgd - here->VDMOSgmbs*vbd);
}
*(ckt->CKTrhs + here->VDMOSgNodePrime) -=
(model->VDMOStype * (ceqgs + ceqgb + ceqgd));
*(ckt->CKTrhs + here->VDMOSbNode) -=
(ceqbs + ceqbd - model->VDMOStype * ceqgb);
*(ckt->CKTrhs + here->VDMOSdNodePrime) +=
(ceqbd - cdreq + model->VDMOStype * ceqgd);
*(ckt->CKTrhs + here->VDMOSsNodePrime) +=
cdreq + ceqbs + model->VDMOStype * ceqgs;
/*
* load y matrix
*/
*(here->VDMOSDdPtr) += (here->VDMOSdrainConductance);
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance); //((gcgd + gcgs + gcgb));
*(here->VDMOSSsPtr) += (here->VDMOSsourceConductance);
*(here->VDMOSBbPtr) += (here->VDMOSgbd + here->VDMOSgbs + gcgb);
*(here->VDMOSDPdpPtr) +=
(here->VDMOSdrainConductance + here->VDMOSgds +
here->VDMOSgbd + xrev*(here->VDMOSgm + here->VDMOSgmbs) + gcgd);
*(here->VDMOSSPspPtr) +=
(here->VDMOSsourceConductance + here->VDMOSgds +
here->VDMOSgbs + xnrm*(here->VDMOSgm + here->VDMOSgmbs) + gcgs);
*(here->VDMOSGPgpPtr) +=
(here->VDMOSgateConductance) + (gcgd + gcgs + gcgb);
*(here->VDMOSGgpPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSDdpPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSGPgPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSGPbPtr) -= gcgb;
*(here->VDMOSGPdpPtr) -= gcgd;
*(here->VDMOSGPspPtr) -= gcgs;
*(here->VDMOSSspPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSBgpPtr) -= gcgb;
*(here->VDMOSBdpPtr) -= here->VDMOSgbd;
*(here->VDMOSBspPtr) -= here->VDMOSgbs;
*(here->VDMOSDPdPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSDPgpPtr) += ((xnrm - xrev)*here->VDMOSgm - gcgd);
*(here->VDMOSDPbPtr) += (-here->VDMOSgbd + (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSDPspPtr) += (-here->VDMOSgds - xnrm*
(here->VDMOSgm + here->VDMOSgmbs));
*(here->VDMOSSPgpPtr) += (-(xnrm - xrev)*here->VDMOSgm - gcgs);
*(here->VDMOSSPsPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSSPbPtr) += (-here->VDMOSgbs - (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSSPdpPtr) += (-here->VDMOSgds - xrev*
(here->VDMOSgm + here->VDMOSgmbs));
*(here->VDMOSDdPtr) += (here->VDMOSdrainConductance);
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance); //((gcgd + gcgs + gcgb));
*(here->VDMOSSsPtr) += (here->VDMOSsourceConductance);
*(here->VDMOSBbPtr) += (here->VDMOSgbd + here->VDMOSgbs + gcgb);
*(here->VDMOSDPdpPtr) +=
(here->VDMOSdrainConductance + here->VDMOSgds +
here->VDMOSgbd + xrev*(here->VDMOSgm + here->VDMOSgmbs) + gcgd);
*(here->VDMOSSPspPtr) +=
(here->VDMOSsourceConductance + here->VDMOSgds +
here->VDMOSgbs + xnrm*(here->VDMOSgm + here->VDMOSgmbs) + gcgs);
*(here->VDMOSGPgpPtr) +=
(here->VDMOSgateConductance) + (gcgd + gcgs + gcgb);
*(here->VDMOSGgpPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSDdpPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSGPgPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSGPbPtr) -= gcgb;
*(here->VDMOSGPdpPtr) -= gcgd;
*(here->VDMOSGPspPtr) -= gcgs;
*(here->VDMOSSspPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSBgpPtr) -= gcgb;
*(here->VDMOSBdpPtr) -= here->VDMOSgbd;
*(here->VDMOSBspPtr) -= here->VDMOSgbs;
*(here->VDMOSDPdPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSDPgpPtr) += ((xnrm - xrev)*here->VDMOSgm - gcgd);
*(here->VDMOSDPbPtr) += (-here->VDMOSgbd + (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSDPspPtr) += (-here->VDMOSgds - xnrm*
(here->VDMOSgm + here->VDMOSgmbs));
*(here->VDMOSSPgpPtr) += (-(xnrm - xrev)*here->VDMOSgm - gcgs);
*(here->VDMOSSPsPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSSPbPtr) += (-here->VDMOSgbs - (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSSPdpPtr) += (-here->VDMOSgds - xrev*
(here->VDMOSgm + here->VDMOSgmbs));
}
}
return(OK);

View File

@ -112,7 +112,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
}
}
/* loop through all instances of the model */
for(here = VDMOSinstances(model); here!= NULL;
here = VDMOSnextInstance(here)) {
@ -218,7 +218,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
if(model->VDMOScapBDGiven) {
czbd = here->VDMOStCbd * here->VDMOSm;
} else {
if(model->VDMOSbulkCapFactorGiven) {
if(model->VDMOSbulkCapFactorGiven) {
czbd=here->VDMOStCj*here->VDMOSm*here->VDMOSdrainArea;
} else {
czbd=0;
@ -299,7 +299,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
}
} else if (model->VDMOSsheetResistanceGiven) {
if(model->VDMOSsheetResistance != 0) {
here->VDMOSdrainConductance =
here->VDMOSdrainConductance =
here->VDMOSm /
(model->VDMOSsheetResistance*here->VDMOSdrainSquares);
} else {
@ -318,7 +318,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
} else if (model->VDMOSsheetResistanceGiven) {
if ((model->VDMOSsheetResistance != 0) &&
(here->VDMOSsourceSquares != 0)) {
here->VDMOSsourceConductance =
here->VDMOSsourceConductance =
here->VDMOSm /
(model->VDMOSsheetResistance*here->VDMOSsourceSquares);
} else {