📄 mos2sacl.c
字号:
- *(ckt->CKTrhsOp + here->MOS2bNode)); DELA = info->SENpertfac * A0 + 1e-8; DELAinv = model->MOS2type * 1.0/DELA; if(info->SENacpertflag == 1){ /* store the values of small signal parameters * corresponding to perturbed vgb */ *(ckt->CKTstate0 + here->MOS2vbs) = vbsOp; *(ckt->CKTstate0 + here->MOS2vbd) = vbdOp; *(ckt->CKTrhsOp + here->MOS2bNode) -= DELA; if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs + 3) = here->MOS2cgs; *(here->MOS2senCgd + 3) = here->MOS2cgd; *(here->MOS2senCgb + 3) = here->MOS2cgb; *(here->MOS2senCbd + 3) = here->MOS2capbd; *(here->MOS2senCbs + 3) = here->MOS2capbs; *(here->MOS2senGds + 3) = here->MOS2gds; *(here->MOS2senGbs + 3) = here->MOS2gbs; *(here->MOS2senGbd + 3) = here->MOS2gbd; *(here->MOS2senGm + 3) = here->MOS2gm; *(here->MOS2senGmbs + 3) = here->MOS2gmbs; *(ckt->CKTrhsOp + here->MOS2bNode) += DELA; } goto load;pertl: /* Perturbation of length */ if(here->MOS2sens_l == 0){ goto pertw; }#ifdef SENSDEBUG printf("\nPerturbation of length\n");#endif /* SENSDEBUG */ flag = 4; A0 = here->MOS2l; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; if(info->SENacpertflag == 1){ /* store the values of small signal parameters * corresponding to perturbed length */ Apert = A0 + DELA; here->MOS2l = Apert; *(ckt->CKTstate0 + here->MOS2vbs) = vbsOp; *(ckt->CKTstate0 + here->MOS2vbd) = vbdOp; if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs + 4) = here->MOS2cgs; *(here->MOS2senCgd + 4) = here->MOS2cgd; *(here->MOS2senCgb + 4) = here->MOS2cgb; *(here->MOS2senCbd + 4) = here->MOS2capbd; *(here->MOS2senCbs + 4) = here->MOS2capbs; *(here->MOS2senGds + 4) = here->MOS2gds; *(here->MOS2senGbs + 4) = here->MOS2gbs; *(here->MOS2senGbd + 4) = here->MOS2gbd; *(here->MOS2senGm + 4) = here->MOS2gm; *(here->MOS2senGmbs + 4) = here->MOS2gmbs; here->MOS2l = A0; } goto load;pertw: /* Perturbation of width */ if(here->MOS2sens_w == 0) goto next;#ifdef SENSDEBUG printf("\nPerturbation of width\n");#endif /* SENSDEBUG */ flag = 5; A0 = here->MOS2w; DELA = info->SENpertfac * A0; DELAinv = 1.0/DELA; Apert = A0 + DELA; if(info->SENacpertflag == 1){ /* store the values of small signal parameters * corresponding to perturbed width */ here->MOS2w = Apert; here->MOS2drainArea *= (1 + info->SENpertfac); here->MOS2sourceArea *= (1 + info->SENpertfac); here->MOS2Cbd *= (1 + info->SENpertfac); here->MOS2Cbs *= (1 + info->SENpertfac); if(here->MOS2drainPerimiter){ here->MOS2Cbdsw += here->MOS2Cbdsw * DELA/here->MOS2drainPerimiter; } if(here->MOS2sourcePerimiter){ here->MOS2Cbssw += here->MOS2Cbssw * DELA/here->MOS2sourcePerimiter; } if(vbdOp >= here->MOS2tDepCap){ arg = 1-model->MOS2fwdCapDepCoeff; sarg = exp( (-model->MOS2bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS2bulkJctSideGradingCoeff) * log(arg) ); here->MOS2f2d = here->MOS2Cbd*(1-model->MOS2fwdCapDepCoeff* (1+model->MOS2bulkJctBotGradingCoeff))* sarg/arg + here->MOS2Cbdsw*(1-model->MOS2fwdCapDepCoeff* (1+model->MOS2bulkJctSideGradingCoeff))* sargsw/arg; here->MOS2f3d = here->MOS2Cbd * model->MOS2bulkJctBotGradingCoeff * sarg/arg/ here->MOS2tBulkPot + here->MOS2Cbdsw * model->MOS2bulkJctSideGradingCoeff * sargsw/arg / here->MOS2tBulkPot; here->MOS2f4d = here->MOS2Cbd*here->MOS2tBulkPot* (1-arg*sarg)/(1-model->MOS2bulkJctBotGradingCoeff) + here->MOS2Cbdsw*here->MOS2tBulkPot*(1-arg*sargsw)/ (1-model->MOS2bulkJctSideGradingCoeff) -here->MOS2f3d/2* (here->MOS2tDepCap*here->MOS2tDepCap) -here->MOS2tDepCap * here->MOS2f2d; } if(vbsOp >= here->MOS2tDepCap){ arg = 1-model->MOS2fwdCapDepCoeff; sarg = exp( (-model->MOS2bulkJctBotGradingCoeff) * log(arg) ); sargsw = exp( (-model->MOS2bulkJctSideGradingCoeff) * log(arg) ); here->MOS2f2s = here->MOS2Cbs*(1-model->MOS2fwdCapDepCoeff* (1+model->MOS2bulkJctBotGradingCoeff))* sarg/arg + here->MOS2Cbssw*(1-model->MOS2fwdCapDepCoeff* (1+model->MOS2bulkJctSideGradingCoeff))* sargsw/arg; here->MOS2f3s = here->MOS2Cbs * model->MOS2bulkJctBotGradingCoeff * sarg/arg/ here->MOS2tBulkPot + here->MOS2Cbssw * model->MOS2bulkJctSideGradingCoeff * sargsw/arg / here->MOS2tBulkPot; here->MOS2f4s = here->MOS2Cbs*here->MOS2tBulkPot* (1-arg*sarg)/(1-model->MOS2bulkJctBotGradingCoeff) + here->MOS2Cbssw*here->MOS2tBulkPot*(1-arg*sargsw)/ (1-model->MOS2bulkJctSideGradingCoeff) -here->MOS2f3s/2* (here->MOS2tDepCap*here->MOS2tDepCap) -here->MOS2tDepCap * here->MOS2f2s; } *(ckt->CKTstate0 + here->MOS2vbs) = vbsOp; *(ckt->CKTstate0 + here->MOS2vbd) = vbdOp; if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs + 5) = here->MOS2cgs; *(here->MOS2senCgd + 5) = here->MOS2cgd; *(here->MOS2senCgb + 5) = here->MOS2cgb; *(here->MOS2senCbd + 5) = here->MOS2capbd; *(here->MOS2senCbs + 5) = here->MOS2capbs; *(here->MOS2senGds + 5) = here->MOS2gds; *(here->MOS2senGbs + 5) = here->MOS2gbs; *(here->MOS2senGbd + 5) = here->MOS2gbd; *(here->MOS2senGm + 5) = here->MOS2gm; *(here->MOS2senGmbs + 5) = here->MOS2gmbs; here->MOS2w = A0; here->MOS2drainArea /= (1 + info->SENpertfac); here->MOS2sourceArea /= (1 + info->SENpertfac); }load: gds= *(here->MOS2senGds + flag); gbs= *(here->MOS2senGbs + flag); gbd= *(here->MOS2senGbd + flag); gm= *(here->MOS2senGm + flag); gmbs= *(here->MOS2senGmbs + flag); if(flag == 5){ gdpr = here->MOS2drainConductance * Apert/A0; gspr = here->MOS2sourceConductance * Apert/A0; } else{ gdpr = here->MOS2drainConductance; gspr = here->MOS2sourceConductance; } xcgs= *(here->MOS2senCgs + flag) * ckt->CKTomega; xcgd= *(here->MOS2senCgd + flag) * ckt->CKTomega; xcgb= *(here->MOS2senCgb + flag) * ckt->CKTomega; xbd= *(here->MOS2senCbd + flag) * ckt->CKTomega; xbs= *(here->MOS2senCbs + flag) * ckt->CKTomega;#ifdef SENSDEBUG printf("flag = %d \n",flag); printf("gspr = %.7e , gdpr = %.7e , gds = %.7e, gbs = %.7e\n", gspr,gdpr,gds,gbs); printf("gbd = %.7e , gm = %.7e , gmbs = %.7e\n",gbd,gm,gmbs); printf("xcgs = %.7e , xcgd = %.7e , xcgb = %.7e,", xcgs,xcgd,xcgb); printf("xbd = %.7e,xbs = %.7e\n", xbd,xbs);#endif /* SENSDEBUG */ cspr = gspr * vspr ; icspr = gspr * ivspr ; cdpr = gdpr * vdpr ; icdpr = gdpr * ivdpr ; cgs = ( - xcgs * ivgs ); icgs = xcgs * vgs ; cgd = ( - xcgd * ivgd ); icgd = xcgd * vgd ; cgb = ( - xcgb * ivgb ); icgb = xcgb * vgb ; cbs = ( gbs * vbs - xbs * ivbs ); icbs = ( xbs * vbs + gbs * ivbs ); cbd = ( gbd * vbd - xbd * ivbd ); icbd = ( xbd * vbd + gbd * ivbd ); cds = ( gds * vds + xnrm * (gm * vgs + gmbs * vbs) - xrev * (gm * vgd + gmbs * vbd) ); icds = ( gds * ivds + xnrm * (gm * ivgs + gmbs * ivbs) - xrev * (gm * ivgd + gmbs * ivbd) ); cs = cspr; ics = icspr; csprm = ( -cspr - cgs - cbs - cds ) ; icsprm = ( -icspr - icgs - icbs - icds ) ; cd = cdpr; icd = icdpr; cdprm = ( -cdpr - cgd - cbd + cds ) ; icdprm = ( -icdpr - icgd - icbd + icds ) ; cg = cgs + cgd + cgb ; icg = icgs + icgd + icgb ; cb = cbs + cbd - cgb ; icb = icbs + icbd - icgb ;#ifdef SENSDEBUG printf("vbs = %.7e , vbd = %.7e , vgb = %.7e\n",vbs,vbd,vgb); printf("ivbs = %.7e , ivbd = %.7e , ivgb = %.7e\n",ivbs,ivbd,ivgb); printf("cbs = %.7e , cbd = %.7e , cgb = %.7e\n",cbs,cbd,cgb); printf("cb = %.7e , cg = %.7e , cs = %.7e\n",cb,cg,cs); printf("csprm = %.7e, cd = %.7e, cdprm = %.7e\n",csprm,cd,cdprm); printf("icb = %.7e , icg = %.7e , ics = %.7e\n",icb,icg,ics); printf("icsprm = %.7e, icd = %.7e, icdprm = %.7e\n", icsprm,icd,icdprm);#endif /* SENSDEBUG */ for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ if ((flag == 4) || (iparmno != here->MOS2senParmNo) ) continue; if ((flag == 5) || (iparmno != (here->MOS2senParmNo + here->MOS2sens_l)) ) continue; switch(flag){ case 1: DvDp = model->MOS2type * (info->SEN_Sap[here->MOS2bNode][iparmno] - info->SEN_Sap[here->MOS2sNodePrime][iparmno]); break; case 2: DvDp = model->MOS2type * ( info->SEN_Sap[here->MOS2bNode][iparmno] - info->SEN_Sap[here->MOS2dNodePrime][iparmno]); break; case 3: DvDp = model->MOS2type * ( info->SEN_Sap[here->MOS2gNode][iparmno] - info->SEN_Sap[here->MOS2bNode][iparmno]); break; case 4: DvDp = 1; break; case 5: DvDp = 1; break; } *(info->SEN_RHS[here->MOS2bNode] + iparmno) -= ( cb - cb0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2bNode] + iparmno) -= ( icb - icb0) * DELAinv * DvDp; *(info->SEN_RHS[here->MOS2gNode] + iparmno) -= ( cg - cg0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2gNode] + iparmno) -= ( icg - icg0) * DELAinv * DvDp; if(here->MOS2sNode != here->MOS2sNodePrime){ *(info->SEN_RHS[here->MOS2sNode] + iparmno) -= ( cs - cs0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2sNode] + iparmno) -= ( ics - ics0) * DELAinv * DvDp; } *(info->SEN_RHS[here->MOS2sNodePrime] + iparmno) -= ( csprm - csprm0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2sNodePrime] + iparmno) -= ( icsprm - icsprm0) * DELAinv * DvDp; if(here->MOS2dNode != here->MOS2dNodePrime){ *(info->SEN_RHS[here->MOS2dNode] + iparmno) -= ( cd - cd0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2dNode] + iparmno) -= ( icd - icd0) * DELAinv * DvDp; } *(info->SEN_RHS[here->MOS2dNodePrime] + iparmno) -= ( cdprm - cdprm0) * DELAinv * DvDp; *(info->SEN_iRHS[here->MOS2dNodePrime] + iparmno) -= ( icdprm - icdprm0) * DELAinv * DvDp;#ifdef SENSDEBUG printf("after loading\n"); printf("DvDp = %.5e , DELAinv = %.5e ,flag = %d ,", DvDp,DELAinv,flag); printf("iparmno = %d,senparmno = %d\n" ,iparmno,here->MOS2senParmNo); printf("A0 = %.5e , Apert = %.5e ,CONSTvt0 = %.5e \n", A0,Apert,CONSTvt0); printf("senb = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2bNode] + iparmno), *(info->SEN_iRHS[here->MOS2bNode] + iparmno)); printf("seng = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2gNode] + iparmno), *(info->SEN_iRHS[here->MOS2gNode] + iparmno)); printf("sens = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2sNode] + iparmno), *(info->SEN_iRHS[here->MOS2sNode] + iparmno)); printf("sensprm = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2sNodePrime] + iparmno), *(info->SEN_iRHS[here->MOS2sNodePrime] + iparmno)); printf("send = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2dNode] + iparmno), *(info->SEN_iRHS[here->MOS2dNode] + iparmno)); printf("sendprm = %.7e + j%.7e ", *(info->SEN_RHS[here->MOS2dNodePrime] + iparmno), *(info->SEN_iRHS[here->MOS2dNodePrime] + iparmno));#endif /* SENSDEBUG */ } switch(flag){ case 1: goto pertvbd ; case 2: goto pertvgb ; case 3: goto pertl ; case 4: goto pertw ; case 5: break; }next: ; /* put the unperturbed values back into the state vector */ for(i=0; i <= 16; i++) *(ckt->CKTstate0 + here->MOS2states + i) = *(SaveState + i); here->MOS2sourceConductance = *(SaveState + 17) ; here->MOS2drainConductance = *(SaveState + 18) ; here->MOS2cd = *(SaveState + 19) ; here->MOS2cbs = *(SaveState + 20) ; here->MOS2cbd = *(SaveState + 21) ; here->MOS2gmbs = *(SaveState + 22) ; here->MOS2gm = *(SaveState + 23) ; here->MOS2gds = *(SaveState + 24) ; here->MOS2gbd = *(SaveState + 25) ; here->MOS2gbs = *(SaveState + 26) ; here->MOS2capbd = *(SaveState + 27) ; here->MOS2capbs = *(SaveState + 28) ; here->MOS2Cbd = *(SaveState + 29) ; here->MOS2Cbdsw = *(SaveState + 30) ; here->MOS2Cbs = *(SaveState + 31) ; here->MOS2Cbssw = *(SaveState + 32) ; here->MOS2f2d = *(SaveState + 33) ; here->MOS2f3d = *(SaveState + 34) ; here->MOS2f4d = *(SaveState + 35) ; here->MOS2f2s = *(SaveState + 36) ; here->MOS2f3s = *(SaveState + 37) ; here->MOS2f4s = *(SaveState + 38) ; here->MOS2cgs = *(SaveState + 39) ; here->MOS2cgd = *(SaveState + 40) ; here->MOS2cgb = *(SaveState + 41) ; here->MOS2vdsat = *(SaveState + 42) ; here->MOS2von = *(SaveState + 43) ; here->MOS2mode = save_mode ; here->MOS2senPertFlag = OFF; } } info->SENstatus = NORMAL;#ifdef SENSDEBUG printf("MOS2senacload end\n");#endif /* SENSDEBUG */ return(OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -