📄 mos2sacl.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Thomas L. Quarles**********//* actually load the current ac sensitivity * information into the array previously provided */#include "spice.h"#include <stdio.h>#include "smpdefs.h"#include "cktdefs.h"#include "const.h"#include "mos2defs.h"#include "util.h"#include "sperror.h"#include "suffix.h"intMOS2sAcLoad(inModel,ckt)GENmodel *inModel;register CKTcircuit *ckt;{ register MOS2model *model = (MOS2model *)inModel; register MOS2instance *here; int xnrm; int xrev; double A0; double Apert; double DELA; double DELAinv; double gdpr0; double gspr0; double gds0; double gbs0; double gbd0; double gm0; double gmbs0; double gdpr; double gspr; double gds; double gbs; double gbd; double gm; double gmbs; double xcgs0; double xcgd0; double xcgb0; double xbd0; double xbs0; double xcgs; double xcgd; double xcgb; double xbd; double xbs; double vbsOp; double vbdOp; double vspr; double vdpr; double vgs; double vgd; double vgb; double vbs; double vbd; double vds; double ivspr; double ivdpr; double ivgs; double ivgd; double ivgb; double ivbs; double ivbd; double ivds; double cspr; double cdpr; double cgs; double cgd; double cgb; double cbs; double cbd; double cds; double cs0; double csprm0; double cd0; double cdprm0; double cg0; double cb0; double cs; double csprm; double cd; double cdprm; double cg; double cb; double icspr; double icdpr; double icgs; double icgd; double icgb; double icbs; double icbd; double icds; double ics0; double icsprm0; double icd0; double icdprm0; double icg0; double icb0; double ics; double icsprm; double icd; double icdprm; double icg; double icb; double DvDp; int i; int flag; int error; int iparmno; double arg; double sarg; double sargsw; double SaveState[44]; int save_mode; SENstruct *info;#ifdef SENSDEBUG printf("MOS2senacload\n"); printf("CKTomega = %.5e\n",ckt->CKTomega);#endif /* SENSDEBUG */ info = ckt->CKTsenInfo; info->SENstatus = PERTURBATION; for( ; model != NULL; model = model->MOS2nextModel) { for(here = model->MOS2instances; here!= NULL; here = here->MOS2nextInstance) { if (here->MOS2owner != ARCHme) continue; /* save the unperturbed values in the state vector */ for(i=0; i <= 16; i++) *(SaveState + i) = *(ckt->CKTstate0 + here->MOS2states + i); *(SaveState + 17) = here->MOS2sourceConductance; *(SaveState + 18) = here->MOS2drainConductance; *(SaveState + 19) = here->MOS2cd; *(SaveState + 20) = here->MOS2cbs; *(SaveState + 21) = here->MOS2cbd; *(SaveState + 22) = here->MOS2gmbs; *(SaveState + 23) = here->MOS2gm; *(SaveState + 24) = here->MOS2gds; *(SaveState + 25) = here->MOS2gbd; *(SaveState + 26) = here->MOS2gbs; *(SaveState + 27) = here->MOS2capbd; *(SaveState + 28) = here->MOS2capbs; *(SaveState + 29) = here->MOS2Cbd; *(SaveState + 30) = here->MOS2Cbdsw; *(SaveState + 31) = here->MOS2Cbs; *(SaveState + 32) = here->MOS2Cbssw; *(SaveState + 33) = here->MOS2f2d; *(SaveState + 34) = here->MOS2f3d; *(SaveState + 35) = here->MOS2f4d; *(SaveState + 36) = here->MOS2f2s; *(SaveState + 37) = here->MOS2f3s; *(SaveState + 38) = here->MOS2f4s; *(SaveState + 39) = here->MOS2cgs; *(SaveState + 40) = here->MOS2cgd; *(SaveState + 41) = here->MOS2cgb; *(SaveState + 42) = here->MOS2vdsat; *(SaveState + 43) = here->MOS2von; save_mode = here->MOS2mode; xnrm=1; xrev=0; if (here->MOS2mode < 0) { xnrm=0; xrev=1; } vbsOp = model->MOS2type * ( *(ckt->CKTrhsOp+here->MOS2bNode) - *(ckt->CKTrhsOp+here->MOS2sNodePrime)); vbdOp = model->MOS2type * ( *(ckt->CKTrhsOp+here->MOS2bNode) - *(ckt->CKTrhsOp+here->MOS2dNodePrime)); vspr = *(ckt->CKTrhsOld + here->MOS2sNode) - *(ckt->CKTrhsOld + here->MOS2sNodePrime) ; ivspr = *(ckt->CKTirhsOld + here->MOS2sNode) - *(ckt->CKTirhsOld + here->MOS2sNodePrime) ; vdpr = *(ckt->CKTrhsOld + here->MOS2dNode) - *(ckt->CKTrhsOld + here->MOS2dNodePrime) ; ivdpr = *(ckt->CKTirhsOld + here->MOS2dNode) - *(ckt->CKTirhsOld + here->MOS2dNodePrime) ; vgb = *(ckt->CKTrhsOld + here->MOS2gNode) - *(ckt->CKTrhsOld + here->MOS2bNode) ; ivgb = *(ckt->CKTirhsOld + here->MOS2gNode) - *(ckt->CKTirhsOld + here->MOS2bNode) ; vbs = *(ckt->CKTrhsOld + here->MOS2bNode) - *(ckt->CKTrhsOld + here->MOS2sNodePrime) ; ivbs = *(ckt->CKTirhsOld + here->MOS2bNode) - *(ckt->CKTirhsOld + here->MOS2sNodePrime) ; vbd = *(ckt->CKTrhsOld + here->MOS2bNode) - *(ckt->CKTrhsOld + here->MOS2dNodePrime) ; ivbd = *(ckt->CKTirhsOld + here->MOS2bNode) - *(ckt->CKTirhsOld + here->MOS2dNodePrime) ; vds = vbs - vbd ; ivds = ivbs - ivbd ; vgs = vgb + vbs ; ivgs = ivgb + ivbs ; vgd = vgb + vbd ; ivgd = ivgb + ivbd ;#ifdef SENSDEBUG printf("senacload instance name %s\n",here->MOS2name); printf("gate = %d ,drain = %d, drainprm = %d\n", here->MOS2gNode,here->MOS2dNode,here->MOS2dNodePrime); printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n", here->MOS2sNode ,here->MOS2sNodePrime, here->MOS2bNode,here->MOS2senParmNo); printf("\n without perturbation \n");#endif /* SENSDEBUG */ /* without perturbation */ *(ckt->CKTstate0 + here->MOS2vbs) = vbsOp; *(ckt->CKTstate0 + here->MOS2vbd) = vbdOp; here->MOS2senPertFlag = ON ; if(info->SENacpertflag == 1){ /* store the unperturbed values of small signal parameters */ if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs) = here->MOS2cgs; *(here->MOS2senCgd) = here->MOS2cgd; *(here->MOS2senCgb) = here->MOS2cgb; *(here->MOS2senCbd) = here->MOS2capbd; *(here->MOS2senCbs) = here->MOS2capbs; *(here->MOS2senGds) = here->MOS2gds; *(here->MOS2senGbs) = here->MOS2gbs; *(here->MOS2senGbd) = here->MOS2gbd; *(here->MOS2senGm) = here->MOS2gm; *(here->MOS2senGmbs) = here->MOS2gmbs; } xcgs0= *(here->MOS2senCgs) * ckt->CKTomega; xcgd0= *(here->MOS2senCgd) * ckt->CKTomega; xcgb0= *(here->MOS2senCgb) * ckt->CKTomega; xbd0= *(here->MOS2senCbd) * ckt->CKTomega; xbs0= *(here->MOS2senCbs) * ckt->CKTomega; gds0= *(here->MOS2senGds); gbs0= *(here->MOS2senGbs); gbd0= *(here->MOS2senGbd); gm0= *(here->MOS2senGm); gmbs0= *(here->MOS2senGmbs); gdpr0 = here->MOS2drainConductance; gspr0 = here->MOS2sourceConductance; cspr = gspr0 * vspr ; icspr = gspr0 * ivspr ; cdpr = gdpr0 * vdpr ; icdpr = gdpr0 * ivdpr ; cgs = ( - xcgs0 * ivgs ); icgs = xcgs0 * vgs ; cgd = ( - xcgd0 * ivgd ); icgd = xcgd0 * vgd ; cgb = ( - xcgb0 * ivgb ); icgb = xcgb0 * vgb ; cbs = ( gbs0 * vbs - xbs0 * ivbs ); icbs = ( xbs0 * vbs + gbs0 * ivbs ); cbd = ( gbd0 * vbd - xbd0 * ivbd ); icbd = ( xbd0 * vbd + gbd0 * ivbd ); cds = ( gds0 * vds + xnrm * (gm0 * vgs + gmbs0 * vbs) - xrev * (gm0 * vgd + gmbs0 * vbd) ); icds = ( gds0 * ivds + xnrm * (gm0 * ivgs + gmbs0 * ivbs) - xrev * (gm0 * ivgd + gmbs0 * ivbd) ); cs0 = cspr; ics0 = icspr; csprm0 = ( -cspr - cgs - cbs - cds ) ; icsprm0 = ( -icspr - icgs - icbs - icds ) ; cd0 = cdpr; icd0 = icdpr; cdprm0 = ( -cdpr - cgd - cbd + cds ) ; icdprm0 = ( -icdpr - icgd - icbd + icds ) ; cg0 = cgs + cgd + cgb ; icg0 = icgs + icgd + icgb ; cb0 = cbs + cbd - cgb ; icb0 = icbs + icbd - icgb ;#ifdef SENSDEBUG printf("gspr0 = %.7e , gdpr0 = %.7e , gds0 = %.7e, gbs0 = %.7e\n", gspr0,gdpr0,gds0,gbs0); printf("gbd0 = %.7e , gm0 = %.7e , gmbs0 = %.7e\n",gbd0,gm0,gmbs0); printf("xcgs0 = %.7e , xcgd0 = %.7e , xcgb0 = %.7e,", xcgs0,xcgd0,xcgb0); printf("xbd0 = %.7e,xbs0 = %.7e\n", xbd0,xbs0); printf("vbs = %.7e , vbd = %.7e , vgb = %.7e\n",vbs,vbd,vgb); printf("ivbs = %.7e , ivbd = %.7e , ivgb = %.7e\n",ivbs,ivbd,ivgb); printf("cbs0 = %.7e , cbd0 = %.7e , cgb0 = %.7e\n",cbs,cbd,cgb); printf("cb0 = %.7e , cg0 = %.7e , cs0 = %.7e\n",cb0,cg0,cs0); printf("csprm0 = %.7e, cd0 = %.7e, cdprm0 = %.7e\n", csprm0,cd0,cdprm0); printf("icb0 = %.7e , icg0 = %.7e , ics0 = %.7e\n",icb0,icg0,ics0); printf("icsprm0 = %.7e, icd0 = %.7e, icdprm0 = %.7e\n", icsprm0,icd0,icdprm0); printf("\nPerturbation of vbs\n");#endif /* SENSDEBUG */ /* Perturbation of vbs */ flag = 1; A0 = vbsOp; DELA = info->SENpertfac * CONSTvt0 ; DELAinv = 1.0/DELA; if(info->SENacpertflag == 1){ /* store the values of small signal parameters * corresponding to perturbed vbs */ Apert = A0 + DELA; *(ckt->CKTstate0 + here->MOS2vbs) = Apert; *(ckt->CKTstate0 + here->MOS2vbd) = vbdOp; if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs + 1) = here->MOS2cgs; *(here->MOS2senCgd + 1) = here->MOS2cgd; *(here->MOS2senCgb + 1) = here->MOS2cgb; *(here->MOS2senCbd + 1) = here->MOS2capbd; *(here->MOS2senCbs + 1) = here->MOS2capbs; *(here->MOS2senGds + 1) = here->MOS2gds; *(here->MOS2senGbs + 1) = here->MOS2gbs; *(here->MOS2senGbd + 1) = here->MOS2gbd; *(here->MOS2senGm + 1) = here->MOS2gm; *(here->MOS2senGmbs + 1) = here->MOS2gmbs; *(ckt->CKTstate0 + here->MOS2vbs) = A0; } goto load;pertvbd: /* Perturbation of vbd */#ifdef SENSDEBUG printf("\nPerturbation of vbd\n");#endif /* SENSDEBUG */ flag = 2; A0 = vbdOp; DELA = info->SENpertfac * CONSTvt0 + 1e-8; DELAinv = 1.0/DELA; if(info->SENacpertflag == 1){ /* store the values of small signal parameters * corresponding to perturbed vbd */ Apert = A0 + DELA; *(ckt->CKTstate0 + here->MOS2vbs) = vbsOp; *(ckt->CKTstate0 + here->MOS2vbd) = Apert; if(error = MOS2load((GENmodel*)model,ckt)) return(error); *(here->MOS2senCgs + 2) = here->MOS2cgs; *(here->MOS2senCgd + 2) = here->MOS2cgd; *(here->MOS2senCgb + 2) = here->MOS2cgb; *(here->MOS2senCbd + 2) = here->MOS2capbd; *(here->MOS2senCbs + 2) = here->MOS2capbs; *(here->MOS2senGds + 2) = here->MOS2gds; *(here->MOS2senGbs + 2) = here->MOS2gbs; *(here->MOS2senGbd + 2) = here->MOS2gbd; *(here->MOS2senGm + 2) = here->MOS2gm; *(here->MOS2senGmbs + 2) = here->MOS2gmbs; *(ckt->CKTstate0 + here->MOS2vbd) = A0; } goto load;pertvgb: /* Perturbation of vgb */#ifdef SENSDEBUG printf("\nPerturbation of vgb\n");#endif /* SENSDEBUG */ flag = 3; A0 = model->MOS2type * (*(ckt->CKTrhsOp + here->MOS2gNode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -