📄 mos2load.c
字号:
} }#endif /*NOSQRT*/ *(ckt->CKTstate0 + here->MOS2qbs) = here->MOS2tBulkPot*(here->MOS2Cbs* (1-arg*sarg)/(1-model->MOS2bulkJctBotGradingCoeff) +here->MOS2Cbssw* (1-arg*sargsw)/ (1-model->MOS2bulkJctSideGradingCoeff)); here->MOS2capbs=here->MOS2Cbs*sarg+ here->MOS2Cbssw*sargsw; } else { *(ckt->CKTstate0 + here->MOS2qbs) = here->MOS2f4s + vbs*(here->MOS2f2s+vbs*(here->MOS2f3s/2)); here->MOS2capbs=here->MOS2f2s+here->MOS2f3s*vbs; }#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS2qbs) = 0; here->MOS2capbs=0; }#endif /*CAPZEROBYPASS*/ }#ifdef CAPBYPASS if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || FABS(delvbd) >= ckt->CKTreltol * MAX(FABS(vbd), FABS(*(ckt->CKTstate0+here->MOS2vbd)))+ ckt->CKTvoltTol)|| senflag)#endif /*CAPBYPASS*/ /* can't bypass the diode capacitance calculations */ {#ifdef CAPZEROBYPASS if(here->MOS2Cbd != 0 || here->MOS2Cbdsw != 0 ) {#endif /*CAPZEROBYPASS*/ if (vbd < here->MOS2tDepCap) { arg=1-vbd/here->MOS2tBulkPot; /* * 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!) */#ifndef NOSQRT if(model->MOS2bulkJctBotGradingCoeff == .5 && model->MOS2bulkJctSideGradingCoeff == .5) { sarg = sargsw = 1/sqrt(arg); } else { if(model->MOS2bulkJctBotGradingCoeff == .5) { sarg = 1/sqrt(arg); } else {#endif /*NOSQRT*/ sarg = exp(-model->MOS2bulkJctBotGradingCoeff* log(arg));#ifndef NOSQRT } if(model->MOS2bulkJctSideGradingCoeff == .5) { sargsw = 1/sqrt(arg); } else {#endif /*NOSQRT*/ sargsw =exp(-model->MOS2bulkJctSideGradingCoeff* log(arg));#ifndef NOSQRT } }#endif /*NOSQRT*/ *(ckt->CKTstate0 + here->MOS2qbd) = here->MOS2tBulkPot*(here->MOS2Cbd* (1-arg*sarg) /(1-model->MOS2bulkJctBotGradingCoeff) +here->MOS2Cbdsw* (1-arg*sargsw) /(1-model->MOS2bulkJctSideGradingCoeff)); here->MOS2capbd=here->MOS2Cbd*sarg+ here->MOS2Cbdsw*sargsw; } else { *(ckt->CKTstate0 + here->MOS2qbd) = here->MOS2f4d + vbd * (here->MOS2f2d + vbd * here->MOS2f3d/2); here->MOS2capbd=here->MOS2f2d + vbd * here->MOS2f3d; }#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS2qbd) = 0; here->MOS2capbd = 0; }#endif /*CAPZEROBYPASS*/ } if(SenCond && (ckt->CKTsenInfo->SENmode==TRANSEN)) goto next2; if ( ckt->CKTmode & MODETRAN ) { /* (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->MOS2capbd, here->MOS2qbd); if(error) return(error); here->MOS2gbd += geq; here->MOS2cbd += *(ckt->CKTstate0 + here->MOS2cqbd); here->MOS2cd -= *(ckt->CKTstate0 + here->MOS2cqbd); error = NIintegrate(ckt,&geq,&ceq,here->MOS2capbs, here->MOS2qbs); if(error) return(error); here->MOS2gbs += geq; here->MOS2cbs += *(ckt->CKTstate0 + here->MOS2cqbs); } } if(SenCond) goto next2; /* * check convergence */ if ( (here->MOS2off == 0) || (!(ckt->CKTmode & (MODEINITFIX|MODEINITSMSIG))) ){ if (Check == 1) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here;#ifndef NEWCONV#ifdef STEPDEBUG printf("MOS2: %s limiting noncon\n",here->MOS2name);#endif /* STEPDEBUG */ } else { tol=ckt->CKTreltol*MAX(FABS(cdhat),FABS(here->MOS2cd))+ ckt->CKTabstol; if (FABS(cdhat-here->MOS2cd) >= tol) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here;#ifdef STEPDEBUG printf("MOS2: %s cd noncon cd=%g, cdhat=%g, mode=%d\n", here->MOS2name,here->MOS2cd,cdhat, here->MOS2mode);#endif /* STEPDEBUG */ } else { tol=ckt->CKTreltol* MAX(FABS(cbhat),FABS(here->MOS2cbs+here->MOS2cbd))+ ckt->CKTabstol; if (FABS(cbhat-(here->MOS2cbs+here->MOS2cbd)) > tol) { ckt->CKTnoncon++; ckt->CKTtroubleElt = (GENinstance *) here;#ifdef STEPDEBUG printf("MOS2: %s cb noncon\n",here->MOS2name);#endif /* STEPDEBUG */ } }#endif /* NEWCONV */ } }next2: *(ckt->CKTstate0 + here->MOS2vbs) = vbs; *(ckt->CKTstate0 + here->MOS2vbd) = vbd; *(ckt->CKTstate0 + here->MOS2vgs) = vgs; *(ckt->CKTstate0 + here->MOS2vds) = vds; /* * meyer's capacitor model */ if ( ckt->CKTmode & (MODETRAN|MODETRANOP|MODEINITSMSIG)) { /* * calculate meyer's capacitors */ if (here->MOS2mode > 0){ DEVqmeyer (vgs,vgd,vgb,von,vdsat, (ckt->CKTstate0 + here->MOS2capgs), (ckt->CKTstate0 + here->MOS2capgd), (ckt->CKTstate0 + here->MOS2capgb), here->MOS2tPhi,OxideCap); } else { DEVqmeyer (vgd,vgs,vgb,von,vdsat, (ckt->CKTstate0 + here->MOS2capgd), (ckt->CKTstate0 + here->MOS2capgs), (ckt->CKTstate0 + here->MOS2capgb), here->MOS2tPhi,OxideCap); } vgs1 = *(ckt->CKTstate1 + here->MOS2vgs); vgd1 = vgs1 - *(ckt->CKTstate1 + here->MOS2vds); vgb1 = vgs1 - *(ckt->CKTstate1 + here->MOS2vbs); if(ckt->CKTmode & MODETRANOP) { capgs = 2 * *(ckt->CKTstate0 + here->MOS2capgs)+ GateSourceOverlapCap; capgd = 2 * *(ckt->CKTstate0 + here->MOS2capgd)+ GateDrainOverlapCap; capgb = 2 * *(ckt->CKTstate0 + here->MOS2capgb)+ GateBulkOverlapCap; } else { capgs = *(ckt->CKTstate0 + here->MOS2capgs)+ *(ckt->CKTstate1 + here->MOS2capgs)+ GateSourceOverlapCap; capgd = *(ckt->CKTstate0 + here->MOS2capgd)+ *(ckt->CKTstate1 + here->MOS2capgd)+ GateDrainOverlapCap; capgb = *(ckt->CKTstate0 + here->MOS2capgb)+ *(ckt->CKTstate1 + here->MOS2capgb)+ GateBulkOverlapCap; } if(ckt->CKTsenInfo){ here->MOS2cgs = capgs; here->MOS2cgd = capgd; here->MOS2cgb = capgb; } /* * store small-signal parameters (for meyer's model) * all parameters already stored, so done... */ if(SenCond){ if(ckt->CKTsenInfo->SENmode & (DCSEN|ACSEN)){ continue; } }#ifndef PREDICTOR if(ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) { *(ckt->CKTstate0 + here->MOS2qgs) = (1+xfact) * *(ckt->CKTstate1 + here->MOS2qgs) -xfact * *(ckt->CKTstate2 + here->MOS2qgs); *(ckt->CKTstate0 + here->MOS2qgd) = (1+xfact) * *(ckt->CKTstate1 + here->MOS2qgd) -xfact * *(ckt->CKTstate2 + here->MOS2qgd); *(ckt->CKTstate0 + here->MOS2qgb) = (1+xfact) * *(ckt->CKTstate1 + here->MOS2qgb) -xfact * *(ckt->CKTstate2 + here->MOS2qgb); } else {#endif /* PREDICTOR */ if(ckt->CKTmode & MODETRAN) { *(ckt->CKTstate0 + here->MOS2qgs) = (vgs-vgs1)*capgs + *(ckt->CKTstate1 + here->MOS2qgs) ; *(ckt->CKTstate0 + here->MOS2qgd) = (vgd-vgd1)*capgd + *(ckt->CKTstate1 + here->MOS2qgd) ; *(ckt->CKTstate0 + here->MOS2qgb) = (vgb-vgb1)*capgb + *(ckt->CKTstate1 + here->MOS2qgb) ; } else { /* TRANOP */ *(ckt->CKTstate0 + here->MOS2qgs) = capgs*vgs; *(ckt->CKTstate0 + here->MOS2qgd) = capgd*vgd; *(ckt->CKTstate0 + here->MOS2qgb) = capgb*vgb; }#ifndef PREDICTOR }#endif /* PREDICTOR */ }#ifndef NOBYPASSbypass:#endif /* NOBYPASS */ if(SenCond) continue; 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->MOS2cqgs) =0; if(capgd == 0) *(ckt->CKTstate0 + here->MOS2cqgd) =0; if(capgb == 0) *(ckt->CKTstate0 + here->MOS2cqgb) =0; /* * calculate equivalent conductances and currents for * meyer"s capacitors */ error = NIintegrate(ckt,&gcgs,&ceqgs,capgs,here->MOS2qgs); if(error) return(error); error = NIintegrate(ckt,&gcgd,&ceqgd,capgd,here->MOS2qgd); if(error) return(error); error = NIintegrate(ckt,&gcgb,&ceqgb,capgb,here->MOS2qgb); if(error) return(error); ceqgs=ceqgs-gcgs*vgs+ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOS2qgs); ceqgd=ceqgd-gcgd*vgd+ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOS2qgd); ceqgb=ceqgb-gcgb*vgb+ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOS2qgb); } /* * store charge storage info for meyer's cap in lx table */ /* * load current vector */ ceqbs = model->MOS2type * (here->MOS2cbs-(here->MOS2gbs-ckt->CKTgmin)*vbs); ceqbd = model->MOS2type * (here->MOS2cbd-(here->MOS2gbd-ckt->CKTgmin)*vbd); if (here->MOS2mode >= 0) { xnrm=1; xrev=0; cdreq=model->MOS2type*(cdrain-here->MOS2gds*vds- here->MOS2gm*vgs-here->MOS2gmbs*vbs); } else { xnrm=0; xrev=1; cdreq = -(model->MOS2type)*(cdrain-here->MOS2gds*(-vds)- here->MOS2gm*vgd-here->MOS2gmbs*vbd); } *(ckt->CKTrhs + here->MOS2gNode) -= model->MOS2type * (ceqgs + ceqgb + ceqgd); *(ckt->CKTrhs + here->MOS2bNode) -= (ceqbs+ceqbd-model->MOS2type * ceqgb); *(ckt->CKTrhs + here->MOS2dNodePrime) += ceqbd - cdreq + model->MOS2type * ceqgd; *(ckt->CKTrhs + here->MOS2sNodePrime) += cdreq + ceqbs + model->MOS2type * ceqgs;/*printf(" loading %s at time %g\n",here->MOS2name,ckt->CKTtime);/**//*printf("%g %g %g %g %g\n", here->MOS2drainConductance,gcgd+gcgs+gcgb, here->MOS2sourceConductance,here->MOS2gbd,here->MOS2gbs);/**//*printf("%g %g %g %g %g\n",-gcgb,0.0,0.0,here->MOS2gds,here->MOS2gm);/**//*printf("%g %g %g %g %g\n", here->MOS2gds,here->MOS2gmbs,gcgd,-gcgs,-gcgd);/**//*printf("%g %g %g %g %g\n", -gcgs,-gcgd,0.0,-gcgs,0.0);/**/ /* * load y matrix */ *(here->MOS2DdPtr) += (here->MOS2drainConductance); *(here->MOS2GgPtr) += gcgd+gcgs+gcgb; *(here->MOS2SsPtr) += (here->MOS2sourceConductance); *(here->MOS2BbPtr) += (here->MOS2gbd+here->MOS2gbs+gcgb); *(here->MOS2DPdpPtr) += here->MOS2drainConductance+here->MOS2gds+ here->MOS2gbd+xrev*(here->MOS2gm+here->MOS2gmbs)+gcgd; *(here->MOS2SPspPtr) += here->MOS2sourceConductance+here->MOS2gds+ here->MOS2gbs+xnrm*(here->MOS2gm+here->MOS2gmbs)+gcgs; *(here->MOS2DdpPtr) -= here->MOS2drainConductance; *(here->MOS2GbPtr) -= gcgb; *(here->MOS2GdpPtr) -= gcgd; *(here->MOS2GspPtr) -= gcgs; *(here->MOS2SspPtr) -= here->MOS2sourceConductance; *(here->MOS2BgPtr) -= gcgb; *(here->MOS2BdpPtr) -= here->MOS2gbd; *(here->MOS2BspPtr) -= here->MOS2gbs; *(here->MOS2DPdPtr) -= here->MOS2drainConductance; *(here->MOS2DPgPtr) += ((xnrm-xrev)*here->MOS2gm-gcgd); *(here->MOS2DPbPtr) += (-here->MOS2gbd+(xnrm-xrev)*here->MOS2gmbs); *(here->MOS2DPspPtr) -= here->MOS2gds+xnrm*(here->MOS2gm+ here->MOS2gmbs); *(here->MOS2SPgPtr) -= (xnrm-xrev)*here->MOS2gm+gcgs; *(here->MOS2SPsPtr) -= here->MOS2sourceConductance; *(here->MOS2SPbPtr) -= here->MOS2gbs+(xnrm-xrev)*here->MOS2gmbs; *(here->MOS2SPdpPtr) -= here->MOS2gds+xrev*(here->MOS2gm+ here->MOS2gmbs); } } return(OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -