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

📄 nummset.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1991 Regents of the University of California.  All rights reserved.Author:	1987 Kartikeya Mayaram, U. C. Berkeley CAD Group**********/#include "spice.h"#include <stdio.h>#include "util.h"#include "strext.h"#include "cktdefs.h"#include "smpdefs.h"#include "numosdef.h"#include "numconst.h"#include "numenum.h"#include "meshext.h"#include "sperror.h"#include "suffix.h"#define NIL(type)   ((type *)0)#define ALLOC(var, size, type)\if (size && (!(var =(type *)calloc(1, (unsigned)(size)*sizeof(type))))) {\   return(E_NOMEM);\}intNUMOSsetup(matrix, inModel, ckt, states)  register SMPmatrix *matrix;  GENmodel *inModel;  CKTcircuit *ckt;  int *states;/* * load the structure with those pointers needed later for fast matrix * loading */{  register NUMOSmodel *model = (NUMOSmodel *) inModel;  register NUMOSinstance *inst;  METHcard *methods;  MODLcard *models;  OPTNcard *options;  OUTPcard *outputs;  char *icFileName;  int nameLen;  int error, xIndex, yIndex;  int xMeshSize, yMeshSize;  TWOdevice *pDevice;  TWOcoord *xCoordList = NIL(TWOcoord);  TWOcoord *yCoordList = NIL(TWOcoord);  TWOdomain *domainList = NIL(TWOdomain);  TWOelectrode *electrodeList = NIL(TWOelectrode);  TWOmaterial *pM, *pMaterial, *materialList = NIL(TWOmaterial);  DOPprofile *profileList = NIL(DOPprofile);  DOPtable *dopTableList = NIL(DOPtable);  double startTime;  void printCoordInfo(), killCoordInfo();  void TWOprintDomainInfo(), killDomainInfo();  void TWOprintElectrodeInfo(), killElectrodeInfo();  void TWObuildMesh(), TWOgetStatePointers();  void checkElectrodes();  /* loop through all the models */  for (; model != NULL; model = model->NUMOSnextModel) {    if (!model->NUMOSpInfo) {      ALLOC(model->NUMOSpInfo, 1, TWOtranInfo);    }    methods = model->NUMOSmethods;    if (!methods) {      ALLOC(methods, 1, METHcard);      model->NUMOSmethods = methods;    }    models = model->NUMOSmodels;    if (!models) {      ALLOC(models, 1, MODLcard);      model->NUMOSmodels = models;    }    options = model->NUMOSoptions;    if (!options) {      ALLOC(options, 1, OPTNcard);      model->NUMOSoptions = options;    }    outputs = model->NUMOSoutputs;    if (!outputs) {      ALLOC(outputs, 1, OUTPcard);      model->NUMOSoutputs = outputs;    }    if (!methods->METHvoltPredGiven) {      methods->METHvoltPred = FALSE;    }    if (!methods->METHmobDerivGiven) {      methods->METHmobDeriv = TRUE;    }    if (!methods->METHoneCarrierGiven) {      methods->METHoneCarrier = FALSE;    }    if (!methods->METHacAnalysisMethodGiven) {      methods->METHacAnalysisMethod = SOR;    }    if (!methods->METHdabstolGiven) {      methods->METHdabstol = DABSTOL2D;    }    if (!methods->METHdreltolGiven) {      methods->METHdreltol = ckt->CKTreltol;    }    if (!methods->METHitLimGiven) {      methods->METHitLim = 50;    }    if (!methods->METHomegaGiven || methods->METHomega <= 0.0) {      methods->METHomega = 2.0 * M_PI /* radians/sec */ ;    }    if (!options->OPTNdefaGiven || options->OPTNdefa <= 0.0) {      options->OPTNdefa = 1.0e4 /* cm^2 */ ;    }    if (!options->OPTNdeflGiven || options->OPTNdefl <= 0.0) {      options->OPTNdefl = 1.0e2 /* cm */ ;    }    if (!options->OPTNdefwGiven && options->OPTNdefaGiven) {      options->OPTNdefw = options->OPTNdefa / options->OPTNdefl;    } else if (!options->OPTNdefwGiven || options->OPTNdefw <= 0.0) {      options->OPTNdefw = 1.0e2 /* cm */ ;    }    if (!options->OPTNdeviceTypeGiven) {      options->OPTNdeviceType = OPTN_MOSFET;    }    if (!options->OPTNicFileGiven) {      options->OPTNicFile = NULL;      options->OPTNunique = FALSE;		/* Can't form a unique name. */    }    if (!options->OPTNuniqueGiven) {      options->OPTNunique = FALSE;    }    OneCarrier = methods->METHoneCarrier;    /* Set up the rest of the card lists */    if (error = MODLsetup(model->NUMOSmodels))      return (error);    BandGapNarrowing = models->MODLbandGapNarrowing;    ConcDepLifetime = models->MODLconcDepLifetime;    TempDepMobility = models->MODLtempDepMobility;    ConcDepMobility = models->MODLconcDepMobility;    SurfaceMobility = models->MODLsurfaceMobility;    if (error = OUTPsetup(model->NUMOSoutputs))      return (error);    if (error = MATLsetup(model->NUMOSmaterials, &materialList))      return (error);    if (error = MOBsetup(model->NUMOSmobility, materialList))      return (error);    if (error = MESHsetup('x', model->NUMOSxMeshes, &xCoordList, &xMeshSize))      return (error);    if (error = MESHsetup('y', model->NUMOSyMeshes, &yCoordList, &yMeshSize))      return (error);    if (error = DOMNsetup(model->NUMOSdomains, &domainList,	    xCoordList, yCoordList, materialList))      return (error);    if (error = BDRYsetup(model->NUMOSboundaries,	    xCoordList, yCoordList, domainList))      return (error);    if (error = ELCTsetup(model->NUMOSelectrodes, &electrodeList,	    xCoordList, yCoordList))      return (error);    /* Make sure electrodes are OK. */    checkElectrodes(electrodeList, 4);	/* NUMOS has 4 electrodes */    if (error = CONTsetup(model->NUMOScontacts, electrodeList))      return (error);    if (error = DOPsetup(model->NUMOSdopings, &profileList,	    &dopTableList, xCoordList, yCoordList))      return (error);    model->NUMOSmatlInfo = materialList;    model->NUMOSprofiles = profileList;    model->NUMOSdopTables = dopTableList;    /* loop through all the instances of the model */    for (inst = model->NUMOSinstances; inst != NULL;	inst = inst->NUMOSnextInstance) {      if (inst->NUMOSowner != ARCHme) goto matrixpointers;      startTime = SPfrontEnd->IFseconds();      if (!inst->NUMOSprintGiven) {	inst->NUMOSprint = 0;      } else if (inst->NUMOSprint <= 0) {	inst->NUMOSprint = 1;      }      if (!inst->NUMOSicFileGiven) {	if (options->OPTNunique) {	  nameLen = strlen(options->OPTNicFile) + strlen(inst->NUMOSname) + 1;	  ALLOC(icFileName, nameLen+1, char);	  sprintf(icFileName, "%s.%s", options->OPTNicFile, inst->NUMOSname);	  icFileName[nameLen] = '\0';          inst->NUMOSicFile = icFileName;	} else if (options->OPTNicFile != NULL) {	  nameLen = strlen(options->OPTNicFile);	  ALLOC(icFileName, nameLen+1, char);	  icFileName = strcpy(icFileName, options->OPTNicFile);	  inst->NUMOSicFile = icFileName;	} else {	  inst->NUMOSicFile = NULL;	}      }      inst->NUMOSstate = *states;      *states += NUMOSnumStates;      if (!inst->NUMOSpDevice) {	/* Assign the mesh info to each instance. */	ALLOC(pDevice, 1, TWOdevice);	ALLOC(pDevice->pStats, 1, TWOstats);	pDevice->name = inst->NUMOSname;	pDevice->solverType = SLV_NONE;	pDevice->numXNodes = xMeshSize;	pDevice->numYNodes = yMeshSize;	pDevice->xScale = MESHmkArray(xCoordList, xMeshSize);	pDevice->yScale = MESHmkArray(yCoordList, yMeshSize);	pDevice->abstol = methods->METHdabstol;	pDevice->reltol = methods->METHdreltol;	ALLOC(pDevice->elemArray, pDevice->numXNodes, TWOelem **);	for (xIndex = 1; xIndex < pDevice->numXNodes; xIndex++) {	  ALLOC(pDevice->elemArray[xIndex], pDevice->numYNodes, TWOelem *);	}	/* Create a copy of material data that can change with temperature. */	pDevice->pMaterials = NIL(TWOmaterial);	for (pM = materialList; pM != NIL(TWOmaterial); pM = pM->next) {	  if (pDevice->pMaterials == NIL(TWOmaterial)) {	    ALLOC(pMaterial, 1, TWOmaterial);	    pDevice->pMaterials = pMaterial;	  } else {	    ALLOC(pMaterial->next, 1, TWOmaterial);	    pMaterial = pMaterial->next;	  }	  /* Copy everything, then fix the incorrect pointer. */	  bcopy((char *) pM, (char *) pMaterial, sizeof(TWOmaterial));	  pMaterial->next = NIL(TWOmaterial);	}	/* Generate the mesh structure for the device. */	TWObuildMesh(pDevice, domainList, electrodeList, pDevice->pMaterials);	/* Store the device info in the instance. */	inst->NUMOSpDevice = pDevice;      }      /* Now update the state pointers. */      TWOgetStatePointers(inst->NUMOSpDevice, states);      /* Wipe out statistics from previous runs (if any). */      bzero((char *) inst->NUMOSpDevice->pStats, sizeof(TWOstats));      inst->NUMOSpDevice->pStats->totalTime[STAT_SETUP] +=	  SPfrontEnd->IFseconds() - startTime;      /* macro to make elements with built in test for out of memory */#define TSTALLOC(ptr,first,second) \if ((inst->ptr = SMPmakeElt(matrix,inst->first,inst->second))==(double *)NULL){\  return(E_NOMEM);\}matrixpointers:      TSTALLOC(NUMOSdrainDrainPtr, NUMOSdrainNode, NUMOSdrainNode)      TSTALLOC(NUMOSdrainSourcePtr, NUMOSdrainNode, NUMOSsourceNode)      TSTALLOC(NUMOSdrainGatePtr, NUMOSdrainNode, NUMOSgateNode)      TSTALLOC(NUMOSdrainBulkPtr, NUMOSdrainNode, NUMOSbulkNode)      TSTALLOC(NUMOSsourceDrainPtr, NUMOSsourceNode, NUMOSdrainNode)      TSTALLOC(NUMOSsourceSourcePtr, NUMOSsourceNode, NUMOSsourceNode)      TSTALLOC(NUMOSsourceGatePtr, NUMOSsourceNode, NUMOSgateNode)      TSTALLOC(NUMOSsourceBulkPtr, NUMOSsourceNode, NUMOSbulkNode)      TSTALLOC(NUMOSgateDrainPtr, NUMOSgateNode, NUMOSdrainNode)      TSTALLOC(NUMOSgateSourcePtr, NUMOSgateNode, NUMOSsourceNode)      TSTALLOC(NUMOSgateGatePtr, NUMOSgateNode, NUMOSgateNode)      TSTALLOC(NUMOSgateBulkPtr, NUMOSgateNode, NUMOSbulkNode)      TSTALLOC(NUMOSbulkDrainPtr, NUMOSbulkNode, NUMOSdrainNode)      TSTALLOC(NUMOSbulkSourcePtr, NUMOSbulkNode, NUMOSsourceNode)      TSTALLOC(NUMOSbulkGatePtr, NUMOSbulkNode, NUMOSgateNode)      TSTALLOC(NUMOSbulkBulkPtr, NUMOSbulkNode, NUMOSbulkNode)    }    /* Clean up lists */    killCoordInfo(xCoordList);    killCoordInfo(yCoordList);    killDomainInfo(domainList);    killElectrodeInfo(electrodeList);  }  return (OK);}

⌨️ 快捷键说明

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