📄 bjtload.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Thomas L. Quarles**********//* * This is the function called each iteration to evaluate the * BJTs in the circuit and load them into the matrix as appropriate */#include "spice.h"#include <stdio.h>#include "util.h"#include "cktdefs.h"#include "bjtdefs.h"#include "const.h"#include "trandefs.h"#include "sperror.h"#include "devdefs.h"#include "suffix.h"intBJTload(inModel,ckt) GENmodel *inModel; register CKTcircuit *ckt; /* actually load the current resistance value into the * sparse matrix previously provided */{ register BJTmodel *model = (BJTmodel*)inModel; register BJTinstance *here; double arg1; double arg2; double arg3; double arg; double argtf; double c2; double c4; double capbc; double capbe; double capbx=0; double capcs=0; double cb; double cbc; double cbcn; double cbe; double cben; double cbhat; double cc; double cchat; double cdis; double ceq; double ceqbc; double ceqbe; double ceqbx; double ceqcs; double cex; double csat; double ctot; double czbc; double czbcf2; double czbe; double czbef2; double czbx; double czbxf2; double czcs; double delvbc; double delvbe; double denom; double dqbdvc; double dqbdve; double evbc; double evbcn; double evbe; double evben; double f1; double f2; double f3; double fcpc; double fcpe; double gbc; double gbcn; double gbe; double gben; double gccs; double gcpr; double gepr; double geq; double geqbx; double geqcb; double gex; double gm; double gmu; double go; double gpi; double gx; double oik; double oikr; double ovtf; double pc; double pe; double ps; double q1; double q2; double qb; double rbpi; double rbpr; double sarg; double sqarg; double td; double temp; double tf; double tol; double tr; double vbc; double vbe; double vbx; double vce; double vcs; double vt; double vtc; double vte; double vtn; double xfact; double xjrb; double xjtf; double xmc; double xme; double xms; double xtf; int icheck; int ichk1; int error; int SenCond=0; /* 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) { if (here->BJTowner != ARCHme) continue; vt = here->BJTtemp * CONSTKoverQ; if(ckt->CKTsenInfo){#ifdef SENSDEBUG printf("BJTload \n");#endif /* SENSDEBUG */ if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& (here->BJTsenPertFlag == OFF)) continue; SenCond = here->BJTsenPertFlag; } gccs=0; ceqcs=0; geqbx=0; ceqbx=0; geqcb=0; /* * dc model paramters */ csat=here->BJTtSatCur*here->BJTarea; rbpr=model->BJTminBaseResist/here->BJTarea; rbpi=model->BJTbaseResist/here->BJTarea-rbpr; gcpr=model->BJTcollectorConduct*here->BJTarea; gepr=model->BJTemitterConduct*here->BJTarea; oik=model->BJTinvRollOffF/here->BJTarea; c2=here->BJTtBEleakCur*here->BJTarea; vte=model->BJTleakBEemissionCoeff*vt; oikr=model->BJTinvRollOffR/here->BJTarea; c4=here->BJTtBCleakCur*here->BJTarea; vtc=model->BJTleakBCemissionCoeff*vt; td=model->BJTexcessPhaseFactor; xjrb=model->BJTbaseCurrentHalfResist*here->BJTarea; if(SenCond){#ifdef SENSDEBUG printf("BJTsenPertFlag = ON \n");#endif /* SENSDEBUG */ if((ckt->CKTsenInfo->SENmode == TRANSEN)&& (ckt->CKTmode & MODEINITTRAN)) { vbe = *(ckt->CKTstate1 + here->BJTvbe); vbc = *(ckt->CKTstate1 + here->BJTvbc); vbx=model->BJTtype*( *(ckt->CKTrhsOp+here->BJTbaseNode)- *(ckt->CKTrhsOp+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOp+here->BJTsubstNode)- *(ckt->CKTrhsOp+here->BJTcolPrimeNode)); } else{ vbe = *(ckt->CKTstate0 + here->BJTvbe); vbc = *(ckt->CKTstate0 + here->BJTvbc); if((ckt->CKTsenInfo->SENmode == DCSEN)|| (ckt->CKTsenInfo->SENmode == TRANSEN)){ vbx=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbaseNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTsubstNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); } if(ckt->CKTsenInfo->SENmode == ACSEN){ vbx=model->BJTtype*( *(ckt->CKTrhsOp+here->BJTbaseNode)- *(ckt->CKTrhsOp+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOp+here->BJTsubstNode)- *(ckt->CKTrhsOp+here->BJTcolPrimeNode)); } } goto next1; } /* * initialization */ icheck=1; if(ckt->CKTmode & MODEINITSMSIG) { vbe= *(ckt->CKTstate0 + here->BJTvbe); vbc= *(ckt->CKTstate0 + here->BJTvbc); vbx=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbaseNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTsubstNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); } else if(ckt->CKTmode & MODEINITTRAN) { vbe = *(ckt->CKTstate1 + here->BJTvbe); vbc = *(ckt->CKTstate1 + here->BJTvbc); vbx=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbaseNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTsubstNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { vbx=model->BJTtype*(here->BJTicVBE-here->BJTicVCE); vcs=0; } } else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ vbe=model->BJTtype*here->BJTicVBE; vce=model->BJTtype*here->BJTicVCE; vbc=vbe-vce; vbx=vbc; vcs=0; } else if((ckt->CKTmode & MODEINITJCT) && (here->BJToff==0)) { vbe=here->BJTtVcrit; vbc=0; /* ERROR: need to initialize VCS, VBX here */ vcs=vbx=0; } else if((ckt->CKTmode & MODEINITJCT) || ( (ckt->CKTmode & MODEINITFIX) && (here->BJToff!=0))) { vbe=0; vbc=0; /* ERROR: need to initialize VCS, VBX here */ vcs=vbx=0; } else {#ifndef PREDICTOR if(ckt->CKTmode & MODEINITPRED) { xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->BJTvbe) = *(ckt->CKTstate1 + here->BJTvbe); vbe = (1+xfact)**(ckt->CKTstate1 + here->BJTvbe)- xfact* *(ckt->CKTstate2 + here->BJTvbe); *(ckt->CKTstate0 + here->BJTvbc) = *(ckt->CKTstate1 + here->BJTvbc); vbc = (1+xfact)**(ckt->CKTstate1 + here->BJTvbc)- xfact* *(ckt->CKTstate2 + here->BJTvbc); *(ckt->CKTstate0 + here->BJTcc) = *(ckt->CKTstate1 + here->BJTcc); *(ckt->CKTstate0 + here->BJTcb) = *(ckt->CKTstate1 + here->BJTcb); *(ckt->CKTstate0 + here->BJTgpi) = *(ckt->CKTstate1 + here->BJTgpi); *(ckt->CKTstate0 + here->BJTgmu) = *(ckt->CKTstate1 + here->BJTgmu); *(ckt->CKTstate0 + here->BJTgm) = *(ckt->CKTstate1 + here->BJTgm); *(ckt->CKTstate0 + here->BJTgo) = *(ckt->CKTstate1 + here->BJTgo); *(ckt->CKTstate0 + here->BJTgx) = *(ckt->CKTstate1 + here->BJTgx); } else {#endif /* PREDICTOR */ /* * compute new nonlinear branch voltages */ vbe=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbasePrimeNode)- *(ckt->CKTrhsOld+here->BJTemitPrimeNode)); vbc=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbasePrimeNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode));#ifndef PREDICTOR }#endif /* PREDICTOR */ delvbe=vbe- *(ckt->CKTstate0 + here->BJTvbe); delvbc=vbc- *(ckt->CKTstate0 + here->BJTvbc); vbx=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTbaseNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); vcs=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTsubstNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); cchat= *(ckt->CKTstate0 + here->BJTcc)+(*(ckt->CKTstate0 + here->BJTgm)+ *(ckt->CKTstate0 + here->BJTgo))*delvbe- (*(ckt->CKTstate0 + here->BJTgo)+*(ckt->CKTstate0 + here->BJTgmu))*delvbc; cbhat= *(ckt->CKTstate0 + here->BJTcb)+ *(ckt->CKTstate0 + here->BJTgpi)*delvbe+ *(ckt->CKTstate0 + here->BJTgmu)* delvbc;#ifndef NOBYPASS /* * bypass if solution has not changed */ /* the following collections of if's would be just one * if the average compiler could handle it, but many * find the expression too complicated, thus the split. */ if( (ckt->CKTbypass) && (!(ckt->CKTmode & MODEINITPRED)) && (FABS(delvbe) < (ckt->CKTreltol*MAX(FABS(vbe), FABS(*(ckt->CKTstate0 + here->BJTvbe)))+ ckt->CKTvoltTol)) ) if( (FABS(delvbc) < ckt->CKTreltol*MAX(FABS(vbc), FABS(*(ckt->CKTstate0 + here->BJTvbc)))+ ckt->CKTvoltTol) ) if( (FABS(cchat-*(ckt->CKTstate0 + here->BJTcc)) < ckt->CKTreltol* MAX(FABS(cchat), FABS(*(ckt->CKTstate0 + here->BJTcc)))+ ckt->CKTabstol) ) if( (FABS(cbhat-*(ckt->CKTstate0 + here->BJTcb)) < ckt->CKTreltol* MAX(FABS(cbhat), FABS(*(ckt->CKTstate0 + here->BJTcb)))+ ckt->CKTabstol) ) { /* * bypassing.... */ vbe = *(ckt->CKTstate0 + here->BJTvbe); vbc = *(ckt->CKTstate0 + here->BJTvbc); cc = *(ckt->CKTstate0 + here->BJTcc); cb = *(ckt->CKTstate0 + here->BJTcb); gpi = *(ckt->CKTstate0 + here->BJTgpi); gmu = *(ckt->CKTstate0 + here->BJTgmu); gm = *(ckt->CKTstate0 + here->BJTgm); go = *(ckt->CKTstate0 + here->BJTgo); gx = *(ckt->CKTstate0 + here->BJTgx); geqcb = *(ckt->CKTstate0 + here->BJTgeqcb); gccs = *(ckt->CKTstate0 + here->BJTgccs); geqbx = *(ckt->CKTstate0 + here->BJTgeqbx); goto load; }#endif /*NOBYPASS*/ /* * limit nonlinear branch voltages */ ichk1=1; vbe = DEVpnjlim(vbe,*(ckt->CKTstate0 + here->BJTvbe),vt, here->BJTtVcrit,&icheck); vbc = DEVpnjlim(vbc,*(ckt->CKTstate0 + here->BJTvbc),vt, here->BJTtVcrit,&ichk1); if (ichk1 == 1) icheck=1; } /* * determine dc current and derivitives */next1: vtn=vt*model->BJTemissionCoeffF; if(vbe > -5*vtn){ evbe=exp(vbe/vtn); cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; gbe=csat*evbe/vtn+ckt->CKTgmin; if (c2 == 0) { cben=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -