📄 mos3sld.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Thomas L. Quarles**********//* actually load the current sensitivity * information into the array previously provided */#include "spice.h"#include <stdio.h>#include "smpdefs.h"#include "cktdefs.h"#include "mos3defs.h"#include "util.h"#include "sperror.h"#include "suffix.h"intMOS3sLoad(inModel,ckt)GENmodel *inModel;CKTcircuit *ckt;{ register MOS3model *model = (MOS3model *)inModel; register MOS3instance *here; double SaveState[44]; int save_mode; int i; int iparmno; int error; int flag; double A0; double DELA; double Apert; double DELAinv; double gspr0; double gspr; double gdpr0; double gdpr; double cdpr0; double cspr0; double cd0; double cbd0; double cbs0; double cd; double cbd; double cbs; double DcdprDp; double DcsprDp; double DcbDp; double DcdDp; double DcbsDp; double DcbdDp; double DcdprmDp; double DcsprmDp; double qgs0; double qgd0; double qgb0; double qbd0; double qbd; double qbs0; double qbs; double DqgsDp; double DqgdDp; double DqgbDp; double DqbdDp; double DqbsDp; double Osxpgs; double Osxpgd; double Osxpgb; double Osxpbd; double Osxpbs; double tag0; double tag1; double arg; double sarg; double sargsw; int offset; double EffectiveLength; SENstruct *info;#ifdef SENSDEBUG printf("MOS3senload \n"); printf("CKTtime = %.5e\n",ckt->CKTtime); printf("CKTorder = %d\n",ckt->CKTorder);#endif /* SENSDEBUG */ info = ckt->CKTsenInfo; info->SENstatus = PERTURBATION; tag0 = ckt->CKTag[0]; tag1 = ckt->CKTag[1]; if(ckt->CKTorder == 1){ tag1 = 0; } /* loop through all the models */ for( ; model != NULL; model = model->MOS3nextModel ) { /* loop through all the instances of the model */ for (here = model->MOS3instances; here != NULL ; here=here->MOS3nextInstance) {#ifdef SENSDEBUG printf("senload instance name %s\n",here->MOS3name); printf("gate = %d ,drain = %d, drainprm = %d\n", here->MOS3gNode,here->MOS3dNode,here->MOS3dNodePrime); printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n", here->MOS3sNode ,here->MOS3sNodePrime, here->MOS3bNode,here->MOS3senParmNo);#endif /* SENSDEBUG */ /* save the unperturbed values in the state vector */ for(i=0; i <= 16; i++){ *(SaveState + i) = *(ckt->CKTstate0 + here->MOS3states + i); } *(SaveState + 17) = here->MOS3sourceConductance; *(SaveState + 18) = here->MOS3drainConductance; *(SaveState + 19) = here->MOS3cd; *(SaveState + 20) = here->MOS3cbs; *(SaveState + 21) = here->MOS3cbd; *(SaveState + 22) = here->MOS3gmbs; *(SaveState + 23) = here->MOS3gm; *(SaveState + 24) = here->MOS3gds; *(SaveState + 25) = here->MOS3gbd; *(SaveState + 26) = here->MOS3gbs; *(SaveState + 27) = here->MOS3capbd; *(SaveState + 28) = here->MOS3capbs; *(SaveState + 29) = here->MOS3Cbd; *(SaveState + 30) = here->MOS3Cbdsw; *(SaveState + 31) = here->MOS3Cbs; *(SaveState + 32) = here->MOS3Cbssw; *(SaveState + 33) = here->MOS3f2d; *(SaveState + 34) = here->MOS3f3d; *(SaveState + 35) = here->MOS3f4d; *(SaveState + 36) = here->MOS3f2s; *(SaveState + 37) = here->MOS3f3s; *(SaveState + 38) = here->MOS3f4s; *(SaveState + 39) = here->MOS3cgs; *(SaveState + 40) = here->MOS3cgd; *(SaveState + 41) = here->MOS3cgb; *(SaveState + 42) = here->MOS3vdsat; *(SaveState + 43) = here->MOS3von; save_mode = here->MOS3mode; if(here->MOS3senParmNo == 0) goto next1;#ifdef SENSDEBUG printf("without perturbation \n");#endif /* SENSDEBUG */ cdpr0= here->MOS3cd; cspr0= -(here->MOS3cd + here->MOS3cbd + here->MOS3cbs); if((info->SENmode == TRANSEN) && (ckt->CKTmode & MODEINITTRAN)){ qgs0 = *(ckt->CKTstate1 + here->MOS3qgs); qgd0 = *(ckt->CKTstate1 + here->MOS3qgd); qgb0 = *(ckt->CKTstate1 + here->MOS3qgb); } else{ qgs0 = *(ckt->CKTstate0 + here->MOS3qgs); qgd0 = *(ckt->CKTstate0 + here->MOS3qgd); qgb0 = *(ckt->CKTstate0 + here->MOS3qgb); } here->MOS3senPertFlag = ON; error = MOS3load((GENmodel*)model,ckt); if(error) return(error); cd0 = here->MOS3cd ; cbd0 = here->MOS3cbd ; cbs0 = here->MOS3cbs ; gspr0= here->MOS3sourceConductance ; gdpr0= here->MOS3drainConductance ; qbs0 = *(ckt->CKTstate0 + here->MOS3qbs); qbd0 = *(ckt->CKTstate0 + here->MOS3qbd); for( flag = 0 ; flag <= 1 ; flag++){ if(here->MOS3sens_l == 0) if(flag == 0) goto next2; if(here->MOS3sens_w == 0) if(flag == 1) goto next2; if(flag == 0){ A0 = here->MOS3l; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; Apert = A0 + DELA; here->MOS3l = Apert; } else{ A0 = here->MOS3w; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; Apert = A0 + DELA; here->MOS3w = Apert; here->MOS3drainArea *= (1 + info->SENpertfac); here->MOS3sourceArea *= (1 + info->SENpertfac); here->MOS3Cbd *= (1 + info->SENpertfac); here->MOS3Cbs *= (1 + info->SENpertfac); if(here->MOS3drainPerimiter){ here->MOS3Cbdsw += here->MOS3Cbdsw * DELA/here->MOS3drainPerimiter; } if(here->MOS3sourcePerimiter){ here->MOS3Cbssw += here->MOS3Cbssw * DELA/here->MOS3sourcePerimiter; } if(*(ckt->CKTstate0 + here->MOS3vbd) >= here->MOS3tDepCap){ arg = 1-model->MOS3fwdCapDepCoeff; sarg = exp( (-model->MOS3bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS3bulkJctSideGradingCoeff) * log(arg) ); here->MOS3f2d = here->MOS3Cbd* (1-model->MOS3fwdCapDepCoeff* (1+model->MOS3bulkJctBotGradingCoeff))* sarg/arg + here->MOS3Cbdsw*(1-model->MOS3fwdCapDepCoeff* (1+model->MOS3bulkJctSideGradingCoeff))* sargsw/arg; here->MOS3f3d = here->MOS3Cbd * model->MOS3bulkJctBotGradingCoeff * sarg/arg/ model->MOS3bulkJctPotential + here->MOS3Cbdsw * model->MOS3bulkJctSideGradingCoeff *sargsw/arg / model->MOS3bulkJctPotential; here->MOS3f4d = here->MOS3Cbd* model->MOS3bulkJctPotential*(1-arg*sarg)/ (1-model->MOS3bulkJctBotGradingCoeff) + here->MOS3Cbdsw*model->MOS3bulkJctPotential* (1-arg*sargsw)/ (1-model->MOS3bulkJctSideGradingCoeff) -here->MOS3f3d/2* (here->MOS3tDepCap*here->MOS3tDepCap) -here->MOS3tDepCap * here->MOS3f2d; } if(*(ckt->CKTstate0 + here->MOS3vbs) >= here->MOS3tDepCap){ arg = 1-model->MOS3fwdCapDepCoeff; sarg = exp( (-model->MOS3bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS3bulkJctSideGradingCoeff) * log(arg) ); here->MOS3f2s = here->MOS3Cbs* (1-model->MOS3fwdCapDepCoeff* (1+model->MOS3bulkJctBotGradingCoeff))* sarg/arg + here->MOS3Cbssw*(1-model->MOS3fwdCapDepCoeff* (1+model->MOS3bulkJctSideGradingCoeff))* sargsw/arg; here->MOS3f3s = here->MOS3Cbs * model->MOS3bulkJctBotGradingCoeff * sarg/arg/ model->MOS3bulkJctPotential + here->MOS3Cbssw * model->MOS3bulkJctSideGradingCoeff * sargsw/arg/ model->MOS3bulkJctPotential; here->MOS3f4s = here->MOS3Cbs* model->MOS3bulkJctPotential*(1-arg*sarg)/ (1-model->MOS3bulkJctBotGradingCoeff) + here->MOS3Cbssw*model->MOS3bulkJctPotential* (1-arg*sargsw)/ (1-model->MOS3bulkJctSideGradingCoeff) -here->MOS3f3s/2* (here->MOS3tBulkPot*here->MOS3tBulkPot) -here->MOS3tBulkPot * here->MOS3f2s; } here->MOS3drainConductance *= Apert/A0; here->MOS3sourceConductance *= Apert/A0; }#ifdef SENSDEBUG if(flag == 0) printf("perturbation of l\n"); if(flag == 1) printf("perturbation of w\n");#endif /* SENSDEBUG */ error = MOS3load((GENmodel*)model,ckt); if(error) return(error); if(flag == 0){ here->MOS3l = A0; } else{ here->MOS3w = A0; here->MOS3drainArea /= (1 + info->SENpertfac); here->MOS3sourceArea /= (1 + info->SENpertfac); here->MOS3drainConductance *= A0/Apert; here->MOS3sourceConductance *= A0/Apert; } cd = here->MOS3cd ; cbd = here->MOS3cbd ; cbs = here->MOS3cbs ; gspr= here->MOS3sourceConductance ; gdpr= here->MOS3drainConductance ; DcdDp = (cd - cd0) * DELAinv; DcbsDp = (cbs - cbs0) * DELAinv; DcbdDp = (cbd - cbd0) * DELAinv; DcbDp = ( DcbsDp + DcbdDp ); DcdprDp = 0; DcsprDp = 0; if(here->MOS3dNode != here->MOS3dNodePrime) if(gdpr0) DcdprDp = cdpr0 * (gdpr - gdpr0)/gdpr0 * DELAinv; if(here->MOS3sNode != here->MOS3sNodePrime)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -