📄 nbjtload.c
字号:
/**********Copyright 1992 Regents of the University of California. All rights reserved.Author: 1987 Kartikeya Mayaram, U. C. Berkeley CAD Group**********//* * This is the function called each iteration to evaluate the numerical BJTs * in the circuit and load them into the matrix as appropriate */#include "spice.h"#include <stdio.h>#include <math.h>#include "util.h"#include "devdefs.h"#include "cktdefs.h"#include "nbjtdefs.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"/* External Declarations */extern int ONEdcDebug;extern int ONEtranDebug;extern int ONEacDebug;extern double limitVbe(), limitVce();extern void computeIntegCoeff(), computePredCoeff();extern void NBJTconductance(), NBJTcurrent(), NBJTproject(), NBJTsetBCs();extern void NBJTupdate();extern void ONEequilSolve(), ONEbiasSolve();extern void ONEpredict(), ONEsaveState();extern void ONEresetJacobian(), ONEstoreInitialGuess();extern int ONEdeviceConverged(), ONEreadState();intNBJTload(inModel, ckt) GENmodel *inModel; CKTcircuit *ckt;{ register NBJTmodel *model = (NBJTmodel *) inModel; register NBJTinstance *inst; register ONEdevice *pDevice; double startTime, startTime2, totalTime, totalTime2; double tol; double ic, ie; double iceq, ieeq; double ichat, iehat; double delVce, delVbe; double vce, vbe, vbc; double dIeDVce, dIeDVbe; double dIcDVce, dIcDVbe; double xfact; int icheck; int icheck1; int i; double deltaNorm[7]; int devConverged; int numDevNonCon; int deviceType; int doInitSolve; int doVoltPred; char *initStateName; /* loop through all the models */ for (; model != NULL; model = model->NBJTnextModel) { FieldDepMobility = model->NBJTmodels->MODLfieldDepMobility; Srh = model->NBJTmodels->MODLsrh; Auger = model->NBJTmodels->MODLauger; AvalancheGen = model->NBJTmodels->MODLavalancheGen; MobDeriv = model->NBJTmethods->METHmobDeriv; MaxIterations = model->NBJTmethods->METHitLim; ONEdcDebug = model->NBJToutputs->OUTPdcDebug; ONEtranDebug = model->NBJToutputs->OUTPtranDebug; ONEacDebug = model->NBJToutputs->OUTPacDebug; deviceType = model->NBJToptions->OPTNdeviceType; doVoltPred = model->NBJTmethods->METHvoltPred; if (ckt->CKTmode & MODEINITPRED) { /* compute normalized deltas and predictor coeff */ if (!(ckt->CKTmode & MODEDCTRANCURVE)) { model->NBJTpInfo->order = ckt->CKTorder; model->NBJTpInfo->method = ckt->CKTintegrateMethod; for (i = 0; i <= ckt->CKTmaxOrder; i++) { deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm; } computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJTpInfo->intCoeff, deltaNorm); computePredCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJTpInfo->predCoeff, deltaNorm); } } else if (ckt->CKTmode & MODEINITTRAN) { model->NBJTpInfo->order = ckt->CKTorder; model->NBJTpInfo->method = ckt->CKTintegrateMethod; for (i = 0; i <= ckt->CKTmaxOrder; i++) { deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm; } computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJTpInfo->intCoeff, deltaNorm); } /* loop through all the instances of the model */ for (inst = model->NBJTinstances; inst != NULL; inst = inst->NBJTnextInstance) { if (inst->NBJTowner != ARCHme) continue; pDevice = inst->NBJTpDevice; totalTime = 0.0; startTime = SPfrontEnd->IFseconds(); /* Get Temp.-Dep. Global Parameters */ GLOBgetGlobals(&(inst->NBJTglobals)); /* * initialization */ pDevice->devStates = ckt->CKTstates; icheck = 1; doInitSolve = FALSE; initStateName = NULL; if (ckt->CKTmode & MODEINITSMSIG) { vbe = *(ckt->CKTstate0 + inst->NBJTvbe); vce = *(ckt->CKTstate0 + inst->NBJTvce); delVbe = 0.0; delVce = 0.0; NBJTsetBCs(pDevice, vce, vbe); } else if (ckt->CKTmode & MODEINITTRAN) { *(ckt->CKTstate0 + inst->NBJTvbe) = *(ckt->CKTstate1 + inst->NBJTvbe); *(ckt->CKTstate0 + inst->NBJTvce) = *(ckt->CKTstate1 + inst->NBJTvce); vbe = *(ckt->CKTstate1 + inst->NBJTvbe); vce = *(ckt->CKTstate1 + inst->NBJTvce); ONEsaveState(pDevice); delVbe = 0.0; delVce = 0.0; } else if ((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) { doInitSolve = TRUE; initStateName = inst->NBJTicFile; vbe = 0.0; vce = 0.0; delVbe = vbe; delVce = vce; } else if ((ckt->CKTmode & MODEINITJCT) && (inst->NBJToff == 0)) { doInitSolve = TRUE; initStateName = inst->NBJTicFile; vbe = inst->NBJTtype * 0.6; vce = inst->NBJTtype * 1.0; delVbe = vbe; delVce = vce; } else if (ckt->CKTmode & MODEINITJCT) { doInitSolve = TRUE; vbe = 0.0; vce = 0.0; delVbe = vbe; delVce = vce; } else if ((ckt->CKTmode & MODEINITFIX) && inst->NBJToff) { vbe = 0.0; vce = 0.0; delVbe = vbe; delVce = vce; } else { if (ckt->CKTmode & MODEINITPRED) { *(ckt->CKTstate0 + inst->NBJTvbe) = *(ckt->CKTstate1 + inst->NBJTvbe); *(ckt->CKTstate0 + inst->NBJTvce) = *(ckt->CKTstate1 + inst->NBJTvce); *(ckt->CKTstate0 + inst->NBJTic) = *(ckt->CKTstate1 + inst->NBJTic); *(ckt->CKTstate0 + inst->NBJTie) = *(ckt->CKTstate1 + inst->NBJTie); *(ckt->CKTstate0 + inst->NBJTdIeDVce) = *(ckt->CKTstate1 + inst->NBJTdIeDVce); *(ckt->CKTstate0 + inst->NBJTdIeDVbe) = *(ckt->CKTstate1 + inst->NBJTdIeDVbe); *(ckt->CKTstate0 + inst->NBJTdIcDVce) = *(ckt->CKTstate1 + inst->NBJTdIcDVce); *(ckt->CKTstate0 + inst->NBJTdIcDVbe) = *(ckt->CKTstate1 + inst->NBJTdIcDVbe); if (!(ckt->CKTmode & MODEDCTRANCURVE)) { /* no linear prediction on device voltages */ vbe = *(ckt->CKTstate1 + inst->NBJTvbe); vce = *(ckt->CKTstate1 + inst->NBJTvce); ONEpredict(pDevice, model->NBJTpInfo); } else { if (doVoltPred) { /* linear prediction */ xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; vbe = (1+xfact) * (*(ckt->CKTstate1 + inst->NBJTvbe)) - (xfact) * (*(ckt->CKTstate2 + inst->NBJTvbe)); vce = (1+xfact) * (*(ckt->CKTstate1 + inst->NBJTvce)) - (xfact) * (*(ckt->CKTstate2 + inst->NBJTvce)); } else { vbe = *(ckt->CKTstate1 + inst->NBJTvbe); vce = *(ckt->CKTstate1 + inst->NBJTvce); } } } else { /* * compute new nonlinear branch voltages */ vbe = *(ckt->CKTrhsOld + inst->NBJTbaseNode) - *(ckt->CKTrhsOld + inst->NBJTemitNode); vce = *(ckt->CKTrhsOld + inst->NBJTcolNode) - *(ckt->CKTrhsOld + inst->NBJTemitNode); } delVbe = vbe - *(ckt->CKTstate0 + inst->NBJTvbe); delVce = vce - *(ckt->CKTstate0 + inst->NBJTvce); ichat = *(ckt->CKTstate0 + inst->NBJTic) - *(ckt->CKTstate0 + inst->NBJTdIcDVbe) * delVbe - *(ckt->CKTstate0 + inst->NBJTdIcDVce) * delVce; iehat = *(ckt->CKTstate0 + inst->NBJTie) - *(ckt->CKTstate0 + inst->NBJTdIeDVbe) * delVbe - *(ckt->CKTstate0 + inst->NBJTdIeDVce) * delVce;#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) && pDevice->converged && (!(ckt->CKTmode & MODEINITPRED)) && (FABS(delVbe) < (ckt->CKTreltol * MAX(FABS(vbe), FABS(*(ckt->CKTstate0 + inst->NBJTvbe))) + ckt->CKTvoltTol))) if ((FABS(delVce) < ckt->CKTreltol * MAX(FABS(vce), FABS(*(ckt->CKTstate0 + inst->NBJTvce))) + ckt->CKTvoltTol)) if ((FABS(ichat - *(ckt->CKTstate0 + inst->NBJTic)) < ckt->CKTreltol * MAX(FABS(ichat), FABS(*(ckt->CKTstate0 + inst->NBJTic))) + ckt->CKTabstol)) if ((FABS(iehat - *(ckt->CKTstate0 + inst->NBJTie)) < ckt->CKTreltol * MAX(FABS(iehat), FABS(*(ckt->CKTstate0 + inst->NBJTie))) + ckt->CKTabstol)) { /* * bypassing.... */ vbe = *(ckt->CKTstate0 + inst->NBJTvbe); vce = *(ckt->CKTstate0 + inst->NBJTvce); ic = *(ckt->CKTstate0 + inst->NBJTic); ie = *(ckt->CKTstate0 + inst->NBJTie); dIeDVce = *(ckt->CKTstate0 + inst->NBJTdIeDVce); dIeDVbe = *(ckt->CKTstate0 + inst->NBJTdIeDVbe); dIcDVce = *(ckt->CKTstate0 + inst->NBJTdIcDVce); dIcDVbe = *(ckt->CKTstate0 + inst->NBJTdIcDVbe); goto load; }#endif /* NOBYPASS */ /* * limit nonlinear branch voltages */ icheck1 = 1; vbe = inst->NBJTtype * limitVbe(inst->NBJTtype * vbe, inst->NBJTtype * *(ckt->CKTstate0 + inst->NBJTvbe), &icheck);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -