⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bjtload.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                    gben=0;                } else {                    evben=exp(vbe/vte);                    cben=c2*(evben-1);                    gben=c2*evben/vte;                }            } else {                gbe = -csat/vbe+ckt->CKTgmin;                cbe=gbe*vbe;                gben = -c2/vbe;                cben=gben*vbe;            }            vtn=vt*model->BJTemissionCoeffR;            if(vbc > -5*vtn) {                evbc=exp(vbc/vtn);                cbc=csat*(evbc-1)+ckt->CKTgmin*vbc;                gbc=csat*evbc/vtn+ckt->CKTgmin;                if (c4 == 0) {                    cbcn=0;                    gbcn=0;                } else {                    evbcn=exp(vbc/vtc);                    cbcn=c4*(evbcn-1);                    gbcn=c4*evbcn/vtc;                }            } else {                gbc = -csat/vbc+ckt->CKTgmin;                cbc = gbc*vbc;                gbcn = -c4/vbc;                cbcn=gbcn*vbc;            }            /*             *   determine base charge terms             */            q1=1/(1-model->BJTinvEarlyVoltF*vbc-model->BJTinvEarlyVoltR*vbe);            if(oik == 0 && oikr == 0) {                qb=q1;                dqbdve=q1*qb*model->BJTinvEarlyVoltR;                dqbdvc=q1*qb*model->BJTinvEarlyVoltF;            } else {                q2=oik*cbe+oikr*cbc;                arg=MAX(0,1+4*q2);                sqarg=1;                if(arg != 0) sqarg=sqrt(arg);                qb=q1*(1+sqarg)/2;                dqbdve=q1*(qb*model->BJTinvEarlyVoltR+oik*gbe/sqarg);                dqbdvc=q1*(qb*model->BJTinvEarlyVoltF+oikr*gbc/sqarg);            }            /*             *   weil's approx. for excess phase applied with backward-             *   euler integration             */            cc=0;            cex=cbe;            gex=gbe;            if(ckt->CKTmode & (MODETRAN | MODEAC) && td != 0) {                arg1=ckt->CKTdelta/td;                arg2=3*arg1;                arg1=arg2*arg1;                denom=1+arg1+arg2;                arg3=arg1/denom;                if(ckt->CKTmode & MODEINITTRAN) {                    *(ckt->CKTstate1 + here->BJTcexbc)=cbe/qb;                    *(ckt->CKTstate2 + here->BJTcexbc)=                            *(ckt->CKTstate1 + here->BJTcexbc);                }                cc=(*(ckt->CKTstate1 + here->BJTcexbc)*(1+ckt->CKTdelta/                        ckt->CKTdeltaOld[1]+arg2)-                        *(ckt->CKTstate2 + here->BJTcexbc)*ckt->CKTdelta/                        ckt->CKTdeltaOld[1])/denom;                cex=cbe*arg3;                gex=gbe*arg3;                *(ckt->CKTstate0 + here->BJTcexbc)=cc+cex/qb;            }            /*             *   determine dc incremental conductances             */            cc=cc+(cex-cbc)/qb-cbc/here->BJTtBetaR-cbcn;            cb=cbe/here->BJTtBetaF+cben+cbc/here->BJTtBetaR+cbcn;            gx=rbpr+rbpi/qb;            if(xjrb != 0) {                arg1=MAX(cb/xjrb,1e-9);                arg2=(-1+sqrt(1+14.59025*arg1))/2.4317/sqrt(arg1);                arg1=tan(arg2);                gx=rbpr+3*rbpi*(arg1-arg2)/arg2/arg1/arg1;            }            if(gx != 0) gx=1/gx;            gpi=gbe/here->BJTtBetaF+gben;            gmu=gbc/here->BJTtBetaR+gbcn;            go=(gbc+(cex-cbc)*dqbdvc/qb)/qb;            gm=(gex-(cex-cbc)*dqbdve/qb)/qb-go;            if( (ckt->CKTmode & (MODETRAN | MODEAC)) ||                    ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ||                    (ckt->CKTmode & MODEINITSMSIG)) {                /*                 *   charge storage elements                 */                tf=model->BJTtransitTimeF;                tr=model->BJTtransitTimeR;                czbe=here->BJTtBEcap*here->BJTarea;                pe=here->BJTtBEpot;                xme=model->BJTjunctionExpBE;                cdis=model->BJTbaseFractionBCcap;                ctot=here->BJTtBCcap*here->BJTarea;                czbc=ctot*cdis;                czbx=ctot-czbc;                pc=here->BJTtBCpot;                xmc=model->BJTjunctionExpBC;                fcpe=here->BJTtDepCap;                czcs=model->BJTcapCS*here->BJTarea;                ps=model->BJTpotentialSubstrate;                xms=model->BJTexponentialSubstrate;                xtf=model->BJTtransitTimeBiasCoeffF;                ovtf=model->BJTtransitTimeVBCFactor;                xjtf=model->BJTtransitTimeHighCurrentF*here->BJTarea;                if(tf != 0 && vbe >0) {                    argtf=0;                    arg2=0;                    arg3=0;                    if(xtf != 0){                        argtf=xtf;                        if(ovtf != 0) {                            argtf=argtf*exp(vbc*ovtf);                        }                        arg2=argtf;                        if(xjtf != 0) {                            temp=cbe/(cbe+xjtf);                            argtf=argtf*temp*temp;                            arg2=argtf*(3-temp-temp);                        }                        arg3=cbe*argtf*ovtf;                    }                    cbe=cbe*(1+argtf)/qb;                    gbe=(gbe*(1+arg2)-cbe*dqbdve)/qb;                    geqcb=tf*(arg3-cbe*dqbdvc)/qb;                }                if (vbe < fcpe) {                    arg=1-vbe/pe;                    sarg=exp(-xme*log(arg));                    *(ckt->CKTstate0 + here->BJTqbe)=tf*cbe+pe*czbe*                            (1-arg*sarg)/(1-xme);                    capbe=tf*gbe+czbe*sarg;                } else {                    f1=here->BJTtf1;                    f2=model->BJTf2;                    f3=model->BJTf3;                    czbef2=czbe/f2;                    *(ckt->CKTstate0 + here->BJTqbe) = tf*cbe+czbe*f1+czbef2*                            (f3*(vbe-fcpe) +(xme/(pe+pe))*(vbe*vbe-fcpe*fcpe));                    capbe=tf*gbe+czbef2*(f3+xme*vbe/pe);                }                fcpc=here->BJTtf4;                f1=here->BJTtf5;                f2=model->BJTf6;                f3=model->BJTf7;                if (vbc < fcpc) {                    arg=1-vbc/pc;                    sarg=exp(-xmc*log(arg));                    *(ckt->CKTstate0 + here->BJTqbc) = tr*cbc+pc*czbc*(                            1-arg*sarg)/(1-xmc);                    capbc=tr*gbc+czbc*sarg;                } else {                    czbcf2=czbc/f2;                    *(ckt->CKTstate0 + here->BJTqbc) = tr*cbc+czbc*f1+czbcf2*                            (f3*(vbc-fcpc) +(xmc/(pc+pc))*(vbc*vbc-fcpc*fcpc));                    capbc=tr*gbc+czbcf2*(f3+xmc*vbc/pc);                }                if(vbx < fcpc) {                    arg=1-vbx/pc;                    sarg=exp(-xmc*log(arg));                    *(ckt->CKTstate0 + here->BJTqbx)=                         pc*czbx* (1-arg*sarg)/(1-xmc);                    capbx=czbx*sarg;                } else {                    czbxf2=czbx/f2;                    *(ckt->CKTstate0 + here->BJTqbx)=czbx*f1+czbxf2*                            (f3*(vbx-fcpc)+(xmc/(pc+pc))*(vbx*vbx-fcpc*fcpc));                    capbx=czbxf2*(f3+xmc*vbx/pc);                }                if(vcs < 0){                    arg=1-vcs/ps;                    sarg=exp(-xms*log(arg));                    *(ckt->CKTstate0 + here->BJTqcs) = ps*czcs*(1-arg*sarg)/                            (1-xms);                    capcs=czcs*sarg;                } else {                    *(ckt->CKTstate0 + here->BJTqcs) = vcs*czcs*(1+xms*vcs/                            (2*ps));                    capcs=czcs*(1+xms*vcs/ps);		}		here->BJTcapbe = capbe;		here->BJTcapbc = capbc;		here->BJTcapcs = capcs;		here->BJTcapbx = capbx;                /*                 *   store small-signal parameters                 */                if ( (!(ckt->CKTmode & MODETRANOP))||                        (!(ckt->CKTmode & MODEUIC)) ) {                    if(ckt->CKTmode & MODEINITSMSIG) {                        *(ckt->CKTstate0 + here->BJTcqbe) = capbe;                        *(ckt->CKTstate0 + here->BJTcqbc) = capbc;                        *(ckt->CKTstate0 + here->BJTcqcs) = capcs;                        *(ckt->CKTstate0 + here->BJTcqbx) = capbx;                        *(ckt->CKTstate0 + here->BJTcexbc) = geqcb;                        if(SenCond){                            *(ckt->CKTstate0 + here->BJTcc) = cc;                            *(ckt->CKTstate0 + here->BJTcb) = cb;                            *(ckt->CKTstate0 + here->BJTgpi) = gpi;                            *(ckt->CKTstate0 + here->BJTgmu) = gmu;                            *(ckt->CKTstate0 + here->BJTgm) = gm;                            *(ckt->CKTstate0 + here->BJTgo) = go;                            *(ckt->CKTstate0 + here->BJTgx) = gx;                            *(ckt->CKTstate0 + here->BJTgccs) = gccs;                            *(ckt->CKTstate0 + here->BJTgeqbx) = geqbx;                        }#ifdef SENSDEBUG                        printf("storing small signal parameters for op\n");                        printf("capbe = %.7e ,capbc = %.7e\n",capbe,capbc);                        printf("capcs = %.7e ,capbx = %.7e\n",capcs,capbx);                        printf("geqcb = %.7e ,gpi = %.7e\n",geqcb,gpi);                        printf("gmu = %.7e ,gm = %.7e\n",gmu,gm);                        printf("go = %.7e ,gx = %.7e\n",go,gx);                        printf("gccs = %.7e ,geqbx = %.7e\n",gccs,geqbx);                        printf("cc = %.7e ,cb = %.7e\n",cc,cb);#endif /* SENSDEBUG */                        continue; /* go to 1000 */                    }                    /*                     *   transient analysis                     */                    if(SenCond && ckt->CKTsenInfo->SENmode == TRANSEN){                        *(ckt->CKTstate0 + here->BJTcc) = cc;                        *(ckt->CKTstate0 + here->BJTcb) = cb;                        *(ckt->CKTstate0 + here->BJTgx) = gx;                        continue;                    }                    if(ckt->CKTmode & MODEINITTRAN) {                        *(ckt->CKTstate1 + here->BJTqbe) =                                *(ckt->CKTstate0 + here->BJTqbe) ;                        *(ckt->CKTstate1 + here->BJTqbc) =                                *(ckt->CKTstate0 + here->BJTqbc) ;                        *(ckt->CKTstate1 + here->BJTqbx) =                                *(ckt->CKTstate0 + here->BJTqbx) ;                        *(ckt->CKTstate1 + here->BJTqcs) =                                *(ckt->CKTstate0 + here->BJTqcs) ;                    }                    error = NIintegrate(ckt,&geq,&ceq,capbe,here->BJTqbe);                    if(error) return(error);                    geqcb=geqcb*ckt->CKTag[0];                    gpi=gpi+geq;                    cb=cb+*(ckt->CKTstate0 + here->BJTcqbe);                    error = NIintegrate(ckt,&geq,&ceq,capbc,here->BJTqbc);                    if(error) return(error);                    gmu=gmu+geq;                    cb=cb+*(ckt->CKTstate0 + here->BJTcqbc);                    cc=cc-*(ckt->CKTstate0 + here->BJTcqbc);                    if(ckt->CKTmode & MODEINITTRAN) {                        *(ckt->CKTstate1 + here->BJTcqbe) =                                *(ckt->CKTstate0 + here->BJTcqbe);                        *(ckt->CKTstate1 + here->BJTcqbc) =                                *(ckt->CKTstate0 + here->BJTcqbc);                    }                }            }            if(SenCond) goto next2;            /*             *   check convergence             */            if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->BJToff))) {                if (icheck == 1) {                    ckt->CKTnoncon++;		    ckt->CKTtroubleElt = (GENinstance *) here;#ifndef NEWCONV                } else {                    tol=ckt->CKTreltol*MAX(FABS(cchat),FABS(cc))+ckt->CKTabstol;                    if (FABS(cchat-cc) > tol) {                        ckt->CKTnoncon++;			ckt->CKTtroubleElt = (GENinstance *) here;                    } else {                        tol=ckt->CKTreltol*MAX(FABS(cbhat),FABS(cb))+                            ckt->CKTabstol;                        if (FABS(cbhat-cb) > tol) {                            ckt->CKTnoncon++;			    ckt->CKTtroubleElt = (GENinstance *) here;                        }                    }#endif /* NEWCONV */                }            }            /*             *      charge storage for c-s and b-x junctions             */            if(ckt->CKTmode & (MODETRAN | MODEAC)) {                error = NIintegrate(ckt,&gccs,&ceq,capcs,here->BJTqcs);                if(error) return(error);                error = NIintegrate(ckt,&geqbx,&ceq,capbx,here->BJTqbx);                if(error) return(error);                if(ckt->CKTmode & MODEINITTRAN) {                    *(ckt->CKTstate1 + here->BJTcqbx) =                            *(ckt->CKTstate0 + here->BJTcqbx);                    *(ckt->CKTstate1 + here->BJTcqcs) =                            *(ckt->CKTstate0 + here->BJTcqcs);                }            }next2:            *(ckt->CKTstate0 + here->BJTvbe) = vbe;            *(ckt->CKTstate0 + here->BJTvbc) = vbc;            *(ckt->CKTstate0 + here->BJTcc) = cc;            *(ckt->CKTstate0 + here->BJTcb) = cb;            *(ckt->CKTstate0 + here->BJTgpi) = gpi;            *(ckt->CKTstate0 + here->BJTgmu) = gmu;            *(ckt->CKTstate0 + here->BJTgm) = gm;            *(ckt->CKTstate0 + here->BJTgo) = go;            *(ckt->CKTstate0 + here->BJTgx) = gx;            *(ckt->CKTstate0 + here->BJTgeqcb) = geqcb;            *(ckt->CKTstate0 + here->BJTgccs) = gccs;            *(ckt->CKTstate0 + here->BJTgeqbx) = geqbx;            /* Do not load the Jacobian and the rhs if               perturbation is being carried out */            if(SenCond)continue;load:            /*             *  load current excitation vector             */            ceqcs=model->BJTtype * (*(ckt->CKTstate0 + here->BJTcqcs) -                     vcs * gccs);            ceqbx=model->BJTtype * (*(ckt->CKTstate0 + here->BJTcqbx) -                    vbx * geqbx);            ceqbe=model->BJTtype * (cc + cb - vbe * (gm + go + gpi) + vbc *                     (go - geqcb));            ceqbc=model->BJTtype * (-cc + vbe * (gm + go) - vbc * (gmu + go));            *(ckt->CKTrhs + here->BJTbaseNode) += (-ceqbx);            *(ckt->CKTrhs + here->BJTcolPrimeNode) +=                     (ceqcs+ceqbx+ceqbc);            *(ckt->CKTrhs + here->BJTbasePrimeNode) +=                     (-ceqbe-ceqbc);            *(ckt->CKTrhs + here->BJTemitPrimeNode) += (ceqbe);            *(ckt->CKTrhs + here->BJTsubstNode) += (-ceqcs);            /*             *  load y matrix             */            *(here->BJTcolColPtr) += (gcpr);            *(here->BJTbaseBasePtr) += (gx+geqbx);            *(here->BJTemitEmitPtr) += (gepr);            *(here->BJTcolPrimeColPrimePtr) += (gmu+go+gcpr+gccs+geqbx);            *(here->BJTbasePrimeBasePrimePtr) += (gx +gpi+gmu+geqcb);            *(here->BJTemitPrimeEmitPrimePtr) += (gpi+gepr+gm+go);            *(here->BJTcolColPrimePtr) += (-gcpr);            *(here->BJTbaseBasePrimePtr) += (-gx);            *(here->BJTemitEmitPrimePtr) += (-gepr);            *(here->BJTcolPrimeColPtr) += (-gcpr);            *(here->BJTcolPrimeBasePrimePtr) += (-gmu+gm);            *(here->BJTcolPrimeEmitPrimePtr) += (-gm-go);            *(here->BJTbasePrimeBasePtr) += (-gx);            *(here->BJTbasePrimeColPrimePtr) += (-gmu-geqcb);            *(here->BJTbasePrimeEmitPrimePtr) += (-gpi);            *(here->BJTemitPrimeEmitPtr) += (-gepr);            *(here->BJTemitPrimeColPrimePtr) += (-go+geqcb);            *(here->BJTemitPrimeBasePrimePtr) += (-gpi-gm-geqcb);            *(here->BJTsubstSubstPtr) += (gccs);            *(here->BJTcolPrimeSubstPtr) += (-gccs);            *(here->BJTsubstColPrimePtr) += (-gccs);            *(here->BJTbaseColPrimePtr) += (-geqbx);            *(here->BJTcolPrimeBasePtr) += (-geqbx);        }    }    return(OK);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -