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

📄 onecont.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	*(pNode->fPN) += dx * pNode->dUdN;      }      pNode1 = pElem->pRightNode;      if (pNode1->nodeType ISNOT CONTACT) {	*(pNode->fPsiPsiiP1) -= rDx;	if (pElem->elemType IS SEMICON) {	  *(pNode->fNPsiiP1) += pEdge->dJnDpsiP1;	  *(pNode->fNNiP1) += pEdge->dJnDnP1;	  *(pNode->fPPsiiP1) += pEdge->dJpDpsiP1;	  *(pNode->fPPiP1) += pEdge->dJpDpP1;	}      }    }    pNode = pElem->pRightNode;    if (pNode->nodeType ISNOT CONTACT) {      pEdge = pElem->pEdge;      dPsi = pEdge->dPsi;      if (pElem->elemType IS SEMICON) {	*(pNode->fNN) += -pEdge->dJnDnP1 - dx * pNode->dUdN;	*(pNode->fNP) -= dx * pNode->dUdP;	*(pNode->fPP) += -pEdge->dJpDpP1 + dx * pNode->dUdP;	*(pNode->fPN) += dx * pNode->dUdN;      }      pNode1 = pElem->pLeftNode;      if (pNode1->nodeType ISNOT CONTACT) {	*(pNode->fPsiPsiiM1) -= rDx;	if (pElem->elemType IS SEMICON) {	  *(pNode->fNPsiiM1) += pEdge->dJnDpsiP1;	  *(pNode->fNNiM1) -= pEdge->dJnDn;	  *(pNode->fPPsiiM1) += pEdge->dJpDpsiP1;	  *(pNode->fPPiM1) -= pEdge->dJpDp;	}      }    }  }  if (AvalancheGen) {    /* add the generation terms */    for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {      pElem = pDevice->elemArray[eIndex];      for (index = 0; index <= 1; index++) {	if (pElem->evalNodes[index]) {	  pNode = pElem->pNodes[index];	  if (pNode->nodeType ISNOT CONTACT AND pElem->elemType IS SEMICON) {	    generation = ONEavalanche(FALSE, pDevice, pNode);	  }	}      }    }  }}void ONE_rhsLoad(pDevice, tranAnalysis, info)  ONEdevice *pDevice;  BOOLEAN tranAnalysis;  ONEtranInfo *info;{  ONEelem *pElem;  ONEnode *pNode, *pNode1;  ONEedge *pEdge;  int index, eIndex;  double *pRhs = pDevice->rhs;  double dx, rDx, dPsi;  double rhsN, rhsP, generation;  double perTime;  double fNd, fNa, fdNd, fdNa;  double netConc, dNd, dNa, psi, nConc, pConc;  /* first compute the currents and their derivatives */  ONE_commonTerms(pDevice, FALSE, tranAnalysis, info);  /* find reciprocal timestep */  if (tranAnalysis) {    perTime = info->intCoeff[0];  }  /* zero the rhs vector */  for (index = 1; index <= pDevice->numEqns; index++) {    pRhs[index] = 0.0;  }  for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {    pElem = pDevice->elemArray[eIndex];    dx = 0.5 * pElem->dx;    rDx = pElem->epsRel * pElem->rDx;    /* load for all i */    for (index = 0; index <= 1; index++) {      pNode = pElem->pNodes[index];      if (pNode->nodeType ISNOT CONTACT) {	pRhs[pNode->psiEqn] += pNode->qf;	if (pElem->elemType IS SEMICON) {	  pEdge = pElem->pEdge;	  netConc = pNode->netConc;	  dNd = 0.0;	  dNa = 0.0;	  psi = *(pDevice->devState0 + pNode->nodePsi);	  nConc = *(pDevice->devState0 + pNode->nodeN);	  pConc = *(pDevice->devState0 + pNode->nodeP);	  if (FreezeOut) {	    ONE_freezeOut(pNode, nConc, pConc, &fNd, &fNa, &fdNd, &fdNa);	    netConc = pNode->nd * fNd - pNode->na * fNa;	    dNd = pNode->nd * fdNd;	    dNa = pNode->na * fdNa;	  }	  pRhs[pNode->psiEqn] += dx * (netConc + pConc - nConc);	  /* Handle generation terms */	  pRhs[pNode->nEqn] -= -dx * pNode->uNet;	  pRhs[pNode->pEqn] -= dx * pNode->uNet;	  /* Handle dXdT continuity terms */	  if (tranAnalysis) {	    pRhs[pNode->nEqn] += dx * pNode->dNdT;	    pRhs[pNode->pEqn] -= dx * pNode->dPdT;	  }	  /* Take care of base contact if necessary */	  /* eg holds the base edge mu/dx */	  if (pNode->baseType IS N_TYPE) {	    pRhs[pNode->nEqn] += 0.5 * pNode->eg * nConc *		(pNode->vbe - psi + log(nConc / pNode->nie));	  } else if (pNode->baseType IS P_TYPE) {	    pRhs[pNode->pEqn] += 0.5 * pNode->eg * pConc *		(pNode->vbe - psi - log(pConc / pNode->nie));	  }	}      }    }    pEdge = pElem->pEdge;    dPsi = pEdge->dPsi;    pNode = pElem->pLeftNode;    if (pNode->nodeType ISNOT CONTACT) {      pRhs[pNode->psiEqn] += rDx * dPsi;      if (pElem->elemType IS SEMICON) {	pRhs[pNode->nEqn] -= pEdge->jn;	pRhs[pNode->pEqn] -= pEdge->jp;      }    }    pNode = pElem->pRightNode;    if (pNode->nodeType ISNOT CONTACT) {      pRhs[pNode->psiEqn] -= rDx * dPsi;      if (pElem->elemType IS SEMICON) {	pRhs[pNode->nEqn] += pEdge->jn;	pRhs[pNode->pEqn] += pEdge->jp;      }    }  }  if (AvalancheGen) {    /* add the generation terms */    for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {      pElem = pDevice->elemArray[eIndex];      for (index = 0; index <= 1; index++) {	if (pElem->evalNodes[index]) {	  pNode = pElem->pNodes[index];	  if (pNode->nodeType ISNOT CONTACT AND pElem->elemType IS SEMICON) {	    generation = ONEavalanche(TRUE, pDevice, pNode);	    pRhs[pNode->nEqn] -= generation;	    pRhs[pNode->pEqn] += generation;	  }	}      }    }  }}void ONE_commonTerms(pDevice, currentOnly, tranAnalysis, info)  ONEdevice *pDevice;  BOOLEAN currentOnly, tranAnalysis;  ONEtranInfo *info;{  ONEelem *pElem;  ONEedge *pEdge;  ONEnode *pNode, *pNode1;  int index, eIndex;  double psi1, psi2, psi, nConc, pConc, nC, pC, nP1, pP1;  double dPsiN, dPsiP;  double bPsiN, dbPsiN, bMPsiN, dbMPsiN;  double bPsiP, dbPsiP, bMPsiP, dbMPsiP;  double mun, dMun, mup, dMup, rDx;  double conc1, conc2;  double cnAug, cpAug;  /* evaluate all node (including recombination) and edge quantities */  for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {    pElem = pDevice->elemArray[eIndex];    cnAug = pElem->matlInfo->cAug[ELEC];    cpAug = pElem->matlInfo->cAug[HOLE];    for (index = 0; index <= 1; index++) {      if (pElem->evalNodes[index]) {	pNode = pElem->pNodes[index];	if (pNode->nodeType ISNOT CONTACT) {	  psi = pDevice->dcSolution[pNode->psiEqn];	  if (pElem->elemType IS SEMICON) {	    nConc = pDevice->dcSolution[pNode->nEqn];	    pConc = pDevice->dcSolution[pNode->pEqn];	    if (Srh) {	      recomb(nConc, pConc,		  pNode->tn, pNode->tp, cnAug, cpAug, pNode->nie,		  &pNode->uNet, &pNode->dUdN, &pNode->dUdP);	    } else {	      pNode->uNet = 0.0;	      pNode->dUdN = 0.0;	      pNode->dUdP = 0.0;	    }	    if (pNode->baseType IS P_TYPE AND pConc <= 0.0) {	      pConc = pNode->na;	    } else if (pNode->baseType IS N_TYPE AND nConc <= 0.0) {	      nConc = pNode->nd;	    }	  }	} else {	  /* a contact node */	  psi = pNode->psi;	  if (pElem->elemType IS SEMICON) {	    nConc = pNode->nConc;	    pConc = pNode->pConc;	  }	}	/* store info in the state tables */	*(pDevice->devState0 + pNode->nodePsi) = psi;	if (pElem->elemType IS SEMICON) {	  *(pDevice->devState0 + pNode->nodeN) = nConc;	  *(pDevice->devState0 + pNode->nodeP) = pConc;	  if (tranAnalysis AND pNode->nodeType ISNOT CONTACT) {	    pNode->dNdT = integrate(pDevice->devStates, info, pNode->nodeN);	    pNode->dPdT = integrate(pDevice->devStates, info, pNode->nodeP);	  }	}      }    }    pEdge = pElem->pEdge;    pNode = pElem->pLeftNode;    if (pNode->nodeType ISNOT CONTACT) {      psi1 = pDevice->dcSolution[pNode->psiEqn];    } else {      psi1 = pNode->psi;    }    pNode = pElem->pRightNode;    if (pNode->nodeType ISNOT CONTACT) {      psi2 = pDevice->dcSolution[pNode->psiEqn];    } else {      psi2 = pNode->psi;    }    pEdge->dPsi = psi2 - psi1;    *(pDevice->devState0 + pEdge->edgeDpsi) = pEdge->dPsi;  }  /* calculate the current densities and mobility values */  for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) {    pElem = pDevice->elemArray[eIndex];    pEdge = pElem->pEdge;    if (pElem->elemType IS SEMICON) {      dPsiN = pEdge->dPsi + pEdge->dCBand;      dPsiP = pEdge->dPsi - pEdge->dVBand;      bernoulli(dPsiN, &bPsiN, &dbPsiN, &bMPsiN, &dbMPsiN, NOT currentOnly);      bernoulli(dPsiP, &bPsiP, &dbPsiP, &bMPsiP, &dbMPsiP, NOT currentOnly);      nC = *(pDevice->devState0 + pElem->pLeftNode->nodeN);      nP1 = *(pDevice->devState0 + pElem->pRightNode->nodeN);      pC = *(pDevice->devState0 + pElem->pLeftNode->nodeP);      pP1 = *(pDevice->devState0 + pElem->pRightNode->nodeP);      conc1 = pElem->pLeftNode->totalConc;      conc2 = pElem->pRightNode->totalConc;      pEdge->jn = (bPsiN * nP1 - bMPsiN * nC);      pEdge->jp = (bPsiP * pC - bMPsiP * pP1);      mun = pEdge->mun;      dMun = 0.0;      mup = pEdge->mup;      dMup = 0.0;      MOBfieldDep(pElem->matlInfo, ELEC, dPsiN * pElem->rDx, &mun, &dMun);      MOBfieldDep(pElem->matlInfo, HOLE, dPsiP * pElem->rDx, &mup, &dMup);      mun *= pElem->rDx;      dMun *= pElem->rDx * pElem->rDx;      mup *= pElem->rDx;      dMup *= pElem->rDx * pElem->rDx;      /*       * The base continuity equation makes use of mu/dx in eg. The base       * length has already been calculated and converted to normalized,       * reciprocal form during setup. The name should be changed, but that's       * a big hassle.       */      for (index = 0; index <= 1; index++) {	if (pElem->evalNodes[index]) {	  pNode = pElem->pNodes[index];	  if (pNode->baseType IS N_TYPE) {	    pNode->eg = pEdge->mun * pDevice->baseLength;	  } else if (pNode->baseType IS P_TYPE) {	    pNode->eg = pEdge->mup * pDevice->baseLength;	  }	}      }      pEdge->jn *= mun;      pEdge->jp *= mup;      if (NOT currentOnly) {	if (dMun IS 0.0) {	  pEdge->dJnDpsiP1 = mun * (dbPsiN * nP1 - dbMPsiN * nC);	} else {	  pEdge->dJnDpsiP1 = dMun * (bPsiN * nP1 - bMPsiN * nC)	      + mun * (dbPsiN * nP1 - dbMPsiN * nC);	}	pEdge->dJnDn = -mun * bMPsiN;	pEdge->dJnDnP1 = mun * bPsiN;	if (dMup IS 0.0) {	  pEdge->dJpDpsiP1 = mup * (dbPsiP * pC - dbMPsiP * pP1);	} else {	  pEdge->dJpDpsiP1 = dMup * (bPsiP * pC - bMPsiP * pP1)	      + mup * (dbPsiP * pC - dbMPsiP * pP1);	}	pEdge->dJpDp = mup * bPsiP;	pEdge->dJpDpP1 = -mup * bMPsiP;      }    }    if (tranAnalysis) {      pEdge->jd = -integrate(pDevice->devStates, info,	  pEdge->edgeDpsi) * pElem->rDx;    }  }}

⌨️ 快捷键说明

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