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

📄 outitf.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group **********//* * This module replaces the old "writedata" routines in nutmeg. * Unlike the writedata routines, the OUT routines are only called by * the simulator routines, and only call routines in nutmeg.  The rest * of nutmeg doesn't deal with OUT at all. */#include "spice.h"#include "misc.h"#include "cpdefs.h"#include "ftedefs.h"#include "ftedata.h"#include "fteconst.h"#include "inpdefs.h"        /* for INPtables */#include "ifsim.h"#include "jobdefs.h"#include "iferrmsg.h"#include "suffix.h"extern void gr_end_iplot();extern SPICEanalysis *analInfo[];#define DOUBLE_PRECISION    15typedef struct dataDesc {    char *name;     /* The name of the vector. */    int type;       /* The type. */    int	gtype;		/* default plot scale */    bool regular;       /* Is this given to us? */    int outIndex;       /* If regular then the index. */    char *specName;     /* The device name if special. */    char *specParamName;    /* The parameter name if special. */    int specIndex;      /* For sensitivity, if special. */    int specType;    GENERIC *specFast;    int refIndex;       /* The index of our ref vector. */    struct dvec *vec;} dataDesc;typedef struct runDesc {    GENERIC *analysis;    GENERIC *circuit;    char *name;    char *type;    int numData;    int refIndex;    dataDesc *data;    bool writeOut;    bool windowed;    bool binary;    struct plot *runPlot;    FILE *fp;    long pointPos;          /* where to write pointCount */    int pointCount;    int isComplex;    int windowCount;} runDesc;static int beginPlot();static int addDataDesc();static int addSpecialDesc();static void fileInit();static void fileInit_pass2( );static void fileStartPoint();static void fileAddRealValue();static void fileAddComplexValue();static void fileEndPoint();static void fileEnd();static void plotInit();static void plotAddRealValue();static void plotAddComplexValue();static void plotEnd();static bool parseSpecial();static bool name_eq();static bool getSpecial();static void freeRun();static bool shouldstop = false; /* Tell simulator to stop next time it asks. */static bool printinfo = false;	/* Print informational "error messages". *//* The two "begin plot" routines share all their internals... */intOUTpBeginPlot(circuitPtr, analysisPtr, analName, refName, refType,        numNames, dataNames, dataType, plotPtr)    GENERIC *circuitPtr;    GENERIC *analysisPtr;    IFuid analName;    IFuid refName;    int refType;    int numNames;    IFuid *dataNames;    int dataType;    GENERIC **plotPtr;{    char *name;#ifdef PARALLEL_ARCH    if (ARCHme != 0) return(OK);#endif /* PARALLEL_ARCH */    if (ft_curckt->ci_ckt == circuitPtr)      name = ft_curckt->ci_name;    else      name = "circuit name";    return (beginPlot(analysisPtr, circuitPtr, name,            (char *) analName, (char *) refName, refType, numNames,            (char **) dataNames, dataType, false,            (runDesc **) plotPtr));}intOUTwBeginPlot(circuitPtr, analysisPtr, analName, refName, refType,        numNames, dataNames, dataType, plotPtr)    GENERIC *circuitPtr;    GENERIC *analysisPtr;    IFuid analName;    IFuid refName;    int refType;    int numNames;    IFuid *dataNames;    int dataType;    GENERIC **plotPtr;{#ifdef PARALLEL_ARCH    if (ARCHme != 0) return(OK);#endif /* PARALLEL_ARCH */    return (beginPlot(analysisPtr, circuitPtr, "circuit name",            (char *) analName, (char *) refName, refType, numNames,            (char **) dataNames, dataType, true,            (runDesc **) plotPtr));}static intbeginPlot(analysisPtr, circuitPtr, cktName, analName, refName, refType,        numNames, dataNames, dataType, windowed, runp)    GENERIC *analysisPtr;    GENERIC *circuitPtr;    char *cktName;    char *analName;    char *refName;    int refType;    int numNames;    char **dataNames;    int dataType;    bool windowed;    runDesc **runp;{    runDesc *run;    struct save_info *saves;    bool *savesused;    int numsaves;    int i, j, depind;    char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP];    bool saveall = true;    char *an_name;    /* Check to see if we want to print informational data. */    if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo))	fprintf(cp_err, "(debug printing enabled)\n");    *runp = run = alloc(struct runDesc);    /* First fill in some general information. */    run->analysis = analysisPtr;    run->circuit = circuitPtr;    run->name = copy(cktName);    run->type = copy(analName);    run->windowed = windowed;    run->numData = 0;    an_name = analInfo[((JOB *) analysisPtr)->JOBtype]->public.name;    /* Now let's see which of these things we need.  First toss in the     * reference vector.  Then toss in anything that getSaves() tells     * us to save that we can find in the name list.  Finally unpack     * the remaining saves into parameters.     */    numsaves = ft_getSaves(&saves);    if (numsaves) {        savesused = (bool *) tmalloc(sizeof (bool) * numsaves);        saveall = false;        for (i = 0; i < numsaves; i++) {            if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) {		/* ignore this one this time around */		savesused[i] = true;		continue;	    }	    if (cieq(saves[i].name, "all")) {                saveall = true;                savesused[i] = true;		saves[i].used = 1;                continue;            }	}    }    /* Pass 0. */    if (refName) {        addDataDesc(run, refName, refType, -1);        for (i = 0; i < numsaves; i++)            if (!savesused[i] && name_eq(saves[i].name, refName)) {                savesused[i] = true;		saves[i].used = 1;            }    } else {        run->refIndex = -1;    }    /* Pass 1. */    if (numsaves && !saveall) {        for (i = 0; i < numsaves; i++) {	    if (!savesused[i]) {		for (j = 0; j < numNames; j++) {		    if (name_eq(saves[i].name, dataNames[j])) {			addDataDesc(run, dataNames[j], dataType, j);			savesused[i] = true;			saves[i].used = 1;			break;		    }		}	    }        }    } else {        for (i = 0; i < numNames; i++)            if (!refName || !name_eq(dataNames[i], refName)) {                addDataDesc(run, dataNames[i], dataType, i);            }    }    /* Pass 2. */    for (i = 0; i < numsaves; i++) {        if (savesused[i])            continue;        if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) {	    if (saves[i].analysis)		fprintf(cp_err, "Warning: can't parse '%s': ignored\n",			saves[i].name);            continue;        }        /* Now, if there's a dep variable, do we already have it? */        if (*depbuf) {            for (j = 0; j < run->numData; j++)                if (name_eq(depbuf, run->data[j].name))                    break;            if (j == run->numData) {                /* Better add it. */                for (j = 0; j < numNames; j++)                    if (name_eq(depbuf, dataNames[j]))                        break;                if (j == numNames) {                    fprintf(cp_err,            "Warning: can't find '%s': value '%s' ignored\n",                        depbuf, saves[i].name);                    continue;                }                addDataDesc(run, dataNames[j], dataType, j);                savesused[i] = true;		saves[i].used = 1;                depind = j;            } else                depind = run->data[j].outIndex;        }        addSpecialDesc(run, saves[i].name, namebuf, parambuf, depind);    }    if (numsaves) {	for (i = 0; i < numsaves; i++) {	    tfree(saves[i].analysis);	    tfree(saves[i].name);	}        tfree(savesused);    }    if (numNames && (run->numData == 1 && run->refIndex != -1	    || run->numData == 0 && run->refIndex == -1))    {	fprintf(cp_err, "Error: no data saved for %s; analysis not run\n",	    analInfo[((JOB *) analysisPtr)->JOBtype]->public.description);	return E_NOTFOUND;    }        /* Now that we have our own data structures built up, let's see what     * nutmeg wants us to do.     */    run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary,            run->type, run->name);    if (run->writeOut)        fileInit(run);    else {        plotInit(run);	if (refName)	    run->runPlot->pl_ndims = 1;    }    return (OK);}static intaddDataDesc(run, name, type, ind)    runDesc *run;    char *name;    int type;    int ind;{    dataDesc *data;    if (!run->numData)        run->data = (dataDesc *) tmalloc(sizeof (dataDesc));    else        run->data = (dataDesc *) trealloc((char *) run->data,                sizeof (dataDesc) * (run->numData + 1));    data = &run->data[run->numData];    /* so freeRun will get nice NULL pointers for the fields we don't set */    bzero(data, sizeof(dataDesc));    data->name = copy(name);    data->type = type;    data->gtype = GRID_LIN;    data->regular = true;    data->outIndex = ind;    if (ind == -1) {        /* It's the reference vector. */        run->refIndex = run->numData;    }    run->numData++;    return (OK);}static intaddSpecialDesc(run, name, devname, param, depind)    runDesc *run;    char *name;    char *devname;    char *param;    int depind;{    dataDesc *data;    char *unique;       /* unique char * from back-end */    if (!run->numData)        run->data = (dataDesc *) tmalloc(sizeof (dataDesc));    else        run->data = (dataDesc *) trealloc((char *) run->data,                sizeof (dataDesc) * (run->numData + 1));    data = &run->data[run->numData];    /* so freeRun will get nice NULL pointers for the fields we don't set */    bzero(data, sizeof(dataDesc));    data->name = copy(name);    unique = devname;    INPinsert(&unique, (INPtables *) ft_curckt->ci_symtab);    data->specName = unique;    data->specParamName = copy(param);    data->specIndex = depind;    data->specType = -1;    data->specFast = NULL;    data->regular = false;    run->numData++;    return (OK);}intOUTpData(plotPtr, refValue, valuePtr)    GENERIC *plotPtr;    IFvalue *refValue;    IFvalue *valuePtr;{    runDesc *run = (runDesc *) plotPtr;    IFvalue val;    int i;#ifdef PARALLEL_ARCH    if (ARCHme != 0) return(OK);#endif /* PARALLEL_ARCH */    run->pointCount++;    if (run->writeOut) {	if (run->pointCount == 1)	    fileInit_pass2(plotPtr);        fileStartPoint(run->fp, run->binary, run->pointCount);        if (run->refIndex != -1) {          if (run->isComplex)            fileAddComplexValue(run->fp, run->binary, refValue->cValue);          else            fileAddRealValue(run->fp, run->binary, refValue->rValue);        }        for (i = 0; i < run->numData; i++) {            /* we've already printed reference vec first */            if (run->data[i].outIndex == -1) continue;            if (run->data[i].regular) {                if(run->data[i].type == IF_REAL)                  fileAddRealValue(run->fp, run->binary,                    valuePtr->v.vec.rVec                    [run->data[i].outIndex]);                else if (run->data[i].type == IF_COMPLEX)                  fileAddComplexValue(run->fp, run->binary,                    valuePtr->v.vec.cVec                    [run->data[i].outIndex]);                else                  fprintf(stderr, "OUTpData: unsupported data type\n");            } else {                /* should pre-check instance */                if (!getSpecial(&run->data[i], run, &val))                    continue;                if (run->data[i].type == IF_REAL)                  fileAddRealValue(run->fp, run->binary,                     val.rValue);                else if (run->data[i].type == IF_COMPLEX)                  fileAddComplexValue(run->fp, run->binary,                     val.cValue);                else                  fprintf(stderr, "OUTpData: unsupported data type\n");            }        }        fileEndPoint(run->fp, run->binary);    } else {        for (i = 0; i < run->numData; i++) {            if (run->data[i].outIndex == -1) {                if (run->data[i].type == IF_REAL)                    plotAddRealValue(&run->data[i],                            refValue->rValue);                else if (run->data[i].type == IF_COMPLEX)                    plotAddComplexValue(&run->data[i],                            refValue->cValue);            } else if (run->data[i].regular) {                if (run->data[i].type == IF_REAL)                    plotAddRealValue(&run->data[i],                        valuePtr->v.vec.rVec                        [run->data[i].outIndex]);                else if (run->data[i].type == IF_COMPLEX)                    plotAddComplexValue(&run->data[i],                        valuePtr->v.vec.cVec                        [run->data[i].outIndex]);            } else {                /* should pre-check instance */                if (!getSpecial(&run->data[i], run, &val))                    continue;                if (run->data[i].type == IF_REAL)                    plotAddRealValue(&run->data[i],                            val.rValue);                else if (run->data[i].type == IF_COMPLEX)                    plotAddComplexValue(&run->data[i],                            val.cValue);                else                     fprintf(stderr, "OUTpData: unsupported data type\n");            }        }        gr_iplot(run->runPlot);    }    if (ft_bpcheck(run->runPlot, run->pointCount) == false)        shouldstop = true;    return (OK);}/* ARGSUSED */ /* until some code gets written */intOUTwReference(plotPtr, valuePtr, refPtr)    GENERIC *plotPtr;    IFvalue *valuePtr;    GENERIC **refPtr;{    return (OK);}/* ARGSUSED */ /* until some code gets written */intOUTwData(plotPtr, dataIndex, valuePtr, refPtr)    GENERIC *plotPtr;    int dataIndex;    IFvalue *valuePtr;    GENERIC *refPtr;{    return (OK);}/* ARGSUSED */ /* until some code gets written */intOUTwEnd(plotPtr)    GENERIC *plotPtr;{    return (OK);}intOUTendPlot(plotPtr)    GENERIC *plotPtr;{    runDesc *run = (runDesc *) plotPtr;#ifdef PARALLEL_ARCH    if (ARCHme != 0) return(OK);#endif /* PARALLEL_ARCH */        if (run->writeOut)        fileEnd(run);    else {        gr_end_iplot();        plotEnd(run);    }    freeRun(run);

⌨️ 快捷键说明

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