📄 mos1sld.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 "mos1defs.h"#include "util.h"#include "sperror.h"#include "suffix.h"intMOS1sLoad(inModel,ckt)GENmodel *inModel;CKTcircuit *ckt;{ register MOS1model *model = (MOS1model *)inModel; register MOS1instance *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("MOS1senload \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->MOS1nextModel ) { /* loop through all the instances of the model */ for (here = model->MOS1instances; here != NULL ; here=here->MOS1nextInstance) { if (here->MOS1owner != ARCHme) continue;#ifdef SENSDEBUG printf("senload instance name %s\n",here->MOS1name); printf("gate = %d ,drain = %d, drainprm = %d\n", here->MOS1gNode,here->MOS1dNode,here->MOS1dNodePrime); printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n", here->MOS1sNode ,here->MOS1sNodePrime, here->MOS1bNode,here->MOS1senParmNo);#endif /* SENSDEBUG */ /* save the unperturbed values in the state vector */ for(i=0; i <= 16; i++){ *(SaveState + i) = *(ckt->CKTstate0 + here->MOS1states + i); } *(SaveState + 17) = here->MOS1sourceConductance; *(SaveState + 18) = here->MOS1drainConductance; *(SaveState + 19) = here->MOS1cd; *(SaveState + 20) = here->MOS1cbs; *(SaveState + 21) = here->MOS1cbd; *(SaveState + 22) = here->MOS1gmbs; *(SaveState + 23) = here->MOS1gm; *(SaveState + 24) = here->MOS1gds; *(SaveState + 25) = here->MOS1gbd; *(SaveState + 26) = here->MOS1gbs; *(SaveState + 27) = here->MOS1capbd; *(SaveState + 28) = here->MOS1capbs; *(SaveState + 29) = here->MOS1Cbd; *(SaveState + 30) = here->MOS1Cbdsw; *(SaveState + 31) = here->MOS1Cbs; *(SaveState + 32) = here->MOS1Cbssw; *(SaveState + 33) = here->MOS1f2d; *(SaveState + 34) = here->MOS1f3d; *(SaveState + 35) = here->MOS1f4d; *(SaveState + 36) = here->MOS1f2s; *(SaveState + 37) = here->MOS1f3s; *(SaveState + 38) = here->MOS1f4s; *(SaveState + 39) = here->MOS1cgs; *(SaveState + 40) = here->MOS1cgd; *(SaveState + 41) = here->MOS1cgb; *(SaveState + 42) = here->MOS1vdsat; *(SaveState + 43) = here->MOS1von; save_mode = here->MOS1mode; if(here->MOS1senParmNo == 0) goto next1;#ifdef SENSDEBUG printf("without perturbation \n"); printf("gbd =%.5e\n",here->MOS1gbd); printf("satCur =%.5e\n",here->MOS1tSatCur); printf("satCurDens =%.5e\n",here->MOS1tSatCurDens); printf("vbd =%.5e\n",*(ckt->CKTstate0 + here->MOS1vbd));#endif /* SENSDEBUG */ cdpr0= here->MOS1cd; cspr0= -(here->MOS1cd + here->MOS1cbd + here->MOS1cbs); if((info->SENmode == TRANSEN) && (ckt->CKTmode & MODEINITTRAN)){ qgs0 = *(ckt->CKTstate1 + here->MOS1qgs); qgd0 = *(ckt->CKTstate1 + here->MOS1qgd); qgb0 = *(ckt->CKTstate1 + here->MOS1qgb); } else{ qgs0 = *(ckt->CKTstate0 + here->MOS1qgs); qgd0 = *(ckt->CKTstate0 + here->MOS1qgd); qgb0 = *(ckt->CKTstate0 + here->MOS1qgb); } here->MOS1senPertFlag = ON; error = MOS1load((GENmodel*)model,ckt); if(error) return(error); cd0 = here->MOS1cd ; cbd0 = here->MOS1cbd ; cbs0 = here->MOS1cbs ; gspr0= here->MOS1sourceConductance ; gdpr0= here->MOS1drainConductance ; qbs0 = *(ckt->CKTstate0 + here->MOS1qbs); qbd0 = *(ckt->CKTstate0 + here->MOS1qbd); for( flag = 0 ; flag <= 1 ; flag++){ if(here->MOS1sens_l == 0) if(flag == 0) goto next2; if(here->MOS1sens_w == 0) if(flag == 1) goto next2; if(flag == 0){ A0 = here->MOS1l; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; Apert = A0 + DELA; here->MOS1l = Apert; } else{ A0 = here->MOS1w; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; Apert = A0 + DELA; here->MOS1w = Apert; here->MOS1drainArea *= (1 + info->SENpertfac); here->MOS1sourceArea *= (1 + info->SENpertfac); here->MOS1Cbd *= (1 + info->SENpertfac); here->MOS1Cbs *= (1 + info->SENpertfac); if(here->MOS1drainPerimiter){ here->MOS1Cbdsw += here->MOS1Cbdsw * DELA/here->MOS1drainPerimiter; } if(here->MOS1sourcePerimiter){ here->MOS1Cbssw += here->MOS1Cbssw * DELA/here->MOS1sourcePerimiter; } if(*(ckt->CKTstate0 + here->MOS1vbd) >= here->MOS1tDepCap){ arg = 1-model->MOS1fwdCapDepCoeff; sarg = exp( (-model->MOS1bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS1bulkJctSideGradingCoeff) * log(arg) ); here->MOS1f2d = here->MOS1Cbd* (1-model->MOS1fwdCapDepCoeff* (1+model->MOS1bulkJctBotGradingCoeff))* sarg/arg + here->MOS1Cbdsw*(1-model->MOS1fwdCapDepCoeff* (1+model->MOS1bulkJctSideGradingCoeff))* sargsw/arg; here->MOS1f3d = here->MOS1Cbd * model->MOS1bulkJctBotGradingCoeff * sarg/arg/ here->MOS1tBulkPot + here->MOS1Cbdsw * model->MOS1bulkJctSideGradingCoeff * sargsw/arg/ here->MOS1tBulkPot; here->MOS1f4d = here->MOS1Cbd* here->MOS1tBulkPot*(1-arg*sarg)/ (1-model->MOS1bulkJctBotGradingCoeff) + here->MOS1Cbdsw*here->MOS1tBulkPot* (1-arg*sargsw)/ (1-model->MOS1bulkJctSideGradingCoeff) -here->MOS1f3d/2* (here->MOS1tDepCap*here->MOS1tDepCap) -here->MOS1tDepCap * here->MOS1f2d; } if(*(ckt->CKTstate0 + here->MOS1vbs) >= here->MOS1tDepCap){ arg = 1-model->MOS1fwdCapDepCoeff; sarg = exp( (-model->MOS1bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS1bulkJctSideGradingCoeff) * log(arg) ); here->MOS1f2s = here->MOS1Cbs* (1-model->MOS1fwdCapDepCoeff* (1+model->MOS1bulkJctBotGradingCoeff))* sarg/arg + here->MOS1Cbssw*(1-model->MOS1fwdCapDepCoeff* (1+model->MOS1bulkJctSideGradingCoeff))* sargsw/arg; here->MOS1f3s = here->MOS1Cbs * model->MOS1bulkJctBotGradingCoeff * sarg/arg/ here->MOS1tBulkPot + here->MOS1Cbssw * model->MOS1bulkJctSideGradingCoeff * sargsw/arg/ here->MOS1tBulkPot; here->MOS1f4s = here->MOS1Cbs* here->MOS1tBulkPot*(1-arg*sarg)/ (1-model->MOS1bulkJctBotGradingCoeff) + here->MOS1Cbssw*here->MOS1tBulkPot* (1-arg*sargsw)/ (1-model->MOS1bulkJctSideGradingCoeff) -here->MOS1f3s/2* (here->MOS1tDepCap*here->MOS1tDepCap) -here->MOS1tDepCap * here->MOS1f2s; } here->MOS1drainConductance *= Apert/A0; here->MOS1sourceConductance *= Apert/A0; }#ifdef SENSDEBUG if(flag == 0) printf("perturbation of l\n"); if(flag == 1) printf("perturbation of w\n");#endif /* SENSDEBUG */ error = MOS1load((GENmodel*)model,ckt); if(error) return(error); if(flag == 0){ here->MOS1l = A0; } else{ here->MOS1w = A0; here->MOS1drainArea /= (1 + info->SENpertfac); here->MOS1sourceArea /= (1 + info->SENpertfac); here->MOS1drainConductance *= A0/Apert; here->MOS1sourceConductance *= A0/Apert; } cd = here->MOS1cd ; cbd = here->MOS1cbd ; cbs = here->MOS1cbs ; gspr= here->MOS1sourceConductance ; gdpr= here->MOS1drainConductance ; DcdDp = (cd - cd0) * DELAinv; DcbsDp = (cbs - cbs0) * DELAinv; DcbdDp = (cbd - cbd0) * DELAinv; DcbDp = ( DcbsDp + DcbdDp ); DcdprDp = 0; DcsprDp = 0; if(here->MOS1dNode != here->MOS1dNodePrime)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -