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

📄 dopset.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1991 Regents of the University of California.  All rights reserved.Author:	1991 David A. Gates, U. C. Berkeley CAD Group**********/#include "spice.h"#include <stdio.h>#include <math.h>#include "const.h"#include "util.h"#include "cktdefs.h"#include "nummacs.h"#include "numenum.h"#include "dopdefs.h"#include "meshext.h"#include "profile.h"#include "gendev.h"#include "sperror.h"#include "suffix.h"#ifdef __STDC__extern int DOPcheck( DOPcard *, MESHcoord *, MESHcoord * );extern int DOPsetup( DOPcard *, DOPprofile **, DOPtable **, MESHcoord *, MESHcoord * );#elseextern int DOPcheck();extern int DOPsetup();#endif /* STDC *//* * Name:	DOPcheck * Purpose:	checks a list of DOPcards for input errors * Formals:	cardList: the list to check * Returns:	OK/E_PRIVATE * Users:	 numerical device setup routines * Calls:	error message handler */intDOPcheck( cardList, xMeshList, yMeshList )DOPcard *cardList;MESHcoord *xMeshList;MESHcoord *yMeshList;{  register DOPcard *card;  int cardNum = 0;  int error = OK;  char ebuf[512];		/* error message buffer */  for ( card = cardList; card != NIL(DOPcard); card = card->DOPnextCard ) {    cardNum++;    if (!card->DOPdomainsGiven) {      card->DOPnumDomains = 0;      card->DOPdomains = NIL(int);    }    if (!card->DOPprofileTypeGiven) {      sprintf( ebuf,	  "doping card %d does not specify profile type",	  cardNum );      SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );      error = E_PRIVATE;    } else switch (card->DOPprofileType) {      case DOP_UNIF:	if (!card->DOPconcGiven) {	  sprintf( ebuf,	      "doping card %d needs conc of uniform distribution",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_LINEAR:	if (!card->DOPconcGiven) {	  sprintf( ebuf,	      "doping card %d needs peak conc of linear distribution",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_GAUSS:	if (!card->DOPconcGiven) {	  sprintf( ebuf,	      "doping card %d needs peak conc of gaussian distribution",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_ERFC:	if (!card->DOPconcGiven) {	  sprintf( ebuf,	      "doping card %d needs peak conc of error-function distribution",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_EXP:	if (!card->DOPconcGiven) {	  sprintf( ebuf,	      "doping card %d needs peak conc of exponential distribution",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_SUPREM3:      case DOP_SUPASCII:	if (!card->DOPinFileGiven) {	  sprintf( ebuf,	      "doping card %d needs input-file name of suprem3 data",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      case DOP_ASCII:	if (!card->DOPinFileGiven) {	  sprintf( ebuf,	      "doping card %d needs input-file name of ascii data",	      cardNum );	  SPfrontEnd->IFerror( ERR_WARNING, ebuf, NIL(IFuid) );	  error = E_PRIVATE;	}	break;      default:	sprintf( ebuf,	    "doping card %d has unrecognized profile type",	    cardNum );	SPfrontEnd->IFerror( ERR_FATAL, ebuf, NIL(IFuid) );	error = E_NOTFOUND;	break;    }    if (!card->DOProtateLatGiven) {      card->DOProtateLat = FALSE;    }    if (!card->DOPlatProfileTypeGiven || card->DOProtateLat) {      card->DOPlatProfileType = card->DOPprofileType;    }    if (!card->DOPratioLatGiven) {      card->DOPratioLat = 1.0;    }    if (!card->DOPcharLenGiven) {      card->DOPcharLen = 1.0e-4; 	/* 1um in centimeters */    }    if (!card->DOPlocationGiven) {      card->DOPlocation = 0.0;    }    if (!card->DOPimpurityTypeGiven) {      card->DOPimpurityType = IMP_N_TYPE;    } else switch (card->DOPimpurityType) {      case DOP_BORON:	card->DOPimpurityType = IMP_BORON;	break;      case DOP_PHOSP:	card->DOPimpurityType = IMP_PHOSPHORUS;	break;      case DOP_ARSEN:	card->DOPimpurityType = IMP_ARSENIC;	break;      case DOP_ANTIM:	card->DOPimpurityType = IMP_ANTIMONY;	break;      case DOP_N_TYPE:	card->DOPimpurityType = IMP_N_TYPE;	break;      case DOP_P_TYPE:	card->DOPimpurityType = IMP_P_TYPE;	break;      default:	break;    }    if (!card->DOPaxisTypeGiven) {      if ( xMeshList && yMeshList ) { /* both lists are non-empty */	card->DOPaxisType = DOP_Y_AXIS;      } else if ( xMeshList ) { /* x-mesh list is non-empty */	card->DOPaxisType = DOP_X_AXIS;      } else if ( yMeshList ) { /* y-mesh list is non-empty */	card->DOPaxisType = DOP_Y_AXIS;      }    }/* Return now if anything has failed */    if (error) return(error);  }  return(OK);}/* * Name:	DOPsetup * Purpose:	convert a list of DOPcard's to DOPprofile's * Formals:	cardList: list of cards to setup *		profileList: returns the list of DOPprofile's *		xMeshList: list of coordinates in the x mesh *		yMeshList: list of coordinates in the y mesh * Returns:	OK/E_PRIVATE * Users:	 numerical devices * Calls:	DOPcheck */intDOPsetup( cardList, profileList, tableList, xMeshList, yMeshList )DOPcard *cardList;DOPprofile **profileList;DOPtable **tableList;MESHcoord *xMeshList;MESHcoord *yMeshList;{  register DOPcard *card;  DOPprofile *newProfile, *endProfile;  int impurityId = 0;  double xMin, xMax, yMin, yMax;  double sign;  int error, xProfUnif, yProfUnif;/* Initialize list of profiles */  *profileList = endProfile = NIL(DOPprofile);/* Check the card list */  if (error = DOPcheck( cardList, xMeshList, yMeshList )) return( error );/* Find the limits on locations */  MESHlBounds( xMeshList, &xMin, &xMax );  MESHlBounds( yMeshList, &yMin, &yMax );  for ( card = cardList; card != NIL(DOPcard); card = card->DOPnextCard ) {    if (*profileList == NIL(DOPprofile)) {      RALLOC( newProfile, DOPprofile, 1 );      *profileList = newProfile;    }    else {      RALLOC( newProfile->next, DOPprofile, 1 );      newProfile = newProfile->next;    }    newProfile->next = NIL(DOPprofile);    newProfile->numDomains = card->DOPnumDomains;    if ( newProfile->numDomains > 0 ) {      int i;      RALLOC( newProfile->domains, int, newProfile->numDomains );      for ( i=0; i < newProfile->numDomains; i++ ) {	newProfile->domains[i] = card->DOPdomains[i];      }    }    else {      newProfile->domains = NIL(int);    }    if ( card->DOPimpurityType == IMP_P_TYPE ) {      sign = -1.0;    }    else {      sign = 1.0;    }    switch( card->DOPprofileType ) {      case DOP_UNIF:	newProfile->type = UNIF;	newProfile->CONC = sign * card->DOPconc;	break;      case DOP_LINEAR:	newProfile->type = LIN;	newProfile->CONC = sign * card->DOPconc;	break;      case DOP_GAUSS:	newProfile->type = GAUSS;	newProfile->CONC = sign * card->DOPconc;	break;      case DOP_ERFC:	newProfile->type = ERRFC;	newProfile->CONC = sign * card->DOPconc;	break;      case DOP_EXP:	newProfile->type = EXP;	newProfile->CONC = sign * card->DOPconc;	break;      case DOP_SUPREM3:	newProfile->type = LOOKUP;	readSupremData( card->DOPinFile, 0, card->DOPimpurityType, tableList );	newProfile->IMPID = ++impurityId;	break;      case DOP_SUPASCII:	newProfile->type = LOOKUP;	readSupremData( card->DOPinFile, 1, card->DOPimpurityType, tableList );	newProfile->IMPID = ++impurityId;	break;      case DOP_ASCII:	newProfile->type = LOOKUP;	readAsciiData( card->DOPinFile, card->DOPimpurityType, tableList );	newProfile->IMPID = ++impurityId;	break;      default:	break;    }    switch( card->DOPlatProfileType ) {      case DOP_UNIF:	newProfile->latType = UNIF;	break;      case DOP_LINEAR:	newProfile->latType = LIN;	break;      case DOP_GAUSS:	newProfile->latType = GAUSS;	break;      case DOP_ERFC:	newProfile->latType = ERRFC;	break;      case DOP_EXP:	newProfile->latType = EXP;	break;      case DOP_SUPREM3:      case DOP_SUPASCII:	newProfile->latType = LOOKUP;	break;      case DOP_ASCII:	newProfile->latType = LOOKUP;	break;      default:	break;    }    newProfile->rotate = card->DOProtateLat;    newProfile->LOCATION = card->DOPlocation;    newProfile->CHAR_LENGTH = card->DOPcharLen;    newProfile->LAT_RATIO = card->DOPratioLat;    xProfUnif = yProfUnif = FALSE;    if (card->DOPaxisType == DOP_X_AXIS) {      newProfile->DIRECTION = X;      if (newProfile->type == UNIF) xProfUnif = TRUE;      if (newProfile->latType == UNIF) yProfUnif = TRUE;    }     else {      newProfile->DIRECTION = Y;      if (newProfile->type == UNIF) yProfUnif = TRUE;      if (newProfile->latType == UNIF) xProfUnif = TRUE;    }/* Fill in x coordinates.  Use defaults if necessary */    if (card->DOPxLowGiven && card->DOPxHighGiven) {      newProfile->X_LOW = card->DOPxLow;      newProfile->X_HIGH = card->DOPxHigh;    }    else if (card->DOPxLowGiven) {      newProfile->X_LOW = card->DOPxLow;      if (xProfUnif) {	newProfile->X_HIGH = xMax;      }      else {	newProfile->X_HIGH = newProfile->X_LOW;      }    }    else if (card->DOPxHighGiven) {      newProfile->X_HIGH = card->DOPxHigh;      if (xProfUnif) {	newProfile->X_LOW = xMin;      }      else {	newProfile->X_LOW = newProfile->X_HIGH;      }    }    else {      if (xProfUnif) {	newProfile->X_LOW = xMin;	newProfile->X_HIGH = xMax;      }      else {	newProfile->X_LOW = 0.5 * (xMin + xMax);	newProfile->X_HIGH = 0.5 * (xMin + xMax);      }    }/* Fill in y coordinates.  Use defaults if necessary */    if (card->DOPyLowGiven && card->DOPyHighGiven) {      newProfile->Y_LOW = card->DOPyLow;      newProfile->Y_HIGH = card->DOPyHigh;    }    else if (card->DOPyLowGiven) {      newProfile->Y_LOW = card->DOPyLow;      if (yProfUnif) {	newProfile->Y_HIGH = yMax;      }      else {	newProfile->Y_HIGH = newProfile->Y_LOW;      }    }    else if (card->DOPyHighGiven) {      newProfile->Y_HIGH = card->DOPyHigh;      if (xProfUnif) {	newProfile->Y_LOW = yMin;      }      else {	newProfile->Y_LOW = newProfile->Y_HIGH;      }    }    else {      if (yProfUnif) {	newProfile->Y_LOW = yMin;	newProfile->Y_HIGH = yMax;      }      else {	newProfile->Y_LOW = 0.5 * (yMin + yMax);	newProfile->Y_HIGH = 0.5 * (yMin + yMax);      }    }  }  return( OK );}

⌨️ 快捷键说明

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