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

📄 twocond.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**********//* Functions to compute terminal conductances & currents. */#include <math.h>#include "numglobs.h"#include "numenum.h"#include "nummacs.h"#include "twomesh.h"#include "twodev.h"/* Forward declarations. */double contactConductance();double oxideConductance();double contactCurrent();double oxideCurrent();void storeNewRhs();/* Temporary hack to remove NUMOS gate special case */#ifdef NORMAL_GATE#define GateTypeConductance oxideConductance#define GateTypeCurrent oxideCurrent#else#define GateTypeConductance contactConductance#define GateTypeCurrent contactCurrent#endif /* NORMAL_GATE */void NUMD2conductance( pDevice, tranAnalysis, intCoeff, gd )     TWOdevice *pDevice;     BOOLEAN tranAnalysis;     double *intCoeff;     double *gd;{  TWOcontact *pContact = pDevice->pFirstContact;  int index;  double *incVpn;  BOOLEAN deltaVContact = FALSE;    /*    * store the new rhs for computing the incremental quantities   * with the second to last node. solve the system of equations   */  incVpn = pDevice->dcDeltaSolution;  storeNewRhs( pDevice, pDevice->pLastContact );  spSolve( pDevice->matrix, pDevice->rhs, incVpn);    incVpn = pDevice->dcDeltaSolution;  *gd = contactConductance( pDevice, pContact, deltaVContact, incVpn,			  tranAnalysis, intCoeff );  *gd *= - GNorm * pDevice->width * LNorm;}void NBJT2conductance( pDevice, tranAnalysis, intCoeff, 		      dIeDVce, dIcDVce, dIeDVbe, dIcDVbe )     TWOdevice *pDevice;     BOOLEAN tranAnalysis;     double *intCoeff;     double *dIeDVce, *dIcDVce, *dIeDVbe, *dIcDVbe;{  TWOcontact *pEmitContact = pDevice->pLastContact;  TWOcontact *pColContact = pDevice->pFirstContact;  TWOcontact *pBaseContact = pDevice->pFirstContact->next;  int index;  double width = pDevice->width;  double *incVce, *incVbe;    /*    * store the new rhs for computing the incremental quantities   * incVce (dcDeltaSolution) and incVbe (copiedSolution) are used to   * store the incremental quantities associated with Vce and Vbe   */    incVce = pDevice->dcDeltaSolution;  incVbe = pDevice->copiedSolution;  storeNewRhs( pDevice, pColContact );  spSolve( pDevice->matrix, pDevice->rhs, incVce);  storeNewRhs( pDevice, pBaseContact );  spSolve( pDevice->matrix, pDevice->rhs, incVbe);    *dIeDVce = contactConductance( pDevice, pEmitContact, FALSE, incVce,				tranAnalysis, intCoeff );  *dIeDVbe = contactConductance( pDevice, pEmitContact, FALSE, incVbe,				tranAnalysis, intCoeff );    *dIcDVce = contactConductance( pDevice, pColContact, TRUE, incVce,				tranAnalysis, intCoeff );  *dIcDVbe = contactConductance( pDevice, pColContact, FALSE, incVbe,				tranAnalysis, intCoeff );  *dIeDVce *= GNorm * width * LNorm;  *dIcDVce *= GNorm * width * LNorm;  *dIeDVbe *= GNorm * width * LNorm;  *dIcDVbe *= GNorm * width * LNorm;}void NUMOSconductance( pDevice, tranAnalysis, intCoeff, dIdV )     TWOdevice *pDevice;     BOOLEAN tranAnalysis;     double *intCoeff;     struct mosConductances *dIdV;{  TWOcontact *pDContact = pDevice->pFirstContact;  TWOcontact *pGContact = pDevice->pFirstContact->next;  TWOcontact *pSContact = pDevice->pFirstContact->next->next;  TWOcontact *pBContact = pDevice->pLastContact;  int index;  double width = pDevice->width;  double *incVdb, *incVsb, *incVgb;    /*    * store the new rhs for computing the incremental quantities   * incVdb (dcDeltaSolution)   */    incVdb = pDevice->dcDeltaSolution;  incVsb = pDevice->copiedSolution;  incVgb = pDevice->rhsImag;  storeNewRhs( pDevice, pDContact );  spSolve( pDevice->matrix, pDevice->rhs, incVdb);  storeNewRhs( pDevice, pSContact );  spSolve( pDevice->matrix, pDevice->rhs, incVsb);  storeNewRhs( pDevice, pGContact );  spSolve( pDevice->matrix, pDevice->rhs, incVgb);    dIdV->dIdDVdb = contactConductance( pDevice, pDContact, TRUE,				     incVdb, tranAnalysis, intCoeff );  dIdV->dIsDVdb = contactConductance( pDevice, pSContact, FALSE,				     incVdb, tranAnalysis, intCoeff );  dIdV->dIgDVdb = GateTypeConductance( pDevice, pGContact, FALSE,				      incVdb, tranAnalysis, intCoeff );  dIdV->dIdDVsb = contactConductance( pDevice, pDContact, FALSE,				     incVsb, tranAnalysis, intCoeff );  dIdV->dIsDVsb = contactConductance( pDevice, pSContact, TRUE,				     incVsb, tranAnalysis, intCoeff );  dIdV->dIgDVsb = GateTypeConductance( pDevice, pGContact, FALSE,				      incVsb, tranAnalysis, intCoeff );  dIdV->dIdDVgb = contactConductance( pDevice, pDContact, FALSE,				     incVgb, tranAnalysis, intCoeff );  dIdV->dIsDVgb = contactConductance( pDevice, pSContact, FALSE,				     incVgb, tranAnalysis, intCoeff );  dIdV->dIgDVgb = GateTypeConductance( pDevice, pGContact, TRUE,				      incVgb, tranAnalysis, intCoeff );    dIdV->dIdDVdb *= GNorm * width * LNorm;  dIdV->dIdDVsb *= GNorm * width * LNorm;  dIdV->dIdDVgb *= GNorm * width * LNorm;  dIdV->dIsDVdb *= GNorm * width * LNorm;  dIdV->dIsDVsb *= GNorm * width * LNorm;  dIdV->dIsDVgb *= GNorm * width * LNorm;  dIdV->dIgDVdb *= GNorm * width * LNorm;  dIdV->dIgDVsb *= GNorm * width * LNorm;  dIdV->dIgDVgb *= GNorm * width * LNorm;  }double  contactCurrent( pDevice, pContact )TWOdevice *pDevice;TWOcontact *pContact;{  /* computes the current through the contact given in pContact */  int index, i, numContactNodes;  TWOnode *pNode;  TWOelem *pElem;  TWOedge *pHEdge, *pVEdge;  double dx, dy;  double jTotal = 0.0;    numContactNodes = pContact->numNodes;  for ( index = 0; index < numContactNodes; index++ ) {    pNode = pContact->pNodes[ index ];    for ( i = 0; i <= 3; i++ ) {      pElem = pNode->pElems[ i ];      if ( pElem ISNOT NIL(TWOelem) ) {	dx = 0.5 * pElem->dx;	dy = 0.5 * pElem->dy;	switch ( i ) {	case 0:	  /* Bottom Right node */	  pHEdge = pElem->pBotEdge;	  pVEdge = pElem->pRightEdge;	  jTotal += pElem->epsRel * ( -dy * pHEdge->jd - dx * pVEdge->jd );	  if ( pElem->elemType IS SEMICON ) {	    jTotal += -dy * (pHEdge->jn + pHEdge->jp)	      -dx * (pVEdge->jn + pVEdge->jp);	  }	  break;	case 1:	  /* Bottom Left node */	  pHEdge = pElem->pBotEdge;	  pVEdge = pElem->pLeftEdge;	  jTotal += pElem->epsRel * ( dy * pHEdge->jd - dx * pVEdge->jd );	  if ( pElem->elemType IS SEMICON ) {	    jTotal += dy * (pHEdge->jn + pHEdge->jp)	      -dx * (pVEdge->jn + pVEdge->jp);	  }	  break;	case 2:	  /* Top Left node */	  pHEdge = pElem->pTopEdge;	  pVEdge = pElem->pLeftEdge;	  jTotal += pElem->epsRel * ( dy * pHEdge->jd + dx * pVEdge->jd );	  if ( pElem->elemType IS SEMICON ) {	    jTotal += dy * (pHEdge->jn + pHEdge->jp)	      + dx * (pVEdge->jn + pVEdge->jp);	  }	  break;	case 3:	  /* Top Right Node */	  pHEdge = pElem->pTopEdge;	  pVEdge = pElem->pRightEdge;	  jTotal += pElem->epsRel * ( -dy * pHEdge->jd + dx * pVEdge->jd );	  if ( pElem->elemType IS SEMICON ) {	    jTotal += -dy * (pHEdge->jn + pHEdge->jp)	      + dx * (pVEdge->jn + pVEdge->jp);	  }	  break;	}      }    }  }    return( jTotal * pDevice->width * LNorm * JNorm );}double oxideCurrent( pDevice, pContact, tranAnalysis )TWOdevice *pDevice;TWOcontact *pContact;BOOLEAN tranAnalysis;{  /* computes the current through the contact given in pContact */  int index, i, numContactNodes;  TWOnode *pNode;  TWOelem *pElem;  TWOedge *pHEdge, *pVEdge;  double dx, dy;  double jTotal = 0.0;    if ( NOT tranAnalysis ) {    return( jTotal );  }    numContactNodes = pContact->numNodes;  for ( index = 0; index < numContactNodes; index++ ) {    pNode = pContact->pNodes[ index ];    for ( i = 0; i <= 3; i++ ) {      pElem = pNode->pElems[ i ];      if ( pElem ISNOT NIL(TWOelem) ) {	dx = 0.5 * pElem->dx;	dy = 0.5 * pElem->dy;	switch ( i ) {	case 0:	  /* Bottom Right node */	  pHEdge = pElem->pBotEdge;	  pVEdge = pElem->pRightEdge;	  jTotal += pElem->epsRel * ( -dy * pHEdge->jd - dx * pVEdge->jd );	  break;	case 1:	  /* Bottom Left node */	  pHEdge = pElem->pBotEdge;	  pVEdge = pElem->pLeftEdge;	  jTotal += pElem->epsRel * ( dy * pHEdge->jd - dx * pVEdge->jd );	  break;	case 2:	  /* Top Left node */	  pHEdge = pElem->pTopEdge;	  pVEdge = pElem->pLeftEdge;	  jTotal += pElem->epsRel * ( dy * pHEdge->jd + dx * pVEdge->jd );	  break;	case 3:	  /* Top Right Node */	  pHEdge = pElem->pTopEdge;	  pVEdge = pElem->pRightEdge;	  jTotal += pElem->epsRel * ( -dy * pHEdge->jd + dx * pVEdge->jd );	  break;	}      }    }  }    return( jTotal * pDevice->width * LNorm * JNorm );}double contactConductance( pDevice, pContact, delVContact,			  dxDv, tranAnalysis, intCoeff )     TWOdevice *pDevice;     TWOcontact *pContact;     BOOLEAN delVContact, tranAnalysis;     double *dxDv, *intCoeff;{  /* computes the conductance of the contact given in pContact */  int index, i, numContactNodes;  TWOnode *pNode, *pHNode, *pVNode;  TWOelem *pElem;  TWOedge *pHEdge, *pVEdge;  double dPsiDv, dnDv, dpDv;  double gTotal = 0.0;  int nInc, pInc;    /* for one carrier the rest of this code relies on appropriate      current derivative term to be zero */  if ( NOT OneCarrier ) {    nInc = 1;    pInc = 2;  } else {    nInc = 1;    pInc = 1;  }     numContactNodes = pContact->numNodes;  for ( index = 0; index < numContactNodes; index++ ) {    pNode = pContact->pNodes[ index ];    for ( i = 0; i <= 3; i++ ) {      pElem = pNode->pElems[ i ];

⌨️ 快捷键说明

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