📄 nbt2load.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 2d 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 "nbjt2def.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"/* External Declarations */extern int TWOdcDebug;extern int TWOtranDebug;extern int TWOacDebug;extern double limitJunctionVoltage(), limitResistorVoltage(), limitVce();extern void computeIntegCoeff(), computePredCoeff();extern void NBJT2conductance(), NBJT2current(), NBJT2project(), NBJT2setBCs();extern void NBJT2update();extern void TWOequilSolve(), TWObiasSolve();extern void TWOpredict(), TWOsaveState();extern void TWOresetJacobian(), TWOstoreInitialGuess();extern int TWOdeviceConverged(), TWOreadState();intNBJT2load(inModel, ckt) GENmodel *inModel; CKTcircuit *ckt;{ register NBJT2model *model = (NBJT2model *) inModel; register NBJT2instance *inst; register TWOdevice *pDevice; double startTime, startTime2, totalTime, totalTime2; double tol; double ic, ie; double iceq, ieeq; double ichat, iehat; double delVce, delVbe; double vce, vbe; 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->NBJT2nextModel) { FieldDepMobility = model->NBJT2models->MODLfieldDepMobility; TransDepMobility = model->NBJT2models->MODLtransDepMobility; SurfaceMobility = model->NBJT2models->MODLsurfaceMobility; Srh = model->NBJT2models->MODLsrh; Auger = model->NBJT2models->MODLauger; AvalancheGen = model->NBJT2models->MODLavalancheGen; OneCarrier = model->NBJT2methods->METHoneCarrier; MobDeriv = model->NBJT2methods->METHmobDeriv; MaxIterations = model->NBJT2methods->METHitLim; TWOdcDebug = model->NBJT2outputs->OUTPdcDebug; TWOtranDebug = model->NBJT2outputs->OUTPtranDebug; TWOacDebug = model->NBJT2outputs->OUTPacDebug; deviceType = model->NBJT2options->OPTNdeviceType; doVoltPred = model->NBJT2methods->METHvoltPred; if (ckt->CKTmode & MODEINITPRED) { /* compute normalized deltas and predictor coeff */ if (!(ckt->CKTmode & MODEDCTRANCURVE)) { model->NBJT2pInfo->order = ckt->CKTorder; model->NBJT2pInfo->method = ckt->CKTintegrateMethod; for (i = 0; i <= ckt->CKTmaxOrder; i++) { deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm; } computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJT2pInfo->intCoeff, deltaNorm); computePredCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJT2pInfo->predCoeff, deltaNorm); } } else if (ckt->CKTmode & MODEINITTRAN) { model->NBJT2pInfo->order = ckt->CKTorder; model->NBJT2pInfo->method = ckt->CKTintegrateMethod; for (i = 0; i <= ckt->CKTmaxOrder; i++) { deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm; } computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder, model->NBJT2pInfo->intCoeff, deltaNorm); } /* loop through all the instances of the model */ for (inst = model->NBJT2instances; inst != NULL; inst = inst->NBJT2nextInstance) { if (inst->NBJT2owner != ARCHme) continue; pDevice = inst->NBJT2pDevice; totalTime = 0.0; startTime = SPfrontEnd->IFseconds(); /* Get Temp.-Dep. Global Parameters */ GLOBgetGlobals(&(inst->NBJT2globals)); /* * initialization */ pDevice->devStates = ckt->CKTstates; icheck = 1; doInitSolve = FALSE; initStateName = NULL; if (ckt->CKTmode & MODEINITSMSIG) { vbe = *(ckt->CKTstate0 + inst->NBJT2vbe); vce = *(ckt->CKTstate0 + inst->NBJT2vce); delVbe = 0.0; delVce = 0.0; NBJT2setBCs(pDevice, vce, vbe); } else if (ckt->CKTmode & MODEINITTRAN) { *(ckt->CKTstate0 + inst->NBJT2vbe) = *(ckt->CKTstate1 + inst->NBJT2vbe); *(ckt->CKTstate0 + inst->NBJT2vce) = *(ckt->CKTstate1 + inst->NBJT2vce); vbe = *(ckt->CKTstate1 + inst->NBJT2vbe); vce = *(ckt->CKTstate1 + inst->NBJT2vce); TWOsaveState(pDevice); delVbe = 0.0; delVce = 0.0; } else if ((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) { doInitSolve = TRUE; initStateName = inst->NBJT2icFile; vbe = 0.0; vce = 0.0; delVbe = vbe; delVce = vce; } else if ((ckt->CKTmode & MODEINITJCT) && (inst->NBJT2off == 0)) { doInitSolve = TRUE; initStateName = inst->NBJT2icFile; if (deviceType == OPTN_JFET) { vbe = 0.0; vce = inst->NBJT2type * 0.5; } else { vbe = inst->NBJT2type * 0.6; vce = inst->NBJT2type * 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->NBJT2off) { vbe = 0.0; vce = 0.0; delVbe = vbe; delVce = vce; } else { if (ckt->CKTmode & MODEINITPRED) { *(ckt->CKTstate0 + inst->NBJT2vbe) = *(ckt->CKTstate1 + inst->NBJT2vbe); *(ckt->CKTstate0 + inst->NBJT2vce) = *(ckt->CKTstate1 + inst->NBJT2vce); *(ckt->CKTstate0 + inst->NBJT2ic) = *(ckt->CKTstate1 + inst->NBJT2ic); *(ckt->CKTstate0 + inst->NBJT2ie) = *(ckt->CKTstate1 + inst->NBJT2ie); *(ckt->CKTstate0 + inst->NBJT2dIeDVce) = *(ckt->CKTstate1 + inst->NBJT2dIeDVce); *(ckt->CKTstate0 + inst->NBJT2dIeDVbe) = *(ckt->CKTstate1 + inst->NBJT2dIeDVbe); *(ckt->CKTstate0 + inst->NBJT2dIcDVce) = *(ckt->CKTstate1 + inst->NBJT2dIcDVce); *(ckt->CKTstate0 + inst->NBJT2dIcDVbe) = *(ckt->CKTstate1 + inst->NBJT2dIcDVbe); /* compute normalized deltas and predictor coeff */ if (!(ckt->CKTmode & MODEDCTRANCURVE)) { /* no linear prediction on device voltages */ vbe = *(ckt->CKTstate1 + inst->NBJT2vbe); vce = *(ckt->CKTstate1 + inst->NBJT2vce); TWOpredict(pDevice, model->NBJT2pInfo); } else { if (doVoltPred) { /* linear prediction */ xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; vbe = (1+xfact) * (*(ckt->CKTstate1 + inst->NBJT2vbe)) - (xfact) * (*(ckt->CKTstate2 + inst->NBJT2vbe)); vce = (1+xfact) * (*(ckt->CKTstate1 + inst->NBJT2vce)) - (xfact) * (*(ckt->CKTstate2 + inst->NBJT2vce)); } else { vbe = *(ckt->CKTstate1 + inst->NBJT2vbe); vce = *(ckt->CKTstate1 + inst->NBJT2vce); } } } else { /* * compute new nonlinear branch voltages */ vbe = *(ckt->CKTrhsOld + inst->NBJT2baseNode) - *(ckt->CKTrhsOld + inst->NBJT2emitNode); vce = *(ckt->CKTrhsOld + inst->NBJT2colNode) - *(ckt->CKTrhsOld + inst->NBJT2emitNode); } delVbe = vbe - *(ckt->CKTstate0 + inst->NBJT2vbe); delVce = vce - *(ckt->CKTstate0 + inst->NBJT2vce); ichat = *(ckt->CKTstate0 + inst->NBJT2ic) + *(ckt->CKTstate0 + inst->NBJT2dIcDVbe) * delVbe + *(ckt->CKTstate0 + inst->NBJT2dIcDVce) * delVce; iehat = *(ckt->CKTstate0 + inst->NBJT2ie) + *(ckt->CKTstate0 + inst->NBJT2dIeDVbe) * delVbe + *(ckt->CKTstate0 + inst->NBJT2dIeDVce) * 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->NBJT2vbe))) + ckt->CKTvoltTol))) if ((FABS(delVce) < ckt->CKTreltol * MAX(FABS(vce), FABS(*(ckt->CKTstate0 + inst->NBJT2vce))) + ckt->CKTvoltTol)) if ((FABS(ichat - *(ckt->CKTstate0 + inst->NBJT2ic)) < ckt->CKTreltol * MAX(FABS(ichat), FABS(*(ckt->CKTstate0 + inst->NBJT2ic))) + ckt->CKTabstol)) if ((FABS(iehat - *(ckt->CKTstate0 + inst->NBJT2ie)) < ckt->CKTreltol * MAX(FABS(iehat), FABS(*(ckt->CKTstate0 + inst->NBJT2ie))) + ckt->CKTabstol)) { /* * bypassing.... */ vbe = *(ckt->CKTstate0 + inst->NBJT2vbe); vce = *(ckt->CKTstate0 + inst->NBJT2vce); ic = *(ckt->CKTstate0 + inst->NBJT2ic);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -