📄 onedopng.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**********/#include <math.h>#include "numglobs.h"#include "numenum.h"#include "nummacs.h"#include "onemesh.h"#include "onedev.h"#include "profile.h"/* functions in this file are used to calculate the conc */double ONEdopingValue(pProfile, pTable, x) DOPprofile *pProfile; DOPtable *pTable; double x;{ double argX, argP, erfc(), lookup(), value; /* Find the appropriate lookup table if necessary */ if (pProfile->type == LOOKUP) { while (pTable ISNOT NIL(DOPtable)) { if (pTable->impId IS pProfile->IMPID) { /* Found it */ break; } else { pTable = pTable->next; } } if (pTable IS NIL(DOPtable)) { fprintf(stderr, "Error: unknown impurity profile %d\n", pProfile->IMPID); exit(1); } } /* Find distances */ if (pProfile->X_LOW > x) { argX = pProfile->X_LOW - x; } else if (x > pProfile->X_HIGH) { argX = x - pProfile->X_HIGH; } else { argX = 0.0; } argP = argX; /* Transform to coordinates of profile peak */ argP -= pProfile->LOCATION; argP /= pProfile->CHAR_LENGTH; switch (pProfile->type) { case UNIF: if (argP > 0.0) { value = 0.0; } else { value = pProfile->CONC; } break; case LIN: argP = ABS(argP); if (argP > 1.0) { value = 0.0; } else { value = pProfile->CONC * (1.0 - argP); } break; case GAUSS: argP *= argP; if (argP > 80.0) { value = 0.0; } else { value = pProfile->PEAK_CONC * exp(-argP); } case EXP: argP = ABS(argP); if (argP > 80.0) { value = 0.0; } else { value = pProfile->PEAK_CONC * exp(-argP); } break; case ERRFC: argP = ABS(argP); if (argP > 10.0) { value = 0.0; } else { value = pProfile->PEAK_CONC * erfc(-argP); } break; case LOOKUP: argP = ABS(argP); value = lookup(pTable->dopData, argP); break; default: break; } return (value);}void ONEsetDoping(pDevice, pProfile, pTable) ONEdevice *pDevice; DOPprofile *pProfile; DOPtable *pTable;{ ONEnode *pNode; ONEelem *pElem; DOPprofile *pP; double conc, ONEdopingValue(); int index, eIndex; BOOLEAN dopeMe; /* Clear doping info for all nodes. */ 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]; pNode->na = 0.0; pNode->nd = 0.0; pNode->netConc = 0.0; pNode->totalConc = 0.0; } } } /* Now compute the contribution to the total doping from each profile. */ for (pP = pProfile; pP != NIL(DOPprofile); pP = pP->next) { for (eIndex = 1; eIndex < pDevice->numNodes; eIndex++) { pElem = pDevice->elemArray[eIndex]; if (pElem->elemType IS SEMICON) { if (pP->numDomains > 0) { dopeMe = FALSE; for (index = 0; index < pP->numDomains; index++) { if (pElem->domain == pP->domains[index]) { dopeMe = TRUE; break; } } } else { /* domains not given, so dope all */ dopeMe = TRUE; } if (dopeMe) { for (index = 0; index <= 1; index++) { if (pElem->evalNodes[index]) { pNode = pElem->pNodes[index]; conc = ONEdopingValue(pP, pTable, pNode->x); pNode->netConc += conc; if (conc < 0.0) { pNode->totalConc -= conc; pNode->na -= conc; } else { pNode->totalConc += conc; pNode->nd += conc; } } } } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -