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

📄 subckt.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 5 页
字号:
 * finishLine now doesn't handle current or voltage sources. * Therefore, it just writes out the final netnames, if required. * Changes made by SDB on 4.29.2003. *-------------------------------------------------------------------*/static voidfinishLine(char *dst, char *src, char *scname){    char buf[4 * BSIZE_SP], which;    char *s;    int i;    int lastwasalpha;    lastwasalpha = 0;    while (*src) {        /* Find the next instance of "<non-alpha>[vi]<opt spaces>(" in         * this string.         */        if (((*src != 'v') && (*src != 'V') &&                (*src != 'i') && (*src != 'I')) ||		lastwasalpha) {	    lastwasalpha = isalpha(*src);            *dst++ = *src++;            continue;        }        for (s = src + 1; *s && isspace(*s); s++)            ;        if (!*s || (*s != '(')) {	    lastwasalpha = isalpha(*src);            *dst++ = *src++;            continue;        }	lastwasalpha = 0;        which = *dst++ = *src;        src = s;        *dst++ = *src++;        while (isspace(*src))            src++;        for (i = 0; *src && !isspace(*src) && *src != ',' && (*src != ')');	    i++)	{            buf[i] = *src++;	}        buf[i] = '\0';        if ((which == 'v') || (which == 'V'))            s = gettrans(buf);        else            s = NULL;        if (s) {            while (*s)                *dst++ = *s++;        } 	else {    /* just a normal netname . . . . */	    /*	     * 	     */             if ((which == 'i' || which == 'I') &&	        (buf[0] == 'v' || buf[0] == 'V')) {		*dst++ = buf[0];		*dst++ = ':';		i = 1;	    } else {		i = 0;	    }            for (s = scname; *s; )                *dst++ = *s++;            *dst++ = ':';            for (s = buf + i; *s; )                *dst++ = *s++;        }	/* translate the reference node, as in the "2" in "v(4,2)" */        if ((which == 'v') || (which == 'V')) {	    while (*src && (isspace(*src) || *src == ',')) {		src++;	    }	    if (*src && *src != ')') {		for (i = 0; *src && !isspace(*src) && (*src != ')'); i++)		    buf[i] = *src++;		buf[i] = '\0';		s = gettrans(buf);		*dst++ = ',';		if (s) {		    while (*s)			*dst++ = *s++;		} else {		    for (s = scname; *s; )			*dst++ = *s++;		    *dst++ = ':';		    for (s = buf; *s; )			*dst++ = *s++;		}	    }	}    }    *dst = '\0'; /* va, append in each case '\0' */    return;}/*------------------------------------------------------------------------------* * settrans builds the table which holds the old and new netnames.   * it also compares the number of nets present in the .subckt definition against * the number of nets present in the subcircuit invocation.  It returns 0 if they * match, otherwise, it returns an error. * * Variable definitions: * formal = copy of the .subckt definition line (e.g. ".subckt subcircuitname 1 2 3") (string) * actual = copy of the .subcircuit invocation line (e.g. "Xexample 4 5 6 subcircuitname") (string) * subname = copy of the subcircuit name  *------------------------------------------------------------------------------*/static intsettrans(char *formal, char *actual, char *subname){    int i;    bzero(table,sizeof(*table));        for (i = 0; ; i++) {        table[i].t_old = gettok(&formal);        table[i].t_new = gettok(&actual);        if (table[i].t_new == NULL) {	    return -1;		/* Too few actual / too many formal */        } else if (table[i].t_old == NULL) {	    if (eq(table[i].t_new, subname))		break;	    else		return 1;	/* Too many actual / too few formal */	}    }    return 0;}/*------------------------------------------------------------------------------* * gettrans returns the name of the top level net if it is in the list, * otherwise it returns NULL. *------------------------------------------------------------------------------*/static char *gettrans(char *name){    int i;#ifdef XSPICE    /* gtri - wbk - 2/27/91 - don't translate the reserved word 'null' */    if (eq(name, "null"))      return (name);    /* gtri - end */#endif/* Added by H.Tanaka to translate global nodes */#ifdef GLOBAL_NODE    for(i=0;i<numgnode;i++)	if(eq(node[i],name)) return (name);#endif /* GLOBAL_NODE */    if (eq(name, "0"))        return (name);    for (i = 0; table[i].t_old; i++)        if (eq(table[i].t_old, name))            return (table[i].t_new);    return (NULL);}/*-------------------------------------------------------------------*//*-------------------------------------------------------------------*/static intnumnodes(char *name){/* gtri - comment - wbk - 10/23/90 - Do not modify this routine for *//* 'A' type devices since the callers will not know how to find the *//* nodes even if they know how many there are.  Modify the callers  *//* instead.                                                         *//* gtri - end - wbk - 10/23/90 */    char c;    struct subs *sss;    char *s, *t, buf[4 * BSIZE_SP];    wordlist *wl;    int n, i, gotit;    while (*name && isspace(*name))	name++;    c = (isupper(*name) ? tolower(*name) : *name);    (void) strncpy(buf, name, sizeof(buf));    s = buf;    if (c == 'x') {     /* Handle this ourselves. */        while(*s)            s++;        s--;        while ((*s == ' ') || (*s == '\t'))            *s-- = '\0';        while ((*s != ' ') && (*s != '\t'))            s--;        s++;        for (sss = subs; sss; sss = sss->su_next)            if (eq(sss->su_name, s))                break;        if (!sss) {            fprintf(cp_err, "Error: no such subcircuit: %s\n", s);            return (0);        }        return (sss->su_numargs);    }    n = inp_numnodes(c);        /* Added this code for variable number of nodes on BSIM3SOI devices  */    /* The consequence of this code is that the value returned by the    */    /* inp_numnodes(c) call must be regarded as "maximum number of nodes */    /* for a given device type.                                          */    /* Paolo Nenzi Jan-2001                                              */        /* I hope that works, this code is very very untested */    	if (c=='m') {		     /* IF this is a mos */			        i = 0;		s = buf;		gotit = 0;		txfree(gettok(&s));	     /* Skip component name */		while ((i < n) && (*s) && !gotit) {		  t = gettok_node(&s);       /* get nodenames . . .  */		  for (wl = modnames; wl; wl = wl->wl_next)		    if (eq(t, wl->wl_word)) 		      gotit = 1;		  i++;		  tfree(t);		} /* while . . . . */				/* Note: node checks must be done on #_of_node-1 because the */		/* "while" cycle increments the counter even when a model is */		/* recognized. This code may be better!                      */	 				if (i < 5) {		  fprintf(cp_err, "Error: too few nodes for MOS: %s\n", name);		  return(0);		}		return(i-1); /* compensate the unnecessary increment in the while cycle */    	} /* if (c=='m' . . .  */        if (nobjthack || (c != 'q'))        return (n);    for (s = buf, i = 0; *s && (i < 4); i++)        txfree(gettok(&s));    if (i == 3)        return (3);    else if (i < 4) {        fprintf(cp_err, "Error: too few nodes for BJT: %s\n", name);        return (0);    }    /* Now, is this a model? */    t = gettok(&s);    for (wl = modnames; wl; wl = wl->wl_next)      if (eq(t, wl->wl_word)) {	  tfree(t);	  return (3);      }    tfree(t);    return (4);}/*-------------------------------------------------------------------* *  This function returns the number of controlling voltage sources *  (for F, H) or controlling nodes (for G, E)  attached to a dependent  *  source. *-------------------------------------------------------------------*/static int numdevs(char *s){  while (*s && isspace(*s))    s++;  switch (*s) {    case 'K':    case 'k':      return (2);          /* two nodes per voltage controlled source */    case 'G':    case 'g':    case 'E':    case 'e':      return(2);      /* one source per current controlled source */    case 'F':    case 'f':    case 'H':    case 'h':   /* 2 lines here added to fix w bug, NCF 1/31/95 */    case 'W':    case 'w':           return (1);            default:        return (0);    }}/*----------------------------------------------------------------------* *  modtranslate --  translates .model lines found in subckt definitions. *  Calling arguments are: *  *deck = pointer to the .subckt definition (linked list) *  *subname = pointer to the subcircuit name used at the subcircuit invocation (string) *  Modtranslate returns TRUE if it translated a model name, FALSE *  otherwise. *----------------------------------------------------------------------*/static boolmodtranslate(struct line *deck, char *subname){    struct line *c;    char *buffer, *name, *t, model[4 * BSIZE_SP];    wordlist *wl, *wlsub;    bool gotone;    (void) strcpy(model, ".model");    gotone = FALSE;    for (c = deck; c; c = c->li_next) {       /* iterate through model def . . . */        if (ciprefix(model, c->li_line)) {            gotone = TRUE;            t = c->li_line;#ifdef TRACE             /* SDB debug statement */             printf("In modtranslate, translating line %s\n", t);#endif	                name = gettok(&t);     /* at this point, name = .model */            buffer = tmalloc(strlen(name) + strlen(t) +                    strlen(subname) + 4);            (void) sprintf(buffer, "%s ",name);    /* at this point, buffer = ".model " */            tfree(name);            name = gettok(&t);                     /* name now holds model name */            wlsub = alloc(struct wordlist);            wlsub->wl_next = submod;            if (submod)                submod->wl_prev = wlsub;            /* here's where we insert the model name into the model name list */		            submod = wlsub;            wlsub->wl_word = name;#ifdef TRACE           /* SDB debug statement */           printf("In modtranslate, sticking model name %s into submod\n", wlsub->wl_word);#endif           /*  now stick the new model name into the model line.  */	                (void) sprintf(buffer + strlen(buffer), "%s:%s ",                     subname, name);                 /* buffer = "model subname:modelname " */            (void) strcat(buffer, t);            tfree(c->li_line);            c->li_line = buffer;#ifdef TRACE           /* SDB debug statement */           printf("In modtranslate, translated line= %s\n", c->li_line);#endif           /* this looks like it tries to stick the translated model name into the list of model names */	                t = c->li_line;            txfree(gettok(&t));            wl = alloc(struct wordlist);            wl->wl_next = modnames;            if (modnames)                 modnames->wl_prev = wl;            modnames = wl;            wl->wl_word = gettok(&t);#ifdef TRACE             /* SDB debug statement */             printf("In modtranslate, sticking model name %s into modnames\n", wl->wl_word);#endif

⌨️ 快捷键说明

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