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

📄 onesetup.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1991 Regents of the University of California.  All rights reserved.Author:	1987 Kartikeya Mayaram, U. C. Berkeley CAD GroupAuthor:	1991 David A. Gates, U. C. Berkeley CAD Group**********//**********One-Dimensional Numerical Device Setup Routines**********/#include <math.h>#include "numglobs.h"#include "numconst.h"#include "numenum.h"#include "nummacs.h"#include "onemesh.h"#include "onedev.h"#include "carddefs.h"		/* XXX Not really modular if we need this. *//* compute node parameters */voidONEsetup(pDevice)  ONEdevice *pDevice;{  double temp1, deltaEg, avgConc, totalConc, absNetConc;  double ncv0, dBand, dNie, psiBand[2];  int index, eIndex;  int numContactNodes;  ONEnode *pNode;  ONEelem *pElem;  ONEedge *pEdge;  ONEmaterial *info;  for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {    pElem = pDevice->elemArray[eIndex];    info = pElem->matlInfo;    pElem->dx = pElem->pRightNode->x - pElem->pLeftNode->x;    pElem->epsRel = info->eps;    if (pElem->elemType IS INSULATOR) {      for (index = 0; index <= 1; index++) {	if (pElem->evalNodes[index]) {	  pNode = pElem->pNodes[index];	  if (pNode->nodeType IS CONTACT) {	    pNode->eaff = PHI_METAL;	    pNode->eg = 0.0;	  } else {	    pNode->eaff = info->affin;	    pNode->eg = info->eg0;	  }	}      }    } else if (pElem->elemType IS SEMICON) {      ncv0 = sqrt(info->nc0) * sqrt(info->nv0);      for (index = 0; index <= 1; index++) {	if (pElem->evalNodes[index]) {	  pNode = pElem->pNodes[index];	  /* Fixed Interface Charge */	  pNode->qf = 0.0;	  /* Narrowing of Energy Band-Gap */	  if (BandGapNarrowing) {	    absNetConc = ABS(pNode->netConc);	    if (pNode->netConc > 0.0) {	      temp1 = log(absNetConc / info->nrefBGN[ELEC]);	      deltaEg = -info->dEgDn[ELEC] * (temp1 + sqrt(temp1 * temp1 + 0.5));	      pNode->eg = info->eg0 + deltaEg;	    } else if (pNode->netConc < 0.0) {	      temp1 = log(absNetConc / info->nrefBGN[HOLE]);	      deltaEg = -info->dEgDn[HOLE] * (temp1 + sqrt(temp1 * temp1 + 0.5));	      pNode->eg = info->eg0 + deltaEg;	    } else {	      pNode->eg = info->eg0;	    }	  } else {	    pNode->eg = info->eg0;	  }	  pNode->nie = ncv0 * exp(-0.5 * pNode->eg / Vt);	  pNode->eaff = info->affin;	  /* Save band structure parameter. */	  psiBand[index] = -info->refPsi;	  /* Ionized-Impurity-Scattering Reduction of Carrier Lifetime */	  if (ConcDepLifetime) {	    totalConc = pNode->totalConc;	    temp1 = 1.0 / (1.0 + totalConc / info->nrefSRH[ELEC]);	    pNode->tn = info->tau0[ELEC] * temp1;	    temp1 = 1.0 / (1.0 + totalConc / info->nrefSRH[HOLE]);	    pNode->tp = info->tau0[HOLE] * temp1;	  } else {	    pNode->tn = info->tau0[ELEC];	    pNode->tp = info->tau0[HOLE];	  }	}      }      pEdge = pElem->pEdge;      /* Variable Band Built-In Potential */      dBand = psiBand[1] - psiBand[0];      dNie = log(pElem->pNodes[1]->nie / pElem->pNodes[0]->nie);      pEdge->dCBand = dBand + dNie;      pEdge->dVBand = -dBand + dNie;      /* Evaluate conc.-dep. mobility. */      avgConc = 0.5 * (pElem->pRightNode->totalConc + pElem->pLeftNode->totalConc);      MOBconcDep(info, avgConc, &pEdge->mun, &pEdge->mup);    }  }}/* Transfer BC info from bdry to nodes and edges. */static voidONEcopyBCinfo(pDevice, pElem, bdry, index)  ONEdevice *pDevice;  ONEelem *pElem;  BDRYcard *bdry;  int index;{  ONEnode *pNode;  ONEelem *pNElem;  int eIndex, nIndex;  double length;  /* First add fixed charge. */  pNode = pElem->pNodes[index];  pNode->qf += bdry->BDRYqf;  /* Now add surface recombination. */  /* Compute semiconductor length around this node. */  length = 0.0;  for (eIndex = 0; eIndex <= 3; eIndex++) {    pNElem = pNode->pElems[eIndex];    if (pNElem ISNOT NIL(ONEelem) && pElem->elemType IS SEMICON) {      length += 0.5 * pElem->dx;    }  }  if (bdry->BDRYsnGiven) {    pNode->tn = pNode->tn /	(1.0 + ((bdry->BDRYsn * TNorm) * pNode->tn) / length);  }  if (bdry->BDRYspGiven) {    pNode->tp = pNode->tp /	(1.0 + ((bdry->BDRYsp * TNorm) * pNode->tp) / length);  }  /* Finally, surface layer is irrelevant for 1d devices. */}/* Compute boundary condition parameters. */voidONEsetBCparams(pDevice, bdryList, contList)  ONEdevice *pDevice;  BDRYcard *bdryList;  CONTcard *contList;{  int index, xIndex;  ONEnode *pNode;  ONEelem *pElem, *pNElem;  BDRYcard *bdry;  CONTcard *cont;  for (bdry = bdryList; bdry != NIL(BDRYcard); bdry = bdry->BDRYnextCard) {    for (xIndex = bdry->BDRYixLow; xIndex < bdry->BDRYixHigh; xIndex++) {      pElem = pDevice->elemArray[xIndex];      if (pElem ISNOT NIL(ONEelem)) {	if (pElem->domain == bdry->BDRYdomain) {	  for (index = 0; index <= 1; index++) {	    if (pElem->evalNodes[index]) {	      pNElem = pElem->pElems[index];	      if (bdry->BDRYneighborGiven) {		if (pNElem && pNElem->domain == bdry->BDRYneighbor) {		  /* Found an interface node. */		  ONEcopyBCinfo(pDevice, pElem, bdry, index);		}	      } else {		if (!pNElem || pNElem->domain != pElem->domain) {		  /* Found a boundary node. */		  ONEcopyBCinfo(pDevice, pElem, bdry, index);		}	      }	    }	  }	}      }    }  }  for (cont = contList; cont != NIL(CONTcard); cont = cont->CONTnextCard) {    if (!cont->CONTworkfunGiven) {      cont->CONTworkfun = PHI_METAL;    }    /*     * XXX This won't work right if someone tries to change the 1d BJT base     * contact workfunction and doesn't want to change the emitter. But no     * one will probably try to do that.     */    if (cont->CONTnumber == 1) {      pDevice->elemArray[1]->pNodes[0]->eaff = cont->CONTworkfun;    } else if (cont->CONTnumber == 2 || cont->CONTnumber == 3) {      pDevice->elemArray[pDevice->numNodes - 1]->pNodes[1]->eaff =	  cont->CONTworkfun;    }  }}voidONEnormalize(pDevice)  ONEdevice *pDevice;{  int index, eIndex;  ONEelem *pElem;  ONEnode *pNode;  for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {    pElem = pDevice->elemArray[eIndex];    pElem->dx /= LNorm;    pElem->rDx = 1.0 / pElem->dx;    pElem->epsRel /= EpsNorm;    for (index = 0; index <= 1; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	pNode->netConc /= NNorm;	pNode->nd /= NNorm;	pNode->na /= NNorm;	pNode->qf /= (NNorm * LNorm);	pNode->nie /= NNorm;	pNode->eg /= VNorm;	pNode->eaff /= VNorm;      }    }  }}

⌨️ 快捷键说明

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