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

📄 spiceif.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group**********//* * Interface routines. These are specific to spice. The only changes to FTE * that should be needed to make FTE work with a different simulator is * to rewrite this file. What each routine is expected to do can be * found in the programmer's manual. This file should be the only one * that includes spice header files. */#include "spice.h"#include "cpdefs.h"#include "ftedefs.h"#include "fteinp.h"#include "fteconst.h"#include "inpdefs.h"#include "iferrmsg.h"#include "ifsim.h"#include "util.h"#include "suffix.h"static IFvalue *doask();static int doset( );static int finddev();static IFparm * parmlookup();static struct variable *parmtovar();/* Input a single deck, and return a pointer to the circuit. */char *if_inpdeck(deck, tab)    struct line *deck;    INPtables **tab;{    GENERIC *ckt;    int err, i, j;    struct line *ll;    IFuid taskUid;    IFuid optUid;    int which = -1;    for (i = 0, ll = deck; ll; ll = ll->li_next)        i++;    *tab = INPtabInit(i);    ft_curckt->ci_symtab = *tab;    if ((err = (*(ft_sim->newCircuit))(&ckt))            != OK) {        ft_sperror(err, "CKTinit");        return (NULL);    }    err = IFnewUid(ckt,&taskUid,(IFuid)NULL,"default",UID_TASK,(GENERIC**)NULL);    if(err) {        ft_sperror(err,"newUid");        return(NULL);    }    err = (*(ft_sim->newTask))(ckt,(GENERIC**)&(ft_curckt->ci_defTask),taskUid);    if(err) {        ft_sperror(err,"newTask");        return(NULL);    }    for(j=0;j<ft_sim->numAnalyses;j++) {        if(strcmp(ft_sim->analyses[j]->name,"options")==0) {            which = j;            break;        }    }     if(which != -1) {        err = IFnewUid(ckt,&optUid,(IFuid)NULL,"options",UID_ANALYSIS,                (GENERIC**)NULL);        if(err) {            ft_sperror(err,"newUid");            return(NULL);        }        err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid,                (GENERIC**)&(ft_curckt->ci_defOpt),                (GENERIC*)ft_curckt->ci_defTask);        if(err) {            ft_sperror(err,"createOptions");            return(NULL);        }        ft_curckt->ci_curOpt  = ft_curckt->ci_defOpt;    }    ft_curckt->ci_curTask = ft_curckt->ci_defTask;    INPpas1((GENERIC *) ckt, (card *) deck->li_next,(INPtables *)*tab);    INPpas2((GENERIC *) ckt, (card *) deck->li_next,            (INPtables *) *tab,ft_curckt->ci_defTask);    INPkillMods();    return (ckt);}/* Do a run of the circuit, of the given type. Type "resume" is special -- * it means to resume whatever simulation that was in progress. The * return value of this routine is 0 if the exit was ok, and 1 if there was * a reason to interrupt the circuit (interrupt typed at the keyboard, * error in the simulation, etc). args should be the entire command line, * e.g. "tran 1 10 20 uic" */intif_run(t, what, args, tab)    char *t;    char *what;    wordlist *args;    char *tab;{    GENERIC *ckt = (GENERIC *) t;    int err;    struct line deck;    char buf[BSIZE_SP];    int j;    int which = -1;    IFuid specUid,optUid;    /* First parse the line... */    if (eq(what, "tran") || eq(what, "ac") || eq(what, "dc")            || eq(what, "op") || eq(what, "pz") || eq(what,"disto")            || eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf")	    || eq(what, "noise")) {        (void) sprintf(buf, ".%s", wl_flatten(args));        deck.li_next = deck.li_actual = NULL;        deck.li_error = NULL;        deck.li_linenum = 0;        deck.li_line = buf;        if(ft_curckt->ci_specTask) {            err=(*(ft_sim->deleteTask))(ft_curckt->ci_ckt,                    ft_curckt->ci_specTask);            if(err) {                ft_sperror(err,"deleteTask");                return(2);            }        }        err = IFnewUid(ft_curckt->ci_ckt,&specUid,(IFuid)NULL,"special",                UID_TASK,(GENERIC**)NULL);        if(err) {            ft_sperror(err,"newUid");            return(2);        }        err = (*(ft_sim->newTask))(ft_curckt->ci_ckt,                (GENERIC**)&(ft_curckt->ci_specTask),specUid);        if(err) {            ft_sperror(err,"newTask");            return(2);        }        for(j=0;j<ft_sim->numAnalyses;j++) {            if(strcmp(ft_sim->analyses[j]->name,"options")==0) {                which = j;                break;            }        }         if(which != -1) {            err = IFnewUid(ft_curckt->ci_ckt,&optUid,(IFuid)NULL,"options",                    UID_ANALYSIS,(GENERIC**)NULL);            if(err) {                ft_sperror(err,"newUid");                return(2);            }            err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid,                    (GENERIC**)&(ft_curckt->ci_specOpt),                    (GENERIC*)ft_curckt->ci_specTask);            if(err) {                ft_sperror(err,"createOptions");                return(2);            }            ft_curckt->ci_curOpt  = ft_curckt->ci_specOpt;        }        ft_curckt->ci_curTask = ft_curckt->ci_specTask;        INPpas2(ckt, (card *) &deck, (INPtables *)tab, ft_curckt->ci_specTask);        if (deck.li_error) {            fprintf(cp_err, "Warning: %s\n", deck.li_error);	    return 2;        }    }    if( eq(what,"run") ) {        ft_curckt->ci_curTask = ft_curckt->ci_defTask;        ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;    }    if (  (eq(what, "tran"))  ||          (eq(what, "ac"))  ||          (eq(what, "dc")) ||          (eq(what, "op")) ||          (eq(what, "pz")) ||          (eq(what, "disto")) ||          (eq(what, "noise")) ||            eq(what, "adjsen") || eq(what, "sens") || eq(what,"tf") ||          (eq(what, "run"))     )  {        if ((err = (*(ft_sim->doAnalyses))(ckt, 1, ft_curckt->ci_curTask))!=OK){            ft_sperror(err, "doAnalyses");            /* wrd_end(); */	    if (err == E_PAUSE)		return (1);	    else		return (2);        }    } else if (eq(what, "resume")) {        if ((err = (*(ft_sim->doAnalyses))(ckt, 0, ft_curckt->ci_curTask))!=OK){            ft_sperror(err, "doAnalyses");            /* wrd_end(); */	    if (err == E_PAUSE)		return (1);	    else		return (2);        }    } else {        fprintf(cp_err, "if_run: Internal Error: bad run type %s\n",                what);	return (2);    }    return (0);}/* Set an option in the circuit. Arguments are option name, type, and * value (the last a char *), suitable for casting to whatever needed... */static char *unsupported[] = {    "itl3",    "itl5",    "lvltim",    "maxord",    "method",    NULL} ;static char *obsolete[] = {    "limpts",    "limtim",    "lvlcod",    NULL} ;intif_option(ckt, name, type, value)    char *ckt;    char *name;    int type;    char *value;{    IFvalue pval;    int err, i;    GENERIC *cc = (GENERIC *) ckt;    char **vv;    int which = -1;    if (eq(name, "acct")) {        ft_acctprint = true;	return 0;    } else if (eq(name, "list")) {        ft_listprint = true;	return 0;    } else if (eq(name, "node")) {        ft_nodesprint = true;	return 0;    } else if (eq(name, "opts")) {        ft_optsprint = true;	return 0;    } else if (eq(name, "nopage")) {	ft_nopage = true;	return 0;    } else if (eq(name, "nomod")) {	ft_nomod = true;	return 0;    }    for(i=0;i<ft_sim->numAnalyses;i++) {        if(strcmp(ft_sim->analyses[i]->name,"options")==0) {            which = i;            break;        }    }    if(which==-1) {        fprintf(cp_err,"Warning:  .options line unsupported\n");        return 0;    }    for (i = 0; i < ft_sim->analyses[which]->numParms; i++)        if (eq(ft_sim->analyses[which]->analysisParms[i].keyword, name) &&                (ft_sim->analyses[which]->analysisParms[i].dataType & IF_SET))            break;    if (i == ft_sim->analyses[which]->numParms) {        /* See if this is unsupported or obsolete. */        for (vv = unsupported; *vv; vv++)            if (eq(name, *vv)) {                fprintf(cp_err,             "Warning: option %s is currently unsupported.\n", name);                return 1;            }        for (vv = obsolete; *vv; vv++)            if (eq(name, *vv)) {                fprintf(cp_err,                 "Warning: option %s is obsolete.\n", name);                return 1;            }        return 0;    }    switch (ft_sim->analyses[which]->analysisParms[i].dataType & IF_VARTYPES) {        case IF_REAL:            if (type == VT_REAL)                pval.rValue = *((double *) value);            else if (type == VT_NUM)                pval.rValue = *((int *) value);            else                goto badtype;            break;        case IF_INTEGER:            if (type == VT_NUM)                pval.iValue = *((int *) value);            else if (type == VT_REAL)                pval.iValue = *((double *) value);            else                goto badtype;            break;        case IF_STRING:            if (type == VT_STRING)                pval.sValue = copy(value);            else                goto badtype;            break;        case IF_FLAG:            /* Do nothing. */            pval.iValue = *((int *) value);            break;        default:            fprintf(cp_err,             "if_option: Internal Error: bad option type %d.\n",                    ft_sim->analyses[which]->analysisParms[i].dataType);    }    if (!ckt) {	/* XXX No circuit loaded */	fprintf(cp_err, "Simulation parameter \"%s\" can't be set until\n",		name);	fprintf(cp_err, "a circuit has been loaded.\n");	return 1;    }    if ((err = (*(ft_sim->setAnalysisParm))(cc, (GENERIC *)ft_curckt->ci_curOpt,            ft_sim->analyses[which]->analysisParms[i].id, &pval,            (IFvalue *)NULL)) != OK)        ft_sperror(err, "setAnalysisParm(options)");    return 1;badtype:    fprintf(cp_err, "Error: bad type given for option %s --\n", name);    fprintf(cp_err, "\ttype given was ");    switch (type) {        case VT_BOOL:   fputs("boolean", cp_err); break;        case VT_NUM:    fputs("integer", cp_err); break;        case VT_REAL:   fputs("real", cp_err); break;        case VT_STRING: fputs("string", cp_err); break;        case VT_LIST:   fputs("list", cp_err); break;        default:    fputs("something strange", cp_err); break;    }    fprintf(cp_err, ", type expected was ");    switch(ft_sim->analyses[which]->analysisParms[i].dataType & IF_VARTYPES) {        case IF_REAL:   fputs("real.\n", cp_err); break;        case IF_INTEGER:fputs("integer.\n", cp_err); break;        case IF_STRING: fputs("string.\n", cp_err); break;        case IF_FLAG:   fputs("flag.\n", cp_err); break;        default:    fputs("something strange.\n", cp_err); break;    }    if (type == VT_BOOL)fputs("\t(Note that you must use an = to separate option name and value.)\n",                     cp_err);     return 0;}/* ARGSUSED */voidif_dump(ckt, file)    char *ckt;    FILE *file;{    /*GENERIC *cc = (GENERIC *) ckt;*/    fprintf(file,"diagnostic output dump unavailable.");    return;}voidif_cktfree(ckt, tab)    char *ckt;    char *tab;{    GENERIC *cc = (GENERIC *) ckt;    (*(ft_sim->deleteCircuit))(cc);    INPtabEnd((INPtables *) tab);    return;}/* Return a string describing an error code. *//* BLOW THIS AWAY.... */char *if_errstring(code)    int code;{    return (INPerror(code));}/* Get a parameter value from the circuit. If name is left unspecified, * we want a circuit parameter. */struct variable *spif_getparam(ckt, name, param, ind, do_model)    char *ckt;    char **name;    char *param;    int ind;    int do_model;{    struct variable *vv = NULL, *tv;    IFvalue *pv;    IFparm *opt;    int typecode, i;    GENinstance *dev=(GENinstance *)NULL;    GENmodel *mod=(GENmodel *)NULL;    IFdevice *device;    /* fprintf(cp_err, "Calling if_getparam(%s, %s)\n", *name, param); */    if (param && eq(param, "all")) {        INPretrieve(name,(INPtables *)ft_curckt->ci_symtab);        typecode = finddev(ckt, *name,(GENERIC**) &dev,(GENERIC**) &mod);        if (typecode == -1) {            fprintf(cp_err,                "Error: no such device or model name %s\n",                    *name);            return (NULL);        }        device = ft_sim->devices[typecode];        for (i = 0; i < *(device->numInstanceParms); i++) {            opt = &device->instanceParms[i];            if(opt->dataType & IF_REDUNDANT || !opt->description)		    continue;            if(!(opt->dataType & IF_ASK)) continue;            pv = doask(ckt, typecode, dev, mod, opt, ind);            if (pv) {                tv = parmtovar(pv, opt);                if (vv)                    tv->va_next = vv;                vv = tv;            } else                fprintf(cp_err,            "Internal Error: no parameter '%s' on device '%s'\n",                    device->instanceParms[i].keyword,                    device->name);        }        return (vv);    } else if (param) {        INPretrieve(name,(INPtables *)ft_curckt->ci_symtab);        typecode = finddev(ckt, *name, (GENERIC**)&dev, (GENERIC**)&mod);        if (typecode == -1) {            fprintf(cp_err,                "Error: no such device or model name %s\n",                    *name);

⌨️ 快捷键说明

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