📄 bjtsacl.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 "util.h"#include "cktdefs.h"#include "smpdefs.h"#include "bjtdefs.h"#include "const.h"#include "sperror.h"#include "ifsim.h"#include "suffix.h"intBJTsAcLoad(inModel,ckt)GENmodel *inModel;CKTcircuit *ckt;{ register BJTmodel *model = (BJTmodel*)inModel; register BJTinstance *here; double SaveState[25]; int error; int flag; double vbeOp; double vbcOp; double A0; double DELA; double Apert; double DELAinv; double vte; double gcpr; double gepr; double gpi; double gmu; double go; double xgm; double td; double arg; double gm; double gx; double xcpi; double xcmu; double xcbx; double xccs; double xcmcb; double cx,icx; double cbx,icbx; double ccs,iccs; double cbc,icbc; double cbe,icbe; double cce,icce; double cb,icb; double cbprm,icbprm; double cc,icc; double ccprm,iccprm; double ce,ice; double ceprm,iceprm; double cs,ics; double vcpr,ivcpr; double vepr,ivepr; double vx,ivx; double vbx,ivbx; double vcs,ivcs; double vbc,ivbc; double vbe,ivbe; double vce,ivce; double cb0,icb0; double cbprm0,icbprm0; double cc0,icc0; double ccprm0,iccprm0; double ce0,ice0; double ceprm0,iceprm0; double cs0,ics0; double DvDp; int iparmno,i; SENstruct *info;#ifdef SENSDEBUG printf("BJTsenacload \n"); printf("BJTsenacload \n");#endif /* SENSDEBUG */ info = ckt->CKTsenInfo; info->SENstatus = PERTURBATION; /* loop through all the models */ for( ; model != NULL; model = model->BJTnextModel ) { /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; here=here->BJTnextInstance) { /* save the unperturbed values in the state vector */ for(i=0; i <= 20; i++) { *(SaveState + i) = *(ckt->CKTstate0 + here->BJTstate + i); } vcpr = *(ckt->CKTrhsOld + here->BJTcolNode) - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ; ivcpr = *(ckt->CKTirhsOld + here->BJTcolNode) - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ; vepr = *(ckt->CKTrhsOld + here->BJTemitNode) - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ; ivepr = *(ckt->CKTirhsOld + here->BJTemitNode) - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ; vx = *(ckt->CKTrhsOld + here->BJTbaseNode) - *(ckt->CKTrhsOld + here->BJTbasePrimeNode) ;/* vb_bprm */ ivx = *(ckt->CKTirhsOld + here->BJTbaseNode) - *(ckt->CKTirhsOld + here->BJTbasePrimeNode) ;/* ivb_bprm */ vcs = *(ckt->CKTrhsOld + here->BJTcolPrimeNode) - *(ckt->CKTrhsOld + here->BJTsubstNode) ; ivcs = *(ckt->CKTirhsOld + here->BJTcolPrimeNode) - *(ckt->CKTirhsOld + here->BJTsubstNode) ; vbc = *(ckt->CKTrhsOld + here->BJTbasePrimeNode) - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ;/* vbprm_cprm */ ivbc = *(ckt->CKTirhsOld + here->BJTbasePrimeNode) - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ;/* ivbprm_cprm */ vbe = *(ckt->CKTrhsOld + here->BJTbasePrimeNode) - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ;/* vbprm_eprm */ ivbe = *(ckt->CKTirhsOld + here->BJTbasePrimeNode) - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ;/* ivbprm_eprm */ vce = vbe - vbc ; ivce = ivbe - ivbc ; vbx = vx + vbc ; ivbx = ivx + ivbc ; vbeOp =model->BJTtype * ( *(ckt->CKTrhsOp + here->BJTbasePrimeNode) - *(ckt->CKTrhsOp + here->BJTemitPrimeNode)); vbcOp =model->BJTtype * ( *(ckt->CKTrhsOp + here->BJTbasePrimeNode) - *(ckt->CKTrhsOp + here->BJTcolPrimeNode));#ifdef SENSDEBUG printf("\n without perturbation\n");#endif /* SENSDEBUG */ /* without perturbation */ A0 = here->BJTarea; here->BJTsenPertFlag = ON; *(ckt->CKTstate0 + here->BJTvbe) = vbeOp; *(ckt->CKTstate0 + here->BJTvbc) = vbcOp; /* info->SENacpertflag == 1 only for first frequency */ if(info->SENacpertflag == 1){ /* store the unperturbed values of small signal parameters */ if(error = BJTload((GENmodel*)model,ckt)) return(error); *(here->BJTsenGpi)= *(ckt->CKTstate0 + here->BJTgpi); *(here->BJTsenGmu)= *(ckt->CKTstate0 + here->BJTgmu); *(here->BJTsenGm)= *(ckt->CKTstate0 + here->BJTgm); *(here->BJTsenGo)= *(ckt->CKTstate0 + here->BJTgo); *(here->BJTsenGx)= *(ckt->CKTstate0 + here->BJTgx); *(here->BJTsenCpi)= *(ckt->CKTstate0 + here->BJTcqbe); *(here->BJTsenCmu)= *(ckt->CKTstate0 + here->BJTcqbc); *(here->BJTsenCbx)= *(ckt->CKTstate0 + here->BJTcqbx); *(here->BJTsenCcs)= *(ckt->CKTstate0 + here->BJTcqcs); *(here->BJTsenCmcb)= *(ckt->CKTstate0 + here->BJTcexbc); } gcpr = model->BJTcollectorConduct * A0; gepr = model->BJTemitterConduct * A0; gpi= *(here->BJTsenGpi); gmu= *(here->BJTsenGmu); gm= *(here->BJTsenGm); go= *(here->BJTsenGo); gx= *(here->BJTsenGx); xgm=0; td=model->BJTexcessPhase; if(td != 0) { arg = td*ckt->CKTomega; gm = gm+go; xgm = -gm * sin(arg); gm = gm * cos(arg)-go; } xcpi= *(here->BJTsenCpi) * ckt->CKTomega; xcmu= *(here->BJTsenCmu) * ckt->CKTomega; xcbx= *(here->BJTsenCbx) * ckt->CKTomega; xccs= *(here->BJTsenCcs) * ckt->CKTomega; xcmcb= *(here->BJTsenCmcb) * ckt->CKTomega; cx=gx * vx ; icx=gx * ivx; cbx=( -xcbx * ivbx) ; icbx= xcbx * vbx ; ccs=( -xccs * ivcs) ; iccs= xccs * vcs ; cbc=(gmu * vbc -xcmu * ivbc) ; icbc=xcmu * vbc + gmu * ivbc ; cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; cce= go * vce + gm * vbe - xgm * ivbe; icce=go * ivce + gm * ivbe + xgm * vbe ; cc0=gcpr * vcpr ; icc0=gcpr * ivcpr ; ce0=gepr * vepr; ice0=gepr * ivepr ; cb0 = cx + cbx; icb0 = icx + icbx; if(here->BJTbaseNode != here->BJTbasePrimeNode){ cbprm0 = (- cx + cbe + cbc); icbprm0 = (- icx + icbe + icbc); } else{ cbprm0 = ( cbx + cbe + cbc); icbprm0 = (icbx + icbe + icbc); } ccprm0 = (- cbx - cc0 + ccs + cce - cbc); iccprm0 = (- icbx - icc0 + iccs + icce - icbc); ceprm0 = (- cbe - cce - ce0); iceprm0 = (- icbe - icce - ice0); cs0 = (- ccs) ; ics0 = (- iccs) ;#ifdef SENSDEBUG printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n", gepr,gcpr,gmu,gpi); printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n", gm,go,gx,xcpi); printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n" ,xcmu,xcbx,xccs,xcmcb); printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n", vepr,ivepr,vcpr,ivcpr); printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n", vbx,ivbx,vx,ivx); printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n", vbc,ivbc,vbe,ivbe); printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n", vce,ivce,vcs,ivcs); printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n", cce,icce,cbe,icbe); printf("cbc0 = %.7e + j%.7e\n", cbc,icbc); printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n", cc0,icc0,ce0,ice0); printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n", cb0,icb0,cs0,ics0); printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n", cbprm0,icbprm0,ceprm0,iceprm0); printf("ccprm0 = %.7e + j%.7e \n", ccprm0,iccprm0); printf("\nPerturbation of Area\n");#endif /* SENSDEBUG */ /* Perturbation of Area */ if(here->BJTsenParmNo == 0){ flag = 0; goto next1; } DELA = info->SENpertfac * A0; Apert = A0 + DELA; DELAinv = 1.0/DELA; here->BJTarea = Apert; *(ckt->CKTstate0 + here->BJTvbe) = vbeOp; *(ckt->CKTstate0 + here->BJTvbc) = vbcOp; if(info->SENacpertflag == 1){ /* store the small signal parameters * corresponding to perturbed area */ if(error = BJTload((GENmodel*)model,ckt)) return(error); *(here->BJTsenGpi + 1)= *(ckt->CKTstate0 + here->BJTgpi); *(here->BJTsenGmu + 1)= *(ckt->CKTstate0 + here->BJTgmu); *(here->BJTsenGm + 1)= *(ckt->CKTstate0 + here->BJTgm); *(here->BJTsenGo + 1)= *(ckt->CKTstate0 + here->BJTgo); *(here->BJTsenGx + 1)= *(ckt->CKTstate0 + here->BJTgx); *(here->BJTsenCpi + 1)= *(ckt->CKTstate0 + here->BJTcqbe); *(here->BJTsenCmu + 1)= *(ckt->CKTstate0 + here->BJTcqbc); *(here->BJTsenCbx + 1)= *(ckt->CKTstate0 + here->BJTcqbx); *(here->BJTsenCcs + 1)= *(ckt->CKTstate0 + here->BJTcqcs); *(here->BJTsenCmcb + 1)= *(ckt->CKTstate0 + here->BJTcexbc); } flag = 0; goto load;pertvbx: /* Perturbation of vbx */#ifdef SENSDEBUG printf("\nPerturbation of vbx\n");#endif /* SENSDEBUG */ here->BJTarea = A0; A0 = model->BJTtype * (*(ckt->CKTrhsOp + here->BJTbaseNode) - *(ckt->CKTrhsOp + here->BJTcolPrimeNode)); DELA = info->SENpertfac * A0 + 1e-8; Apert = A0 + DELA; DELAinv = model->BJTtype * 1.0/DELA; *(ckt->CKTrhsOp + here->BJTbaseNode) += DELA; *(ckt->CKTstate0 + here->BJTvbe) = vbeOp; *(ckt->CKTstate0 + here->BJTvbc) = vbcOp; if(info->SENacpertflag == 1){ /* store the small signal parameters * corresponding to perturbed vbx */ if(error = BJTload((GENmodel*)model,ckt)) return(error); *(here->BJTsenGpi + 2)= *(ckt->CKTstate0 + here->BJTgpi); *(here->BJTsenGmu + 2)= *(ckt->CKTstate0 + here->BJTgmu); *(here->BJTsenGm + 2)= *(ckt->CKTstate0 + here->BJTgm); *(here->BJTsenGo + 2)= *(ckt->CKTstate0 + here->BJTgo); *(here->BJTsenGx + 2)= *(ckt->CKTstate0 + here->BJTgx); *(here->BJTsenCpi + 2)= *(ckt->CKTstate0 + here->BJTcqbe); *(here->BJTsenCmu + 2)= *(ckt->CKTstate0 + here->BJTcqbc); *(here->BJTsenCbx + 2)= *(ckt->CKTstate0 + here->BJTcqbx); *(here->BJTsenCcs + 2)= *(ckt->CKTstate0 + here->BJTcqcs); *(here->BJTsenCmcb + 2)= *(ckt->CKTstate0 + here->BJTcexbc); } flag = 1; goto load;pertvbe: /* Perturbation of vbe */#ifdef SENSDEBUG printf("\nPerturbation of vbe\n");#endif /* SENSDEBUG */ if (*(here->BJTsenCbx) != 0){ *(ckt->CKTrhsOp + here ->BJTbaseNode) -= DELA; } vte=model->BJTleakBEemissionCoeff*CONSTvt0; A0 = vbeOp; DELA = info->SENpertfac * vte ; Apert = A0 + DELA; DELAinv = 1.0/DELA; *(ckt->CKTstate0 + here->BJTvbe) = Apert; *(ckt->CKTstate0 + here->BJTvbc) = vbcOp; if(info->SENacpertflag == 1){ /* store the small signal parameters * corresponding to perturbed vbe */ if(error = BJTload((GENmodel*)model,ckt)) return(error); *(here->BJTsenGpi + 3)= *(ckt->CKTstate0 + here->BJTgpi); *(here->BJTsenGmu + 3)= *(ckt->CKTstate0 + here->BJTgmu); *(here->BJTsenGm + 3)= *(ckt->CKTstate0 + here->BJTgm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -