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

📄 noisean.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1987 Gary W. Ng**********/#include "spice.h"#include <stdio.h>#include "strext.h"#include "acdefs.h"#include "cktdefs.h"#include "fteconst.h"#include "iferrmsg.h"#include "noisedef.h"#include "sperror.h"#ifdef HAS_FLAT_INCLUDES#include "vsrcdefs.h"#include "isrcdefs.h"#else#include "vsrc/vsrcdefs.h"#include "isrc/isrcdefs.h"#endif#include "util.h"#include "suffix.h"intNOISEan (ckt, restart)CKTcircuit *ckt;int restart;{    register Ndata *data;    double realVal;    double imagVal;    int error;    int posOutNode;    int negOutNode;    int code;    int step;    register CKTnode *node;    IFuid freqUid;    char *inst;    double freqTol; /* tolerence parameter for finding final frequency; hack */    register NOISEAN *job = (NOISEAN*) (ckt->CKTcurJob);    static char *noacinput =    "noise input source has no AC value";    posOutNode = ((CKTnode*) (job->output))->number;    negOutNode = ((CKTnode*) (job->outputRef))->number;    /* see if the source specified is AC */    inst = NULL;    code = CKTtypelook("Vsource");    if (code != -1) {        error = CKTfndDev((GENERIC*)ckt,&code,&inst,                job->input, (GENERIC *)NULL, (IFuid)NULL);	if (!error && !((VSRCinstance *)inst)->VSRCacGiven) {	    errMsg = MALLOC(strlen(noacinput)+1);	    strcpy(errMsg,noacinput);	    return (E_NOACINPUT);	}    }    code = CKTtypelook("Isource");    if (code != -1 && inst==NULL) {        error = CKTfndDev((GENERIC*)ckt,&code,&inst,                job->input, (GENERIC *)NULL,(IFuid)NULL);        if (error) {	    /* XXX ??? */            (*(SPfrontEnd->IFerror))(ERR_WARNING,                    "Noise input source %s not in circuit",                    &job->input);		return (E_NOTFOUND);	    }	if (!((ISRCinstance *)inst)->ISRCacGiven) {	    errMsg = MALLOC(strlen(noacinput)+1);	    strcpy(errMsg,noacinput);	    return (E_NOACINPUT);	}    }    if ( (job->NsavFstp == 0) || restart) {	switch (job->NstpType) {        case DECADE:            job->NfreqDelta = exp(log(10.0)/                            job->NnumSteps);            break;        case OCTAVE:            job->NfreqDelta = exp(log(2.0)/	                    job->NnumSteps);            break;        case LINEAR:            job->NfreqDelta = (job->NstopFreq -                             job->NstartFreq)/			    (job->NnumSteps+1);            break;        default:            return(E_BADPARM);        }	/* error = DCop(ckt); */	error = CKTop(ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,		(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,		ckt->CKTdcMaxIter);	if (error) return(error);        data = (Ndata*)MALLOC(sizeof(Ndata));	step = 0;	data->freq = job->NstartFreq;	data->outNoiz = 0.0;	data->inNoise = 0.0;	/* the current front-end needs the namelist to be fully		declared before an OUTpBeginplot */	(*(SPfrontEnd->IFnewUid))((GENERIC *)ckt,&freqUid,(IFuid)NULL,		"frequency", UID_OTHER,(GENERIC **)NULL);	data->numPlots = 0;                /* we don't have any plots  yet */        error = CKTnoise(ckt,N_DENS,N_OPEN,data);        if (error) return(error);	/*	 * all names in the namelist have been declared. now start the	 * plot	 */	error = (*(SPfrontEnd->OUTpBeginPlot))(ckt,(GENERIC *)(ckt->CKTcurJob),	   "Noise Spectral Density Curves - (V^2 or A^2)/Hz",	   freqUid,IF_REAL,data->numPlots,data->namelist,IF_REAL,	   &(data->NplotPtr));	if (error) return(error);        if (job->NstpType != LINEAR) {	    (*(SPfrontEnd->OUTattributes))((GENERIC *)data->NplotPtr,NULL,		    OUT_SCALE_LOG, NULL);	}    } else {   /* we must have paused before.  pick up where we left off */	step = job->NsavFstp;	switch (job->NstpType) {	case DECADE:        case OCTAVE:	    data->freq = job->NstartFreq * exp (step *		     log (job->NfreqDelta));            break;                    case LINEAR:	    data->freq = job->NstartFreq + step *		     job->NfreqDelta;            break;        default:            return(E_BADPARM);        }	job->NsavFstp = 0;	data->outNoiz = job->NsavOnoise;	data->inNoise = job->NsavInoise;    }    switch (job->NstpType) {    case DECADE:    case OCTAVE:        freqTol = job->NfreqDelta * job->NstopFreq * ckt->CKTreltol;        break;    case LINEAR:        freqTol = job->NfreqDelta * ckt->CKTreltol;        break;    default:        return(E_BADPARM);    }    data->lstFreq = data->freq;    /* do the noise analysis over all frequencies */    while (data->freq <= job->NstopFreq + freqTol) {        if( (*(SPfrontEnd->IFpauseTest))() ) { 	    job->NsavFstp = step;   /* save our results */	    job->NsavOnoise = data->outNoiz; /* up until now     */	    job->NsavInoise = data->inNoise;	    return (E_PAUSE);        }	ckt->CKTomega = 2.0 * M_PI * data->freq;	ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC;	/*	 * solve the original AC system to get the transfer	 * function between the input and output	 */	NIacIter(ckt);	realVal = *((ckt->CKTrhsOld) + posOutNode)		- *((ckt->CKTrhsOld) + negOutNode);	imagVal = *((ckt->CKTirhsOld) + posOutNode)		- *((ckt->CKTirhsOld) + negOutNode);	data->GainSqInv = 1.0 / MAX(((realVal*realVal)		+ (imagVal*imagVal)),N_MINGAIN);	data->lnGainInv = log(data->GainSqInv);	/* set up a block of "common" data so we don't have to	 * recalculate it for every device	 */	data->delFreq = data->freq - data->lstFreq;	data->lnFreq = log(MAX(data->freq,N_MINLOG));	data->lnLastFreq = log(MAX(data->lstFreq,N_MINLOG));        data->delLnFreq = data->lnFreq - data->lnLastFreq;	if ((job->NStpsSm != 0) && ((step % (job->NStpsSm)) == 0)) {	    data->prtSummary = TRUE;        } else {	    data->prtSummary = FALSE;        }	/*	data->outNumber = 1;       	*/	data->outNumber = 0;	/* the frequency will NOT be stored in array[0]  as before; instead,	 * it will be given in refVal.rValue (see later)	 */	NInzIter(ckt,posOutNode,negOutNode);   /* solve the adjoint system */	/* now we use the adjoint system to calculate the noise	 * contributions of each generator in the circuit	 */	error = CKTnoise(ckt,N_DENS,N_CALC,data);	if (error) return(error);	data->lstFreq = data->freq;	/* update the frequency */	switch (job->NstpType) {	case DECADE:	case OCTAVE:	    data->freq *= job->NfreqDelta;	    break;        case LINEAR:	    data->freq += job->NfreqDelta;	    break;        	default:	    return(E_INTERN);        }	step++;    }    error = CKTnoise(ckt,N_DENS,N_CLOSE,data);    if (error) return(error);    data->numPlots = 0;    data->outNumber = 0;    if (job->NstartFreq != job->NstopFreq) {	error = CKTnoise(ckt,INT_NOIZ,N_OPEN,data);	if (error) return(error);	(*(SPfrontEnd->OUTpBeginPlot))(ckt,(GENERIC *)(ckt->CKTcurJob),	       "Integrated Noise - V^2 or A^2",	       (IFuid)NULL,(int)0,data->numPlots,data->namelist,IF_REAL,	       &(data->NplotPtr));	error = CKTnoise(ckt,INT_NOIZ,N_CALC,data);	if (error) return(error);	error = CKTnoise(ckt,INT_NOIZ,N_CLOSE,data);	if (error) return(error);    }    FREE(data);    return(OK);}

⌨️ 快捷键说明

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