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

📄 nummload.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1991 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 * MOSFETs 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 "numosdef.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"struct mosAdmittances {  SPcomplex yIdVdb;  SPcomplex yIdVsb;  SPcomplex yIdVgb;  SPcomplex yIsVdb;  SPcomplex yIsVsb;  SPcomplex yIsVgb;  SPcomplex yIgVdb;  SPcomplex yIgVsb;  SPcomplex yIgVgb;};/* External Declarations */extern int TWOdcDebug;extern int TWOtranDebug;extern int TWOacDebug;double limitJunctionVoltage();double limitVbe();double limitVce();double limitVgb();void TWOstoreInitialGuess();void NUMOSconductance();void NUMOScurrent();void NUMOSproject();void NUMOSupdate();void NUMOSsetBCs();void TWOequilSolve();void TWObiasSolve();void computeIntegCoeff();void computePredCoeff();void TWOpredict();void TWOsaveState();void TWOresetJacobian();int TWOdeviceConverged(), TWOreadState();intNUMOSload(inModel, ckt)  GENmodel *inModel;  CKTcircuit *ckt;{  register NUMOSmodel *model = (NUMOSmodel *) inModel;  register NUMOSinstance *inst;  register TWOdevice *pDevice;  double startTime, startTime2, totalTime, totalTime2;  double tol;  double xfact;  double id, is, ig;  double ideq, iseq, igeq;  double idhat, ishat, ighat;  double delVdb, delVsb, delVgb;  double vdb, vsb, vgb;  struct mosConductances g;  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->NUMOSnextModel) {    FieldDepMobility = model->NUMOSmodels->MODLfieldDepMobility;    TransDepMobility = model->NUMOSmodels->MODLtransDepMobility;    SurfaceMobility = model->NUMOSmodels->MODLsurfaceMobility;    Srh = model->NUMOSmodels->MODLsrh;    Auger = model->NUMOSmodels->MODLauger;    AvalancheGen = model->NUMOSmodels->MODLavalancheGen;    OneCarrier = model->NUMOSmethods->METHoneCarrier;    MobDeriv = model->NUMOSmethods->METHmobDeriv;    MaxIterations = model->NUMOSmethods->METHitLim;    TWOdcDebug = model->NUMOSoutputs->OUTPdcDebug;    TWOtranDebug = model->NUMOSoutputs->OUTPtranDebug;    TWOacDebug = model->NUMOSoutputs->OUTPacDebug;    deviceType = model->NUMOSoptions->OPTNdeviceType;    doVoltPred = model->NUMOSmethods->METHvoltPred;    if (ckt->CKTmode & MODEINITPRED) {      /* compute normalized deltas and predictor coeff */      if (!(ckt->CKTmode & MODEDCTRANCURVE)) {	model->NUMOSpInfo->order = ckt->CKTorder;	model->NUMOSpInfo->method = ckt->CKTintegrateMethod;	for (i = 0; i <= ckt->CKTmaxOrder; i++) {	  deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm;	}	computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder,	    model->NUMOSpInfo->intCoeff, deltaNorm);	computePredCoeff(ckt->CKTintegrateMethod, ckt->CKTorder,	    model->NUMOSpInfo->predCoeff, deltaNorm);      }    } else if (ckt->CKTmode & MODEINITTRAN) {      model->NUMOSpInfo->order = ckt->CKTorder;      model->NUMOSpInfo->method = ckt->CKTintegrateMethod;      for (i = 0; i <= ckt->CKTmaxOrder; i++) {	deltaNorm[i] = ckt->CKTdeltaOld[i] / TNorm;      }      computeIntegCoeff(ckt->CKTintegrateMethod, ckt->CKTorder,	  model->NUMOSpInfo->intCoeff, deltaNorm);    }    /* loop through all the instances of the model */    for (inst = model->NUMOSinstances; inst != NULL;	inst = inst->NUMOSnextInstance) {      if (inst->NUMOSowner != ARCHme) continue;      pDevice = inst->NUMOSpDevice;      totalTime = 0.0;      startTime = SPfrontEnd->IFseconds();      /* Get Temp.-Dep. Global Parameters */      GLOBgetGlobals(&(inst->NUMOSglobals));      /*       * initialization       */      pDevice->devStates = ckt->CKTstates;      icheck = 1;      doInitSolve = FALSE;      initStateName = NULL;      if (ckt->CKTmode & MODEINITSMSIG) {	vdb = *(ckt->CKTstate0 + inst->NUMOSvdb);	vsb = *(ckt->CKTstate0 + inst->NUMOSvsb);	vgb = *(ckt->CKTstate0 + inst->NUMOSvgb);	delVdb = 0.0;	delVsb = 0.0;	delVgb = 0.0;	NUMOSsetBCs(pDevice, vdb, vsb, vgb);      } else if (ckt->CKTmode & MODEINITTRAN) {	*(ckt->CKTstate0 + inst->NUMOSvdb) =	    *(ckt->CKTstate1 + inst->NUMOSvdb);	*(ckt->CKTstate0 + inst->NUMOSvsb) =	    *(ckt->CKTstate1 + inst->NUMOSvsb);	*(ckt->CKTstate0 + inst->NUMOSvgb) =	    *(ckt->CKTstate1 + inst->NUMOSvgb);	vdb = *(ckt->CKTstate1 + inst->NUMOSvdb);	vsb = *(ckt->CKTstate1 + inst->NUMOSvsb);	vgb = *(ckt->CKTstate1 + inst->NUMOSvgb);	TWOsaveState(pDevice);	delVdb = 0.0;	delVsb = 0.0;	delVgb = 0.0;      } else if ((ckt->CKTmode & MODEINITJCT) &&	  (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) {	doInitSolve = TRUE;	initStateName = inst->NUMOSicFile;	vdb = 0.0;	vsb = 0.0;	vgb = 0.0;	delVdb = vdb;	delVsb = vsb;	delVgb = vgb;      } else if ((ckt->CKTmode & MODEINITJCT) && (inst->NUMOSoff == 0)) {	doInitSolve = TRUE;	initStateName = inst->NUMOSicFile;	if (deviceType == OPTN_BIPOLAR) {	  /* d,g,s,b => c,b,e,s */	  vdb = 0.0;	  vsb = -inst->NUMOStype * 1.0;	  vgb = -inst->NUMOStype * (1.0 - 0.6);	} else if (deviceType == OPTN_JFET) {	  vdb = inst->NUMOStype * 0.5;	  vsb = 0.0;	  vgb = 0.0;	} else {	  vdb = inst->NUMOStype * 0.5;	  vsb = 0.0;	  vgb = inst->NUMOStype * 1.0;	}	delVdb = vdb;	delVsb = vsb;	delVgb = vgb;      } else if (ckt->CKTmode & MODEINITJCT) {	doInitSolve = TRUE;	vdb = 0.0;	vsb = 0.0;	vgb = 0.0;	delVdb = vdb;	delVsb = vsb;	delVgb = vgb;      } else if ((ckt->CKTmode & MODEINITFIX) && inst->NUMOSoff) {	vdb = 0.0;	vsb = 0.0;	vgb = 0.0;	delVdb = vdb;	delVsb = vsb;	delVgb = vgb;      } else {	if (ckt->CKTmode & MODEINITPRED) {	  *(ckt->CKTstate0 + inst->NUMOSvdb) =	      *(ckt->CKTstate1 + inst->NUMOSvdb);	  *(ckt->CKTstate0 + inst->NUMOSvsb) =	      *(ckt->CKTstate1 + inst->NUMOSvsb);	  *(ckt->CKTstate0 + inst->NUMOSvgb) =	      *(ckt->CKTstate1 + inst->NUMOSvgb);	  *(ckt->CKTstate0 + inst->NUMOSid) =	      *(ckt->CKTstate1 + inst->NUMOSid);	  *(ckt->CKTstate0 + inst->NUMOSis) =	      *(ckt->CKTstate1 + inst->NUMOSis);	  *(ckt->CKTstate0 + inst->NUMOSig) =	      *(ckt->CKTstate1 + inst->NUMOSig);	  *(ckt->CKTstate0 + inst->NUMOSdIdDVdb) =	      *(ckt->CKTstate1 + inst->NUMOSdIdDVdb);	  *(ckt->CKTstate0 + inst->NUMOSdIdDVsb) =	      *(ckt->CKTstate1 + inst->NUMOSdIdDVsb);	  *(ckt->CKTstate0 + inst->NUMOSdIdDVgb) =	      *(ckt->CKTstate1 + inst->NUMOSdIdDVgb);	  *(ckt->CKTstate0 + inst->NUMOSdIsDVdb) =	      *(ckt->CKTstate1 + inst->NUMOSdIsDVdb);	  *(ckt->CKTstate0 + inst->NUMOSdIsDVsb) =	      *(ckt->CKTstate1 + inst->NUMOSdIsDVsb);	  *(ckt->CKTstate0 + inst->NUMOSdIsDVgb) =	      *(ckt->CKTstate1 + inst->NUMOSdIsDVgb);	  *(ckt->CKTstate0 + inst->NUMOSdIgDVdb) =	      *(ckt->CKTstate1 + inst->NUMOSdIgDVdb);	  *(ckt->CKTstate0 + inst->NUMOSdIgDVsb) =	      *(ckt->CKTstate1 + inst->NUMOSdIgDVsb);	  *(ckt->CKTstate0 + inst->NUMOSdIgDVgb) =	      *(ckt->CKTstate1 + inst->NUMOSdIgDVgb);	  if (!(ckt->CKTmode & MODEDCTRANCURVE)) {	    /* no linear prediction on device voltages */	    vdb = *(ckt->CKTstate1 + inst->NUMOSvdb);	    vsb = *(ckt->CKTstate1 + inst->NUMOSvsb);	    vgb = *(ckt->CKTstate1 + inst->NUMOSvgb);	    TWOpredict(pDevice, model->NUMOSpInfo);	  } else {            if (doVoltPred) {	      /* linear prediction */	      xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1];	      vdb = (1+xfact) * (*(ckt->CKTstate1 + inst->NUMOSvdb))		  -   (xfact) * (*(ckt->CKTstate2 + inst->NUMOSvdb));	      vsb = (1+xfact) * (*(ckt->CKTstate1 + inst->NUMOSvsb))		  -   (xfact) * (*(ckt->CKTstate2 + inst->NUMOSvsb));	      vgb = (1+xfact) * (*(ckt->CKTstate1 + inst->NUMOSvgb))		  -   (xfact) * (*(ckt->CKTstate2 + inst->NUMOSvgb));	    } else {	      vdb = *(ckt->CKTstate1 + inst->NUMOSvdb);	      vsb = *(ckt->CKTstate1 + inst->NUMOSvsb);	      vgb = *(ckt->CKTstate1 + inst->NUMOSvgb);	    }	  }	} else {	  /*	   * compute new nonlinear branch voltages	   */	  vdb = *(ckt->CKTrhsOld + inst->NUMOSdrainNode)	      - *(ckt->CKTrhsOld + inst->NUMOSbulkNode);	  vsb = *(ckt->CKTrhsOld + inst->NUMOSsourceNode)	      - *(ckt->CKTrhsOld + inst->NUMOSbulkNode);	  vgb = *(ckt->CKTrhsOld + inst->NUMOSgateNode)	      - *(ckt->CKTrhsOld + inst->NUMOSbulkNode);	}	delVdb = vdb - *(ckt->CKTstate0 + inst->NUMOSvdb);	delVsb = vsb - *(ckt->CKTstate0 + inst->NUMOSvsb);	delVgb = vgb - *(ckt->CKTstate0 + inst->NUMOSvgb);	idhat = *(ckt->CKTstate0 + inst->NUMOSid)	    + *(ckt->CKTstate0 + inst->NUMOSdIdDVdb) * delVdb	    + *(ckt->CKTstate0 + inst->NUMOSdIdDVsb) * delVsb	    + *(ckt->CKTstate0 + inst->NUMOSdIdDVgb) * delVgb;	ishat = *(ckt->CKTstate0 + inst->NUMOSis)	    + *(ckt->CKTstate0 + inst->NUMOSdIsDVdb) * delVdb	    + *(ckt->CKTstate0 + inst->NUMOSdIsDVsb) * delVsb	    + *(ckt->CKTstate0 + inst->NUMOSdIsDVgb) * delVgb;	ighat = *(ckt->CKTstate0 + inst->NUMOSig)	    + *(ckt->CKTstate0 + inst->NUMOSdIgDVdb) * delVdb	    + *(ckt->CKTstate0 + inst->NUMOSdIgDVsb) * delVsb	    + *(ckt->CKTstate0 + inst->NUMOSdIgDVgb) * delVgb;#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(delVdb) < (ckt->CKTreltol * MAX(FABS(vdb),			FABS(*(ckt->CKTstate0 + inst->NUMOSvdb))) +		    ckt->CKTvoltTol)))	  if ((FABS(delVsb) < ckt->CKTreltol * MAX(FABS(vsb),		      FABS(*(ckt->CKTstate0 + inst->NUMOSvsb))) +		  ckt->CKTvoltTol))	    if ((FABS(delVgb) < ckt->CKTreltol * MAX(FABS(vgb),			FABS(*(ckt->CKTstate0 + inst->NUMOSvgb))) +		    ckt->CKTvoltTol))	      if ((FABS(idhat - *(ckt->CKTstate0 + inst->NUMOSid)) <		      ckt->CKTreltol * MAX(FABS(idhat),			  FABS(*(ckt->CKTstate0 + inst->NUMOSid))) +		      ckt->CKTabstol))		if ((FABS(ishat - *(ckt->CKTstate0 + inst->NUMOSis)) <			ckt->CKTreltol * MAX(FABS(ishat),			    FABS(*(ckt->CKTstate0 + inst->NUMOSis))) +			ckt->CKTabstol))		  if ((FABS(ighat - *(ckt->CKTstate0 + inst->NUMOSig)) <			  ckt->CKTreltol * MAX(FABS(ighat),			      FABS(*(ckt->CKTstate0 + inst->NUMOSig))) +			  ckt->CKTabstol)) {		    /*		     * bypassing....		     */		    vdb = *(ckt->CKTstate0 + inst->NUMOSvdb);		    vsb = *(ckt->CKTstate0 + inst->NUMOSvsb);		    vgb = *(ckt->CKTstate0 + inst->NUMOSvgb);		    id = *(ckt->CKTstate0 + inst->NUMOSid);		    is = *(ckt->CKTstate0 + inst->NUMOSis);

⌨️ 快捷键说明

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