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

📄 spiceif.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 3 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD GroupModified: 2000 AlansFixes$Id: spiceif.c,v 1.18 2005/05/30 20:28:30 sjborley Exp $**********//* * 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 ngspice.header files. *//*CDHW Notes:I have never really understood the way Berkeley intended the six pointersto default values (ci_defOpt/Task  ci_specOpt/Task ci_curOpt/Task) to work,as there only see to be two data blocks to point at, or I've missed somethingclever elsewhere.Anyway, in the original 3f4 the interactive command 'set temp = 10'set temp for its current task and clobbered the default values as a sideeffect. When an interactive is run it created specTask using the spiceapplication default values, not the circuit defaults affectedby 'set temp = 10'.The fix involves two changes  1. Make 'set temp = 10' change the values in the 'default' block, not whatever     the 'current' pointer happens to be pointing at (which is usually the     default block except when one interactive is run immediately after another).  2. Hack CKTnewTask() so that it looks to see whether it is creating a 'special'     task, in which case it copies the values from ft_curckt->ci_defTask providing     everything looks sane, otherwise it uses the hard-coded 'application defaults'.These are fairly minor changes, and as they don't change the data structuresthey should be fairly 'safe'. However, ...CDHW*/#include "ngspice.h"#include "cpdefs.h"#include "tskdefs.h" /* Is really needed ? */#include "ftedefs.h"#include "fteinp.h"#include "inpdefs.h"#include "iferrmsg.h"#include "ifsim.h"#include "circuits.h"#include "spiceif.h"#include "variable.h"#ifdef XSPICE/* gtri - add - wbk - 11/9/90 - include MIF function prototypes */#include "mifproto.h"/* gtri - end - wbk - 11/9/90 *//* gtri - evt - wbk - 5/20/91 - Add stuff for user-defined nodes */#include "evtproto.h"#include "evtudn.h"/* gtri - end - wbk - 5/20/91 - Add stuff for user-defined nodes */#endif/* static declarations */static struct variable * parmtovar(IFvalue *pv, IFparm *opt);static IFparm * parmlookup(IFdevice *dev, GENinstance **inptr, char *param, 			   int do_model, int inout);static IFvalue * doask(void *ckt, int typecode, GENinstance *dev, GENmodel *mod, 		       IFparm *opt, int ind);static int doset(void *ckt, int typecode, GENinstance *dev, GENmodel *mod, 		 IFparm *opt, struct dvec *val);static int finddev(void *ck, char *name, void **devptr, void **modptr);/* Input a single deck, and return a pointer to the circuit. */char *if_inpdeck(struct line *deck, INPtables **tab){    void *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;    err = (*(ft_sim->newCircuit))(&ckt);    if (err != OK) {        ft_sperror(err, "CKTinit");        return (NULL);    }/*CDHW Create a task DDD with a new UID. ci_defTask will point to it CDHW*/    err = IFnewUid(ckt,&taskUid,(IFuid)NULL,"default",UID_TASK,(void**)NULL);    if(err) {        ft_sperror(err,"newUid");        return(NULL);    }#if (0)       err =      (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid);#else /*CDHW*/       err =        (*(ft_sim->newTask))(ckt,(void**)&(ft_curckt->ci_defTask),taskUid,       (void**)NULL);#endif    if(err) {        ft_sperror(err,"newTask");        return(NULL);    }/*CDHW which options available for this simulator? CDHW*/    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,                (void**)NULL);        if(err) {            ft_sperror(err,"newUid");            return(NULL);        }        err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid,                (void**)&(ft_curckt->ci_defOpt),                (void*)ft_curckt->ci_defTask);		/*CDHW ci_defTask and ci_defOpt point to parameters DDD CDHW*/				        if(err) {            ft_sperror(err,"createOptions");            return(NULL);        }        ft_curckt->ci_curOpt  = ft_curckt->ci_defOpt;/*CDHW ci_curOpt and ci_defOpt point to DDD CDHW*/    }    ft_curckt->ci_curTask = ft_curckt->ci_defTask;        INPpas1((void *) ckt, (card *) deck->li_next,(INPtables *)*tab);    INPpas2((void *) ckt, (card *) deck->li_next,            (INPtables *) *tab,ft_curckt->ci_defTask);    INPkillMods();    /* INPpas2 has been modified to ignore .NODESET and .IC     * cards. These are left till INPpas3 so that we can check for     * nodeset/ic of non-existant nodes.  */    INPpas3((void *) ckt, (card *) deck->li_next,            (INPtables *) *tab,ft_curckt->ci_defTask, ft_sim->nodeParms,	    ft_sim->numNodeParms);#ifdef XSPICE/* gtri - begin - wbk - 6/6/91 - Finish initialization of event driven structures */    err = EVTinit((void *) ckt);    if(err) {        ft_sperror(err,"EVTinit");        return(NULL);    }/* gtri - end - wbk - 6/6/91 - Finish initialization of event driven structures */#endif    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(char *t, char *what, wordlist *args, char *tab){    void *ckt = (void *) t;    int err;    struct line deck;    char buf[BSIZE_SP];    int j;    int which = -1;    IFuid specUid,optUid;    char *s;            /* First parse the line... */    /*CDHW Look for an interactive task CDHW*/    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"))     {    	s = wl_flatten(args); /* va: tfree char's tmalloc'ed in wl_flatten */        (void) sprintf(buf, ".%s", s);        tfree(s);              deck.li_next = deck.li_actual = NULL;        deck.li_error = NULL;        deck.li_linenum = 0;        deck.li_line = buf;        /*CDHW Delete any previous special task CDHW*/	        if(ft_curckt->ci_specTask) {	   if (ft_curckt->ci_specTask == ft_curckt->ci_defTask) { /*CDHW*/              printf("Oh dear...something bad has happened to the options.\n");            }            err=(*(ft_sim->deleteTask))(ft_curckt->ci_ckt,                    ft_curckt->ci_specTask);            if(err) {                ft_sperror(err,"deleteTask");                return(2);            }	    ft_curckt->ci_specTask = ft_curckt->ci_specOpt = NULL; /*CDHW*/        }       /*CDHW Create an interactive task AAA with a new UID.  ci_specTask will point to it CDHW*/	        err = IFnewUid(ft_curckt->ci_ckt,&specUid,(IFuid)NULL,"special",                UID_TASK,(void**)NULL);        if(err) {            ft_sperror(err,"newUid");            return(2);        }#if (0)        err = (*(ft_sim->newTask))(ft_curckt->ci_ckt,                 (void**)&(ft_curckt->ci_specTask),specUid);#else /*CDHW*/        err = (*(ft_sim->newTask))(ft_curckt->ci_ckt,                  (void**)&(ft_curckt->ci_specTask),                 specUid,(void**)&(ft_curckt->ci_defTask));#endif                if(err) {            ft_sperror(err,"newTask");            return(2);        }/*CDHW which options available for this simulator? CDHW*/                   for(j=0;j<ft_sim->numAnalyses;j++) {            if(strcmp(ft_sim->analyses[j]->name,"options")==0) {                which = j;                break;            }        }         if(which != -1) { /*CDHW options are available CDHW*/            err = IFnewUid(ft_curckt->ci_ckt,&optUid,(IFuid)NULL,"options",                    UID_ANALYSIS,(void**)NULL);            if(err) {                ft_sperror(err,"newUid");                return(2);            }            err = (*(ft_sim->newAnalysis))(ft_curckt->ci_ckt,which,optUid,                    (void**)&(ft_curckt->ci_specOpt),                    (void*)ft_curckt->ci_specTask);		    /*CDHW 'options' ci_specOpt points to AAA in this case CDHW*/		    		                if(err) {                ft_sperror(err,"createOptions");                return(2);            }	                ft_curckt->ci_curOpt  = ft_curckt->ci_specOpt;/*CDHW ci_specTask ci_specOpt and ci_curOpt all point to AAA CDHW*/		        	}	        ft_curckt->ci_curTask = ft_curckt->ci_specTask;/*CDHW ci_curTask and ci_specTask point to the interactive task AAA CDHW*/                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;        }    }     /*CDHW     ** if the task is to 'run' the deck, change ci_curTask and          ** ci_curOpt to point to DDD     ** created by if_inpdeck(), otherwise they point to AAA.     CDHW*/        if( eq(what,"run") ) {        ft_curckt->ci_curTask = ft_curckt->ci_defTask;        ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;    }/* -- Find out what we are supposed to do.              */    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"))  )  {	/*CDHW Run the analysis pointed to by ci_curTask CDHW*/        ft_curckt->ci_curOpt = ft_curckt->ci_defOpt;	        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(void *ckt, char *name, int type, char *value){    IFvalue pval;    int err, i;    void *cc = (void *) 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);

⌨️ 快捷键说明

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