diff --git a/compile_macos_clang.sh b/compile_macos_clang.sh index a48cf4d16..491550f4f 100755 --- a/compile_macos_clang.sh +++ b/compile_macos_clang.sh @@ -52,14 +52,14 @@ if test "$1" = "d"; then # You may add --enable-adms to the following command for adding adms generated devices # Builtin readline is not compatible (Big Sur), readline via Homebrew required (in /usr/local/opt) # Standard clang does not support OpenMP - ../configure --with-x --enable-xspice --enable-cider --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" + ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline CFLAGS="-m64 -O0 -g -Wall -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include" LDFLAGS="-m64 -g -L/usr/local/opt/readline/lib -L/opt/X11/lib" else cd release if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi echo "configuring for 64 bit release" echo # You may add --enable-adms to the following command for adding adms generated devices - ../configure --with-x --enable-xspice --enable-cider --with-readline=/usr/local/opt/readline --disable-debug CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib" + ../configure --with-x --enable-xspice --enable-cider --enable-predictor --enable-osdi --enable-klu --with-readline=/usr/local/opt/readline --disable-debug CFLAGS="-m64 -O2 -I/opt/X11/include/freetype2 -I/usr/local/opt/readline/include -I/usr/local/opt/ncurses/include" LDFLAGS="-m64 -L/usr/local/opt/readline/lib -L/usr/local/opt/ncurses/lib -L/opt/X11/lib" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/examples/measure/meas_expression.cir b/examples/measure/meas_expression.cir new file mode 100644 index 000000000..4954477c4 --- /dev/null +++ b/examples/measure/meas_expression.cir @@ -0,0 +1,20 @@ +* measurement examples with evaluating an expression 0.9*v(2) +* transient simulation of two sine signals with different frequencies + +vac1 1 0 DC 0 sin(0 1 1.0k 0 0) +vac2 2 0 DC 0 sin(0 1.2 0.9k 0 0) + +.tran 10u 5m + +** evaluate '0.9*v(2)' in dot command +.measure tran yeval1 FIND v(2) WHEN v(1)=par('0.9*v(2)') + +.control +run +** evaluate '0.9*v(2)' in control language command +let vint = 0.9*v(2) +meas tran yeval2 FIND v(2) WHEN v(1)= vint +plot V(1) v(2) +.endc + +.end diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 7d2249a70..e2fdb6ed8 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -226,6 +226,36 @@ com_compose(wordlist *wl) } length *= blocksize; + } else if (eq(wl->wl_word, "device") && resname[0] == '@') { + /* Make vector(s) from device parameters; also works with models. */ + + result = vec_get(resname); + + /* With @dev[all] a chain of vectors is returned. */ + + while (result) { + char *cp; + + /* Change name so it is not an array reference. */ + + for (cp = result->v_name; cp && *cp; ++cp) { + if (*cp == '[') + *cp = '_'; + if (*cp == ']') { + *cp = '\0'; + break; + } + } + + /* Set dimension info */ + + result->v_numdims = 1; + result->v_dims[0] = length; + + result->v_flags |= VF_PERMANENT; + result = result->v_link2; + } + goto done; #ifdef XSPICE } else if (eq(wl->wl_word, "xspice")) { /* Make vectors from an event node. */ @@ -240,7 +270,6 @@ com_compose(wordlist *wl) result->v_scale->v_flags |= VF_PERMANENT; vec_new(result->v_scale); cp_addkword(CT_VECTOR, result->v_scale->v_name); - txfree(resname); // It was copied goto finished; #endif } else { diff --git a/src/frontend/com_fileio.c b/src/frontend/com_fileio.c index 078baa2c3..e795a324d 100644 --- a/src/frontend/com_fileio.c +++ b/src/frontend/com_fileio.c @@ -117,7 +117,7 @@ void com_fread(wordlist *wl) } if (fgets(buf, sizeof buf, Open_Files[fd].fp)) { - length = strlen(buf); + length = (int)strlen(buf); if (length > 0 && buf[length - 1] == '\n') { --length; if (length > 0 && buf[length - 1] == '\r') { diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index 1a4be8a97..04e6aabfd 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -57,7 +57,24 @@ typedef enum AnalysisType { static void measure_errMessage(const char *mName, const char *mFunction, const char *trigTarg, const char *errMsg, int chk_only); +/* like in string.c, here special without () */ +static bool +is_arith_char2(char c) +{ + return c != '\0' && strchr("*/<>?:|&^!%\\", c); +} +static bool +str_has_arith_char2(char* s) +{ + if (*s == '+' || *s == '-') + s++; + for (; *s; s++) + if (is_arith_char2(*s)) + return TRUE; + + return FALSE; +} /** return precision (either 5 or value of environment variable NGSPICE_MEAS_PRECISION) */ int @@ -466,7 +483,7 @@ com_measure_when( } /* 'dc' is special: it may start at an arbitrary scale value. - Use m_td to store this value, a delay TD does not make sense */ + Use m_td to store this value, as a delay TD does not make sense */ if (dc_check && (i == 0)) meas->m_td = scaleValue; /* if analysis tran, suppress values below TD */ @@ -1480,8 +1497,12 @@ measure_parse_when( if (cieq("ac", meas->m_analysis) || cieq("sp", meas->m_analysis)) correct_vec(meas); } else { - meas->m_val = INPevaluate(&pVar2, &err, 1); - if (err) { + if (str_has_arith_char2(pVar2)) { + snprintf(errBuf, 99, "Expressions like %s are not supported.\n", pVar2); + return MEASUREMENT_FAILURE; + } + meas->m_val = INPevaluate2(&pVar2, &err, 0); + if (err || (*pVar2 && (!strchr("avfc", *pVar2) || *(pVar2 + 1) != '\0'))) { snprintf(errBuf, 99, "Cannot evaluate %s \n", pVar2); return MEASUREMENT_FAILURE; } diff --git a/src/frontend/com_strcmp.c b/src/frontend/com_strcmp.c index 4663d59b3..6d179485e 100644 --- a/src/frontend/com_strcmp.c +++ b/src/frontend/com_strcmp.c @@ -36,11 +36,11 @@ void com_strstr(wordlist *wl) if (*s2) { var = strstr(s1, s2); // Search for s2 in s1 if (var) - i = var - s1; // Offset to match + i = (int)(var - s1); // Offset to match else i = -1; } else { - i = strlen(s1); // Length + i = (int)strlen(s1); // Length } tfree(s1); tfree(s2); @@ -58,7 +58,7 @@ void com_strslice(wordlist *wl) wl = wl->wl_next; offset = atoi(wl->wl_word); length = atoi(wl->wl_next->wl_word); - actual = strlen(s1); + actual = (int)strlen(s1); if (offset < 0) offset = actual + offset; if (length + offset > actual) diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index ec92c981c..a132b7580 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -265,63 +265,71 @@ ft_cpinit(void) wl_free(wl); } - /* Now source the standard startup file spinit or tclspinit. */ - - /* jump over leading spaces */ - for (copys = s = cp_tildexpand(Lib_Path); copys && *copys; ) { - s = skip_ws(s); - /* copy s into buf until end of s, r is the actual position in buf */ - int ii; - for (r = buf, ii = 0; *s; r++, s++, ii++) { - *r = *s; - if (ii > 500) { - fprintf(stderr, "Warning: spinit path is too long.\n"); - break; + /* Now source the standard startup file spinit or tclspinit + if no_spinit is not set . */ + if (!cp_getvar("no_spinit", CP_BOOL, NULL, 0)) { + /* jump over leading spaces */ + for (copys = s = cp_tildexpand(Lib_Path); copys && *copys; ) { + s = skip_ws(s); + /* copy s into buf until end of s, r is the actual position in buf */ + int ii; + for (r = buf, ii = 0; *s; r++, s++, ii++) { + *r = *s; + if (ii > 500) { + fprintf(stderr, "Warning: spinit path is too long.\n"); + break; + } } - } - tfree(copys); - /* add a path separator to buf at actual position */ - (void) strcpy(r, DIR_PATHSEP); + tfree(copys); + /* add a path separator to buf at actual position */ + (void)strcpy(r, DIR_PATHSEP); #ifdef TCL_MODULE - /* add "tclspinit" to buf after actual position */ - (void) strcat(r, "tclspinit"); + /* add "tclspinit" to buf after actual position */ + (void) strcat(r, "tclspinit"); #else - /* add "spinit" to buf after actual position */ - (void) strcat(r, "spinit"); + /* add "spinit" to buf after actual position */ + (void)strcat(r, "spinit"); #endif - if ((fp = fopen(buf, "r")) != NULL) { + if ((fp = fopen(buf, "r")) != NULL) { - cp_interactive = FALSE; - inp_spsource(fp, TRUE, buf, FALSE); - cp_interactive = TRUE; - found = TRUE; - break; + cp_interactive = FALSE; + inp_spsource(fp, TRUE, buf, FALSE); + cp_interactive = TRUE; + found = TRUE; + break; #if defined(HAS_WINGUI) || defined(__MINGW32__) || defined(_MSC_VER) - /* search in local directory where ngspice.exe resides */ + /* search in local directory where ngspice.exe resides */ #if defined TCL_MODULE - } else if ((fp = fopen("./tclspinit", "r")) != NULL) { + } + else if ((fp = fopen("./tclspinit", "r")) != NULL) { #else - } else if ((fp = fopen("./spinit", "r")) != NULL) { + } + else if ((fp = fopen("./spinit", "r")) != NULL) { #endif - cp_interactive = FALSE; - inp_spsource(fp, TRUE, buf, FALSE); - cp_interactive = TRUE; - found = TRUE; - break; + cp_interactive = FALSE; + inp_spsource(fp, TRUE, buf, FALSE); + cp_interactive = TRUE; + found = TRUE; + break; +#endif + } + else if (ft_controldb) { + fprintf(cp_err, "Warning: can't open \"%s\".\n", buf); + } + } + + if (!found) { +#if defined TCL_MODULE + fprintf(cp_err, "Warning: can't find the initialization file tclspinit.\n"); +#else + fprintf(cp_err, "Warning: can't find the initialization file spinit.\n"); #endif - } else if (ft_controldb) { - fprintf(cp_err, "Note: can't open \"%s\".\n", buf); } } - - if (!found) { -#if defined TCL_MODULE - fprintf(cp_err, "Note: can't find the initialization file tclspinit.\n"); -#else - fprintf(cp_err, "Note: can't find the initialization file spinit.\n"); -#endif + else { + fprintf(cp_out, "Note: Start without reading file 'spinit'.\n"); } } diff --git a/src/frontend/inp.c b/src/frontend/inp.c index da24fa05f..1d98ed4df 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -667,7 +667,7 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) with_params = TRUE; size = sizeof header + 10; // Allow for %u and close. for (argc = 0; Copy_of_argv[optind + argc]; ++argc) - size += strlen(Copy_of_argv[optind + argc]); + size += (int)strlen(Copy_of_argv[optind + argc]); size += 3 * argc; // Spaces and quotes. if (size <= sizeof buf) p_buf_active = buf; diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index f55771b7b..06cabc0e0 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -206,7 +206,7 @@ static int inp_poly_2g6_compat(struct card* deck); static void inp_poly_err(struct card *deck); #endif -#ifdef CIDER +#if defined(CIDER) || defined(XSPICE) static char *keep_case_of_cider_param(char *buffer) { int numq = 0, keep_case = 0; @@ -240,6 +240,31 @@ static char *keep_case_of_cider_param(char *buffer) return s; } +static char* make_lower_case_copy(char* inbuf) +{ + char* s = NULL; + char* rets = NULL; + size_t lenb = 0; + + if (!inbuf) { + return NULL; + } + lenb = strlen(inbuf); + if (lenb < 1) { + return NULL; + } + rets = dup_string(inbuf, lenb); + if (!rets) { + return NULL; + } + for (s = rets; *s; s++) { + *s = tolower_c(*s); + } + return rets; +} +#endif + +#ifdef CIDER static int is_comment_or_blank(char *buffer) { /* Assume line buffers have initial whitespace removed */ @@ -275,29 +300,6 @@ static int turn_off_case_retention(char *buffer) } } -static char *make_lower_case_copy(char *inbuf) -{ - char *s = NULL; - char *rets = NULL; - size_t lenb = 0; - - if (!inbuf) { - return NULL; - } - lenb = strlen(inbuf); - if (lenb < 1) { - return NULL; - } - rets = dup_string(inbuf, lenb); - if (!rets) { - return NULL; - } - for (s = rets; *s; s++) { - *s = tolower_c(*s); - } - return rets; -} - static int ignore_line(char *buf) { /* Can the line in buf be ignored for ic.file checking? @@ -397,6 +399,31 @@ static int is_cider_model(char *buf) } } #endif +#ifdef XSPICE +static int is_xspice_model(char* buf) +{ + /* Expect filesource, table2d, table3d, d_state, d_source, d_process, d_cosim + to be on the same line as the .model. + Otherwise it will be missed if on a continuation line. + This should be rare. + */ + char* s; + if (!ciprefix(".model", buf)) { + return 0; + } + s = make_lower_case_copy(buf); + if (!s) return 0; + if (strstr(s, "filesource") || strstr(s, "table2d") || strstr(s, "table3d") || + strstr(s, "d_state") || strstr(s, "d_source") || strstr(s, "d_process") || strstr(s, "d_cosim")) { + tfree(s); + return 1; + } + else { + tfree(s); + return 0; + } +} +#endif /* Insert a new card, just behind the given card. * The new card takes ownership of the memory pointed to by "line". @@ -1213,26 +1240,26 @@ struct card *inp_readall(FILE *fp, const char *dir_name, } -struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, - bool comfile, bool intfile) -/* fp: in, pointer to file to be read, - call_depth: in, nested call to fcn - dir_name: in, name of directory of file to be read - comfile: in, TRUE if command file (e.g. spinit, .spiceinit) - intfile: in, TRUE if deck is generated from internal circarray -*/ +struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name, + bool comfile, bool intfile) + /* fp: in, pointer to file to be read, + call_depth: in, nested call to fcn + dir_name: in, name of directory of file to be read + comfile: in, TRUE if command file (e.g. spinit, .spiceinit) + intfile: in, TRUE if deck is generated from internal circarray + */ { struct inp_read_t rv; - struct card *end = NULL, *cc = NULL; - char *buffer = NULL; + struct card* end = NULL, * cc = NULL; + char* buffer = NULL; /* segfault fix */ #ifdef XSPICE char big_buff[5000]; int line_count = 0; #endif - char *new_title = NULL; + char* new_title = NULL; int line_number = 1; - /* sjb - renamed to avoid confusion with struct card */ + /* sjb - renamed to avoid confusion with struct card */ int line_number_orig = 1; int cirlinecount = 0; /* length of circarray */ static int is_control = 0; /* We are reading from a .control section */ @@ -1259,8 +1286,8 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* gtri - modify - 12/12/90 - wbk - read from mailbox if ipc * enabled */ - /* If IPC is not enabled, do equivalent of what SPICE did before - */ + /* If IPC is not enabled, do equivalent of what SPICE did before + */ if (!g_ipc.enabled) { if (call_depth == 0 && line_count == 0) { line_count++; @@ -1280,7 +1307,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, char ipc_buffer[1025]; /* Had better be big enough */ int ipc_len; Ipc_Status_t ipc_status = - ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT); + ipc_get_line(ipc_buffer, &ipc_len, IPC_WAIT); if (ipc_status == IPC_STATUS_END_OF_DECK) { buffer = NULL; break; @@ -1302,7 +1329,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, buffer = readline(fp); if (!buffer) { break; - } + } #endif } @@ -1318,7 +1345,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* OK -- now we have loaded the next line into 'buffer'. Process it. */ - /* If input line is blank, ignore it & continue looping. */ + /* If input line is blank, ignore it & continue looping. */ if ((strcmp(buffer, "\n") == 0) || (strcmp(buffer, "\r\n") == 0)) if (call_depth != 0 || (call_depth == 0 && cc != NULL)) { line_number_orig++; @@ -1339,7 +1366,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* now handle .title statement */ if (ciprefix(".title", buffer)) { - char *s; + char* s; s = skip_non_ws(buffer); /* skip over .title */ s = skip_ws(s); /* advance past space chars */ @@ -1362,7 +1389,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, * so .lib is interpreted as old style .lib (no lib * name given, .lib replaced by .include). */ - char *s = skip_non_ws(buffer); /* skip over .lib */ + char* s = skip_non_ws(buffer); /* skip over .lib */ fprintf(cp_err, " File included as: .inc %s\n", s); memcpy(buffer, ".inc", 4); } @@ -1370,10 +1397,10 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* now handle .include statements */ if (ciprefix(".include", buffer) || ciprefix(".inc", buffer)) { - char *y = NULL; - char *s; + char* y = NULL; + char* s; - struct card *newcard; + struct card* newcard; inp_stripcomments_line(buffer, FALSE); @@ -1388,13 +1415,13 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, } { - char *y_resolved = inp_pathresolve_at(y, dir_name); - char *y_dir_name; - FILE *newfp; + char* y_resolved = inp_pathresolve_at(y, dir_name); + char* y_dir_name; + FILE* newfp; if (!y_resolved) { fprintf(cp_err, "Error: Could not find include file %s\n", - y); + y); if (ft_stricterror) controlled_exit(EXIT_FAILURE); rv.line_number = line_number; @@ -1413,14 +1440,14 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, y_dir_name = ngdirname(y_resolved); newcard = inp_read( - newfp, call_depth + 1, y_dir_name, FALSE, FALSE) - .cc; /* read stuff in include file into - netlist */ + newfp, call_depth + 1, y_dir_name, FALSE, FALSE) + .cc; /* read stuff in include file into + netlist */ tfree(y_dir_name); tfree(y_resolved); - (void) fclose(newfp); + (void)fclose(newfp); } /* Make the .include a comment */ @@ -1429,7 +1456,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, /* append `buffer' to the (cc, end) chain of decks */ { end = insert_new_line( - end, copy(buffer), line_number, line_number); + end, copy(buffer), line_number, line_number); if (!cc) cc = end; @@ -1447,17 +1474,17 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, end->nextcard = newcard; /* Renumber the lines */ for (end = newcard; end && end->nextcard; - end = end->nextcard) { + end = end->nextcard) { end->linenum = line_number++; end->linenum_orig = line_number_inc++; } end->linenum = line_number++; /* SJB - renumber last line */ end->linenum_orig = line_number_inc++; - /* SJB - renumber the last line */ + /* SJB - renumber the last line */ } /* Fix the buffer up a bit. */ - (void) memcpy(buffer + 1, "end of: ", 8); + (void)memcpy(buffer + 1, "end of: ", 8); } /* end of .include handling */ /* loop through 'buffer' until end is reached. Make all letters lower @@ -1468,7 +1495,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, * double quotes. Single quotes are later on swallowed and disappear, * double quotes are printed. */ { - char *s; + char* s; #ifdef CIDER if (ciprefix(".model", buffer)) { in_cider_model = is_cider_model(buffer); @@ -1476,16 +1503,16 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, printf("Found .model Cider model is %s\n", (in_cider_model ? "ON" : "OFF")); #endif - } + } if (in_cider_model && turn_off_case_retention(buffer)) { in_cider_model = 0; #ifdef TRACE printf("Cider model is OFF\n"); #endif - } + } #endif if (ciprefix("plot", buffer) || ciprefix("gnuplot", buffer) || - ciprefix("hardcopy", buffer)) { + ciprefix("hardcopy", buffer)) { /* lower case excluded for tokens following title, xlabel, * ylabel. tokens may contain spaces, then they have to be * enclosed in quotes. keywords and tokens have to be @@ -1549,9 +1576,9 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, } } else if (ciprefix("print", buffer) || - ciprefix("eprint", buffer) || - ciprefix("eprvcd", buffer) || - ciprefix("asciiplot", buffer)) { + ciprefix("eprint", buffer) || + ciprefix("eprvcd", buffer) || + ciprefix("asciiplot", buffer)) { /* lower case excluded for tokens following output redirection * '>' */ bool redir = FALSE; @@ -1565,12 +1592,19 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, } #ifdef CIDER else if (in_cider_model && !is_comment_or_blank(buffer) && - (ciprefix(".model", buffer) || buffer[0] == '+')) { + (ciprefix(".model", buffer) || buffer[0] == '+')) { s = keep_case_of_cider_param(buffer); } else if (line_contains_icfile(buffer)) { s = keep_case_of_cider_param(buffer); } +#endif +#ifdef XSPICE + /* lower case excluded for text in quotes for .model of code models + filesource, rable2d, table3d, d_state, d_source, d_process, d_cosim */ + else if (is_xspice_model(buffer)) { + s = keep_case_of_cider_param(buffer); + } #endif /* no lower case letters for lines beginning with: */ else if (!ciprefix("write", buffer) && @@ -6596,11 +6630,13 @@ static void inp_compat(struct card *card) // skip '=' cut_line++; // copy the replacement without trailing '\0' - for (ii = 0; ii < xlen; ii++) + char* loc_ptr = str_ptr - 1; + for (ii = 0; ii < xlen; ii++) { if (*copy_ptr) - *cut_line++ = *copy_ptr++; + *loc_ptr++ = *copy_ptr++; else - *cut_line++ = ' '; + *loc_ptr++ = ' '; + } tfree(del_ptr); tfree(exp_ptr); diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index c135b37db..206050b5e 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -79,7 +79,8 @@ extern INPmodel *modtab; extern NGHASHPTR modtabhash; extern bool ft_batchmode; -static struct variable *parmtovar(IFvalue *pv, IFparm *opt); +static struct variable *parmtovar(IFvalue *pv, IFparm *opt, + int use_description); static IFparm *parmlookup(IFdevice *dev, GENinstance **inptr, char *param, int do_model, int inout); static IFvalue *doask(CKTcircuit *ckt, int typecode, GENinstance *dev, GENmodel *mod, @@ -688,17 +689,12 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do continue; pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) { - tv = parmtovar(pv, opt); - - /* With the following we pack the name and the acronym of the parameter */ - { - char *x = tv->va_name; - tv->va_name = tprintf("%s [%s]", tv->va_name, device->instanceParms[i].keyword); - tfree(x); + tv = parmtovar(pv, opt, 0); + if (tv) { + if (vv) + tv->va_next = vv; + vv = tv; } - if (vv) - tv->va_next = vv; - vv = tv; } else { fprintf(cp_err, "Internal Error: no parameter '%s' on device '%s'\n", @@ -725,26 +721,12 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do continue; pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) { - tv = parmtovar(pv, opt); - /* Inside parmtovar: - * 1. tv->va_name = copy(opt->description); - * 2. Copy the type of variable of IFparm into a variable (thus parm-to-var) - * vv->va_type = opt->dataType - * The long description of the parameter: - * IFparm MOS_SGTmPTable[] = { // model parameters // - * OP("type", MOS_SGT_MOD_TYPE, IF_STRING, "N-channel or P-channel MOS") - * goes into tv->va_name to put braces around the parameter of the model - * tv->va_name += device->modelParms[i].keyword; - */ - { - char *x = tv->va_name; - tv->va_name = tprintf("%s [%s]", tv->va_name, device->modelParms[i].keyword); - tfree(x); + tv = parmtovar(pv, opt, 0); + if (tv) { + if (vv) + tv->va_next = vv; + vv = tv; } - /* tv->va_string = device->modelParms[i].keyword; Put the name of the variable */ - if (vv) - tv->va_next = vv; - vv = tv; } else { fprintf(cp_err, "Internal Error: no parameter '%s' on device '%s'\n", @@ -768,7 +750,7 @@ spif_getparam_special(CKTcircuit *ckt, char **name, char *param, int ind, int do } pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) - vv = parmtovar(pv, opt); + vv = parmtovar(pv, opt, 0); return (vv); } else { return (if_getstat(ckt, *name)); @@ -814,10 +796,12 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model) continue; pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) { - tv = parmtovar(pv, opt); - if (vv) - tv->va_next = vv; - vv = tv; + tv = parmtovar(pv, opt, 0); + if (tv) { + if (vv) + tv->va_next = vv; + vv = tv; + } } else { fprintf(cp_err, "Internal Error: no parameter '%s' on device '%s'\n", @@ -843,7 +827,7 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model) } pv = doask(ckt, typecode, dev, mod, opt, ind); if (pv) - vv = parmtovar(pv, opt); + vv = parmtovar(pv, opt, 0); return (vv); } else { return (if_getstat(ckt, *name)); @@ -991,49 +975,90 @@ if_setparam(CKTcircuit *ckt, char **name, char *param, struct dvec *val, int do_ } } +/* Make a linked list where the first node is a CP_LIST variable + * pointing to the different values of the vector variables. + * + * + * In the case of Vin_sin 1 0 sin (0 2 2000) + * and of print @vin_sin[sin] + * + * vv->va_V.vV_list->va_V.vV_real = 2000 + * vv->va_V.vV_list->va_next->va_V.vV_real = 2 + * vv->va_V.vV_list->va_next->va_next->va_V.vV_real = 0 + * So the list is starting from behind, but no problem + * This works fine + */ static struct variable * -parmtovar(IFvalue *pv, IFparm *opt) +parmtolist(IFvalue *pv, IFparm *opt, char *name) { - /* It is not clear whether we want to name the variable - * by `keyword' or by `description' */ + struct variable *list = NULL; + int i; + + for (i = pv->v.numValue; --i >= 0;) { + switch (opt->dataType & (IF_VARTYPES & ~IF_VECTOR)) { + case IF_INTEGER: + list = var_alloc_num(NULL, pv->v.vec.iVec[i], list); + break; + case IF_REAL: + case IF_COMPLEX: + list = var_alloc_real(NULL, pv->v.vec.rVec[i], list); + break; + case IF_STRING: + list = var_alloc_string(NULL, copy(pv->v.vec.sVec[i]), list); + break; + case IF_FLAG: + list = var_alloc_bool(NULL, pv->v.vec.iVec[i] ? TRUE : FALSE, + list); + break; + default: + fprintf(cp_err, + "parmtolist: Internal Error: bad PARM type " + "%#x for %s (%s).\n", + opt->dataType, opt->keyword, opt->description); + if (name) + free(name); + break; + } + } + + if (i || pv->v.numValue == 0) + list = var_alloc_vlist(name, list, NULL); + if (pv->v.vec.iVec) { // All the union members are pointers + free(pv->v.vec.iVec); + pv->v.vec.iVec = NULL; + } + return list; +} + +static struct variable * +parmtovar(IFvalue *pv, IFparm *opt, int use_description) +{ + char *name; + + name = use_description ? opt->description : opt->keyword; + if (name) + name = copy(name); + if (opt->dataType & IF_VECTOR) + return parmtolist(pv, opt, name); switch (opt->dataType & IF_VARTYPES) { case IF_INTEGER: - return var_alloc_num(copy(opt->description), pv->iValue, NULL); + return var_alloc_num(name, pv->iValue, NULL); case IF_REAL: case IF_COMPLEX: - return var_alloc_real(copy(opt->description), pv->rValue, NULL); + return var_alloc_real(name, pv->rValue, NULL); case IF_STRING: - return var_alloc_string(copy(opt->description), pv->sValue, NULL); + return var_alloc_string(name, copy(pv->sValue), NULL); case IF_FLAG: - return var_alloc_bool(copy(opt->description), pv->iValue ? TRUE : FALSE, NULL); - case IF_REALVEC: { - struct variable *list = NULL; - int i; - for (i = pv->v.numValue; --i >= 0;) - list = var_alloc_real(NULL, pv->v.vec.rVec[i], list); - return var_alloc_vlist(copy(opt->description), list, NULL); - /* It is a linked list where the first node is a variable - * pointing to the different values of the variables. - * - * To access the values of the real variable vector must be - * vv->va_V.vV_real = valor node ppal that is of no use. - * - * In the case of Vin_sin 1 0 sin (0 2 2000) - * and of print @vin_sin[sin] - * - * vv->va_V.vV_list->va_V.vV_real = 2000 - * vv->va_V.vV_list->va_next->va_V.vV_real = 2 - * vv->va_V.vV_list->va_next->va_next->va_V.vV_real = 0 - * So the list is starting from behind, but no problem - * This works fine - */ - } + return var_alloc_bool(name, pv->iValue ? TRUE : FALSE, + NULL); default: fprintf(cp_err, - "parmtovar: Internal Error: bad PARM type %d.\n", - opt->dataType); + "parmtovar: Internal Error: bad PARM type %#x for %s (%s).\n", + opt->dataType, opt->keyword, opt->description); + if (name) + free(name); return (NULL); } } @@ -1317,7 +1342,7 @@ if_getstat(CKTcircuit *ckt, char *name) return (NULL); } - return (parmtovar(&parm, if_parm)); + return (parmtovar(&parm, if_parm, 1)); } else { @@ -1339,7 +1364,7 @@ if_getstat(CKTcircuit *ckt, char *name) return (NULL); } - *v = parmtovar(&parm, if_parm); + *v = parmtovar(&parm, if_parm, 1); v = &((*v)->va_next); } diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 26eca7494..0bf986fa0 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -580,8 +580,8 @@ vec_get(const char *vec_name) { struct dvec *d, *end = NULL, *newv = NULL; struct plot *pl; char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param; - int i = 0; - struct variable *vv; + int i = 0; + struct variable *vv, *v; wd = word = copy(vec_name); /* Gets mangled below... */ @@ -638,6 +638,8 @@ vec_get(const char *vec_name) { } if (!d && (*word == SPECCHAR)) { /* "@" */ + int multiple; + /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, @@ -646,6 +648,12 @@ vec_get(const char *vec_name) { return (NULL); /* va: use NULL */ } + if (!ft_curckt) { + fprintf(cp_err, "Error: No circuit loaded.\n"); + tfree(wd); + return (NULL); + } + whole = copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) @@ -660,157 +668,131 @@ vec_get(const char *vec_name) { param = NULL; } + /* + * This is what is done in case of "alter r1 resistance = 1234" + * r1 resistance, 0 + * if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); + */ - if (ft_curckt) { - /* - * This is what is done in case of "alter r1 resistance = 1234" - * r1 resistance, 0 - * if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model); - */ - - /* vv = if_getparam (ft_curckt->ci_ckt, &name, param, 0, 0); */ - vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0); - if (!vv) { - tfree(whole); - tfree(wd); - return (NULL); - } - } else { - fprintf(cp_err, "Error: No circuit loaded.\n"); + vv = if_getparam(ft_curckt->ci_ckt, &name, param, 0, 0); + if (!vv) { tfree(whole); tfree(wd); return (NULL); } - d = dvec_alloc(copy(whole), /* MW. The same as word before */ - SV_NOTYPE, - VF_REAL, /* No complex values yet... */ - 1, NULL); - - /* In case the represented variable is a REAL vector this takes - * the actual value of the first element of the linked list which - * does not make sense. - * This is an error. + /* If vec_name was "@dev", "@model", "@dev[all]" or @model[all]", + * if_getparam() returns a list. */ - /* This will copy the contents of the structure vv in another structure - * dvec (FTEDATA.H) that do not have INTEGER so that those parameters - * defined as IF_INTEGER are not given their value when using - * print @pot[pos_node] - * To fix this, it is necessary to define: - * OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potenciometer"), - * int POTnegNode; // number of negative node of potenciometer (Nodo_3) - * case POT_QUEST_POS_NODE: - * value->rValue = (double)fast->POTposNode; - * return (OK); - * Works but with the format 1.00000E0 - */ + multiple = (vv->va_next != NULL); + if (multiple && param) + *--param = '\0'; - /* We must make a change in format between the data that carries a variable to - * put in a dvec. - */ + for (v = vv; v; v = v->va_next) { + struct dvec *nd; + char *new_vec_name, new_name[256]; - /* - * #define va_bool va_V.vV_bool - * #define va_num va_V.vV_num - * #define va_real va_V.vV_real - * #define va_string va_V.vV_string - * #define va_vlist va_V.vV_list - * enum cp_types { - * CP_BOOL, - * CP_NUM, - * CP_REAL, - * CP_STRING, - * CP_LIST - ° }; - */ - - /* The variable is a vector */ - if (vv->va_type == CP_LIST) { - /* Compute the length of the vector, - * used with the parameters of isrc and vsrc - */ - struct variable *nv; - - /* Count the number of nodes in the list */ - i = 0; - for (nv = vv->va_vlist; nv; nv = nv->va_next) { - i++; + if (multiple) { + snprintf(new_name, sizeof new_name, "@%s[%s]", + name, v->va_name); + new_vec_name = new_name; + } else { + new_vec_name = whole; } + nd = dvec_alloc(copy(new_vec_name), + SV_NOTYPE, + VF_REAL, /* No complex values yet... */ + 1, NULL); - dvec_realloc(d, i, NULL); /* Resize to # nodes */ + switch (v->va_type) { + case CP_BOOL: + *nd->v_realdata = (double)v->va_bool; + break; + case CP_NUM: + *nd->v_realdata = (double)v->va_num; + break; + case CP_REAL: + *nd->v_realdata = v->va_real; + break; + case CP_STRING: + fprintf(stderr, + "ERROR: can not handle string value " + "of '%s' in vec_get(%s)\nIgnoring...\n", + v->va_name, new_vec_name); + dvec_free(nd); + continue; + break; + case CP_LIST: + { + struct variable *nv; + enum cp_types ft; - /* Step through the list again, setting values this time */ - i = 0; - for (nv = vv->va_vlist; nv; nv = nv->va_next) { - d->v_realdata[i++] = nv->va_real; - } - - /* To be able to identify the vector to represent - * belongs to a special "conunto" and should be printed in a - * special way. - */ - d->v_dims[1] = 1; - } - else if (vv->va_type == CP_NUM) { /* Variable is an integer */ - *d->v_realdata = (double) vv->va_num; - } - else if (vv->va_type == CP_REAL) { /* Variable is a real */ - if (!(vv->va_next)) { - /* Only a real data - * usually normal - */ - *d->v_realdata = vv->va_real; - } - else { - /* Real data set - * When you print a model @ [all] - * Just print numerical values, not the string - */ - struct variable *nv; - /* We go to print the list of values - * nv->va_name = Parameter description - * nv->va_string = Parameter - * nv->va_real= Value - */ - nv = vv; - for (i = 1; ; i++) { - switch (nv->va_type) { - case CP_REAL: - fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real); - break; - case CP_STRING: - fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string); - break; - case CP_NUM: - fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num); - break; - case CP_BOOL: - fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_bool); - break; - default: { - fprintf(stderr, "ERROR: enumeration value `CP_LIST' not handled in vec_get\nIgnoring...\n"); - break; - } - } - nv = nv->va_next; + /* Array values are presented as a list. + * Compute the length of the vector, and check that + * it is homogenous: + * used with the parameters of isrc and vsrc + */ + i = 0; + nv = v->va_vlist; if (!nv) { - break; + dvec_free(nd); + continue; + } + ft = nv->va_type; + for (; nv; nv = nv->va_next) { + /* Count the number of nodes in the list */ + + i++; + if (nv->va_type != ft) + break; + } + if (nv || ft == CP_STRING || ft == CP_LIST) { + fprintf(stderr, + "ERROR: can not handle mixed, string or list " + "value of '%s' in vec_get(%s)\nIgnoring...\n", + v->va_name, new_vec_name); + dvec_free(nd); + continue; + } + dvec_realloc(nd, i, NULL); /* Resize to # nodes */ + + /* Step through the list again, setting values this time */ + + i = 0; + for (nv = v->va_vlist; nv; nv = nv->va_next) { + switch (ft) { + case CP_BOOL: + nd->v_realdata[i++] = (double)nv->va_bool; + break; + case CP_NUM: + nd->v_realdata[i++] = (double)nv->va_num; + break; + default: + case CP_REAL: + nd->v_realdata[i++] = nv->va_real; + break; + } + + /* To be able to identify the vector to represent + * belongs to a special "conunto" and should be printed + * in a special way. + */ + nd->v_dims[1] = 1; } } - - /* To distinguish those does not take anything for print screen to - * make a print or M1 @ @ M1 [all] leaving only the correct data - * and not the last - */ - d->v_rlength = 1; + break; } + /* Chain it on. */ + + vec_new(nd); + nd->v_link2 = d; + d = nd; } free_struct_variable(vv); tfree(wd); - vec_new(d); tfree(whole); return d; } diff --git a/src/frontend/wdisp/winprint.c b/src/frontend/wdisp/winprint.c index db5bfe577..249224cb6 100644 --- a/src/frontend/wdisp/winprint.c +++ b/src/frontend/wdisp/winprint.c @@ -378,7 +378,7 @@ int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) } -int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) +int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta, bool isgrid) /* * Notes: * Draws an arc of and center at (x0,y0) beginning at @@ -397,6 +397,8 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) double dx0; double dy0; + NG_IGNORE(isgrid); + if (!currentgraph) return 0; pd = pPrintData(currentgraph); if (!pd) return 0; diff --git a/src/frontend/wdisp/winprint.h b/src/frontend/wdisp/winprint.h index f6d591d02..0c35a7816 100644 --- a/src/frontend/wdisp/winprint.h +++ b/src/frontend/wdisp/winprint.h @@ -12,7 +12,7 @@ int WPRINT_NewViewport( GRAPH * graph); int WPRINT_Close(void); int WPRINT_Clear(void); int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid); -int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta); +int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta, bool isgrid); int WPRINT_Text( char * text, int x, int y, int degrees); int WPRINT_DefineColor(int colorid, double red, double green, double blue); int WPRINT_DefineLinestyle(int num, int mask); diff --git a/src/include/ngspice/bool.h b/src/include/ngspice/bool.h index c5f70e331..7f398d105 100644 --- a/src/include/ngspice/bool.h +++ b/src/include/ngspice/bool.h @@ -1,20 +1,20 @@ #ifndef ngspice_BOOL_H #define ngspice_BOOL_H -//typedef unsigned char bool; +#if defined (__MINGW32__) || defined (_MSC_VER) #ifndef __cplusplus typedef int bool; #endif +#else +#include +#endif typedef int BOOL; - #define BOOLEAN int #define TRUE 1 #define FALSE 0 #define NO 0 #define YES 1 - - #endif diff --git a/src/include/ngspice/devdefs.h b/src/include/ngspice/devdefs.h index 870708b69..09af7ce68 100644 --- a/src/include/ngspice/devdefs.h +++ b/src/include/ngspice/devdefs.h @@ -107,6 +107,9 @@ typedef struct SPICEdev { /* noise routine */ int (*DEVsoaCheck)(CKTcircuit*,GENmodel*); /* subroutine to call on soa check */ + int *DEVinstSize; /* size of an instance */ + int *DEVmodSize; /* size of a model */ + #ifdef CIDER void (*DEVdump)(GENmodel *, CKTcircuit *); void (*DEVacct)(GENmodel *, CKTcircuit *, FILE *); @@ -114,8 +117,6 @@ typedef struct SPICEdev { * now used only by cider numerical devices */ #endif - int *DEVinstSize; /* size of an instance */ - int *DEVmodSize; /* size of a model */ #ifdef KLU int (*DEVbindCSC)(GENmodel *, CKTcircuit *); diff --git a/src/include/ngspice/ifsim.h b/src/include/ngspice/ifsim.h index cf019be2e..1802a2a60 100644 --- a/src/include/ngspice/ifsim.h +++ b/src/include/ngspice/ifsim.h @@ -282,6 +282,8 @@ struct IFdevice { int *numModelParms; /* number of model parameter descriptors */ IFparm *modelParms; /* array of model parameter descriptors */ + int flags; /* DEV_ */ + /* gtri - modify - wbk - 10/11/90 - add entries to hold data required */ /* by new parser */ #ifdef XSPICE @@ -298,8 +300,6 @@ struct IFdevice { /* gtri - end - wbk - 10/11/90 */ #endif - int flags; /* DEV_ */ - #ifdef OSDI const void *registry_entry; #endif diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index 49488ea88..661e6a2a3 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -116,6 +116,7 @@ char *INPerrCat(char *, char *); char *INPstrCat(char *, char, char *); char *INPerror(int); double INPevaluate(char **, int *, int); +double INPevaluate2(char **, int *, int); double INPevaluateRKM_R(char **, int *, int); double INPevaluateRKM_C(char **, int *, int); double INPevaluateRKM_L(char **, int *, int); diff --git a/src/include/ngspice/mifparse.h b/src/include/ngspice/mifparse.h index fcd5e98e1..40f689558 100644 --- a/src/include/ngspice/mifparse.h +++ b/src/include/ngspice/mifparse.h @@ -47,21 +47,14 @@ NON-STANDARD FEATURES #include "ngspice/miftypes.h" -/* - * Values of different types used by the parser. Note that this is a structure - * instead of a union because we need to do initializations in the ifspec.c files for - * the models and unions cannot be initialized in any useful way in C - * - */ - -struct Mif_Parse_Value { +/* Values of different types used by the parser. */ +union Mif_Parse_Value { Mif_Boolean_t bvalue; /* For boolean values */ int ivalue; /* For integer values */ double rvalue; /* For real values */ Mif_Complex_t cvalue; /* For complex values */ char *svalue; /* For string values */ - }; @@ -101,8 +94,8 @@ struct Mif_Param_Info { char *name; /* Name of this parameter */ char *description; /* Description of this parameter */ Mif_Data_Type_t type; /* Is this a real, boolean, string, ... */ - Mif_Boolean_t has_default; /* True if there is a default value */ - Mif_Parse_Value_t default_value; /* The default value */ + int default_value_siz;/* Size of default_values array. */ + Mif_Parse_Value_t *default_values; /* The default values (array). */ Mif_Boolean_t has_lower_limit; /* True if there is a lower limit */ Mif_Parse_Value_t lower_limit; /* The lower limit for this parameter */ Mif_Boolean_t has_upper_limit; /* True if there is a upper limit */ diff --git a/src/include/ngspice/miftypes.h b/src/include/ngspice/miftypes.h index 532b884e1..f7c05e6cd 100644 --- a/src/include/ngspice/miftypes.h +++ b/src/include/ngspice/miftypes.h @@ -205,19 +205,19 @@ typedef struct Mif_Complex { typedef union { - Mif_Boolean_t bvalue; /* For digital node value */ + Mif_Boolean_t bvalue; /* For boolean parameters */ int ivalue; /* For integer parameters */ double rvalue; /* For spice node values and real parameters */ Mif_Complex_t cvalue; /* For complex parameters */ - char *svalue; /* For string parameters */ - void *pvalue; /* For user defined nodes */ + char *svalue; /* For string parameters */ + void *pvalue; /* For Digital and user defined nodes */ } Mif_Value_t; /* types from mifparse.h */ -typedef struct Mif_Parse_Value Mif_Parse_Value_t; +typedef union Mif_Parse_Value Mif_Parse_Value_t; typedef struct Mif_Conn_Info Mif_Conn_Info_t; typedef struct Mif_Param_Info Mif_Param_Info_t; typedef struct Mif_Inst_Var_Info Mif_Inst_Var_Info_t; diff --git a/src/include/ngspice/sharedspice.h b/src/include/ngspice/sharedspice.h index 2b9ac5b5f..111aaae9b 100644 --- a/src/include/ngspice/sharedspice.h +++ b/src/include/ngspice/sharedspice.h @@ -1,9 +1,13 @@ /* header file for shared ngspice */ -/* Copyright 2021 Holger Vogt */ +/* Copyright 2021-2024 Holger Vogt */ /* Modified BSD license */ /* Interface between a calling program (caller) and ngspice.dll (ngspice.so) +** +ngSpice_nospinit(void) +Set variable no_spinit, if reading the initialization file 'spinit' is not wanted. +To be called before ngSpice_Init() ** ngSpice_Init(SendChar*, SendStat*, ControlledExit*, @@ -441,6 +445,9 @@ NG_BOOL ngSpice_running(void); IMPEXP NG_BOOL ngSpice_SetBkpt(double time); +/* Set variable no_spinit, if reading 'spinit' is not wanted. */ +IMPEXP +int ngSpice_nospinit(void); #ifdef __cplusplus } diff --git a/src/sharedspice.c b/src/sharedspice.c index 54bdc5b90..30680fed3 100644 --- a/src/sharedspice.c +++ b/src/sharedspice.c @@ -788,6 +788,15 @@ ngSpice_running (void) } #endif +/* Set variable no_spinit, if reading 'spinit' is not wanted. */ +IMPEXP +int +ngSpice_nospinit(void) +{ + bool t = TRUE; + cp_vset("no_spinit", CP_BOOL, &t); + return 0; +} /* Initialise external voltage source and synchronization */ IMPEXP diff --git a/src/spicelib/analysis/ninteg.c b/src/spicelib/analysis/ninteg.c index ec482ac20..43c5b6732 100644 --- a/src/spicelib/analysis/ninteg.c +++ b/src/spicelib/analysis/ninteg.c @@ -31,15 +31,15 @@ Nintegrate (double noizDens, double lnNdens, double lnNlstDens, Ndata *data) exponent = (lnNdens - lnNlstDens) / data->delLnFreq; if ( fabs(exponent) < N_INTFTHRESH ) { - return (noizDens * data->delFreq); + return (noizDens * data->delFreq); } else { - a = limexp(lnNdens - exponent*data->lnFreq); - exponent += 1.0; - if (fabs(exponent) < N_INTUSELOG) { - return (a * (data->lnFreq - data->lnLastFreq)); + a = limexp(lnNdens - exponent*data->lnFreq); + exponent += 1.0; + if (fabs(exponent) < N_INTUSELOG) { + return (a * (data->lnFreq - data->lnLastFreq)); } else { - return (a * ((exp(exponent * data->lnFreq) - exp(exponent * data->lnLastFreq)) / - exponent)); + return (a * ((limexp(exponent * data->lnFreq) - limexp(exponent * data->lnLastFreq)) / + exponent)); } } } diff --git a/src/spicelib/analysis/optran.c b/src/spicelib/analysis/optran.c index f0c7dd76e..8a75fd1b6 100644 --- a/src/spicelib/analysis/optran.c +++ b/src/spicelib/analysis/optran.c @@ -161,7 +161,8 @@ void com_optran(wordlist* wl) { wltmp = wltmp->wl_next; stpstr = wltmp->wl_word; opramptime = INPevaluate(&stpstr, &err, 1); - if (err || (*stpstr != '\0')) + /* optran with uic reads initial conditions */ + if (err || ((*stpstr != '\0') && !strstr(stpstr, "uic"))) goto bugquit; if (opstepsize > opfinaltime) { fprintf(stderr, "Error: Optran step size larger than final time.\n"); diff --git a/src/spicelib/devices/cktinit.c b/src/spicelib/devices/cktinit.c index 92e83093b..ea4ed0c29 100644 --- a/src/spicelib/devices/cktinit.c +++ b/src/spicelib/devices/cktinit.c @@ -89,8 +89,8 @@ CKTinit(CKTcircuit **ckt) /* new circuit to create */ sckt->CKTabsDv = 0.5; sckt->CKTrelDv = 2.0; sckt->CKTvarHertz = 0; - sckt->DEVnameHash = nghash_init_pointer(100); - sckt->MODnameHash = nghash_init_pointer(100); + sckt->DEVnameHash = nghash_init(100); + sckt->MODnameHash = nghash_init(100); sckt->CKTepsmin = 1e-28; #ifdef XSPICE diff --git a/src/spicelib/devices/cpl/cplask.c b/src/spicelib/devices/cpl/cplask.c index 4606e0313..9bef294d5 100644 --- a/src/spicelib/devices/cpl/cplask.c +++ b/src/spicelib/devices/cpl/cplask.c @@ -24,12 +24,18 @@ CPLask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *s NG_IGNORE(select); switch(which) { + /* String tables are expected to be freed, but not the strings. */ + case CPL_POS_NODE: - value->v.vec.sVec = here->in_node_names; + value->v.vec.sVec = TMALLOC(char *, here->dimension); + memcpy(value->v.vec.sVec, here->in_node_names, + here->dimension * sizeof (char *)); value->v.numValue = here->dimension; return(OK); case CPL_NEG_NODE: - value->v.vec.sVec = here->out_node_names; + value->v.vec.sVec = TMALLOC(char *, here->dimension); + memcpy(value->v.vec.sVec, here->out_node_names, + here->dimension * sizeof (char *)); value->v.numValue = here->dimension; return(OK); case CPL_DIM: diff --git a/src/spicelib/parser/inpeval.c b/src/spicelib/parser/inpeval.c index 13dcaa81b..bd17eebbf 100644 --- a/src/spicelib/parser/inpeval.c +++ b/src/spicelib/parser/inpeval.c @@ -686,7 +686,7 @@ INPevaluateRKM_C(char** line, int* error, int gobble) } /* In addition to fcn INPevaluate() above, allow values like 4k7, - similar to the RKM code (used by inp2r) */ + similar to the RKM code (used by inp2l) */ double INPevaluateRKM_L(char** line, int* error, int gobble) /* gobble: non-zero to gobble rest of token, zero to leave it alone */ @@ -923,3 +923,217 @@ INPevaluateRKM_L(char** line, int* error, int gobble) pow(10.0, (double)(expo1 + expsgn * expo2))); } + +/* This version will move past the scale factor for the rest of the token */ +double +INPevaluate2(char** line, int* error, int gobble) +/* gobble: non-zero to gobble rest of token, zero to leave it alone */ +{ + char* token; + char* here; + double mantis; + int expo1; + int expo2; + int sign; + int expsgn; + char* tmpline; + + /* setup */ + tmpline = *line; + + if (gobble) { + /* MW. INPgetUTok should be called with gobble=0 or it make + * errors in v(1,2) exp */ + *error = INPgetUTok(line, &token, 0); + if (*error) + return (0.0); + } + else { + token = *line; + *error = 0; + } + + mantis = 0; + expo1 = 0; + expo2 = 0; + sign = 1; + expsgn = 1; + + /* loop through all of the input token */ + here = token; + + if (*here == '+') + here++; /* plus, so do nothing except skip it */ + else if (*here == '-') { /* minus, so skip it, and change sign */ + here++; + sign = -1; + } + + if ((*here == '\0') || ((!(isdigit_c(*here))) && (*here != '.'))) { + /* number looks like just a sign! */ + *error = 1; + if (gobble) { + FREE(token); + /* back out the 'gettok' operation */ + *line = tmpline; + } + return (0); + } + + while (isdigit_c(*here)) { + /* digit, so accumulate it. */ + mantis = 10 * mantis + *here - '0'; + here++; + } + + if (*here == '\0') { + /* reached the end of token - done. */ + if (gobble) { + FREE(token); + } + else { + *line = here; + } + return ((double)mantis * sign); + } + + if (*here == ':') { + /* ':' is no longer used for subcircuit node numbering + but is part of ternary function a?b:c + FIXME : subcircuit models still use ':' for model numbering + Will this hurt somewhere? */ + if (gobble) { + FREE(token); + } + else { + *line = here; + } + return ((double)mantis * sign); + } + + /* after decimal point! */ + if (*here == '.') { + /* found a decimal point! */ + here++; /* skip to next character */ + + if (*here == '\0') { + /* number ends in the decimal point */ + if (gobble) { + FREE(token); + } + else { + *line = here; + } + return ((double)mantis * sign); + } + + while (isdigit_c(*here)) { + /* digit, so accumulate it. */ + mantis = 10 * mantis + *here - '0'; + expo1 = expo1 - 1; + here++; + } + } + + /* now look for "E","e",etc to indicate an exponent */ + if ((*here == 'E') || (*here == 'e') || (*here == 'D') || (*here == 'd')) { + + /* have an exponent, so skip the e */ + here++; + + /* now look for exponent sign */ + if (*here == '+') + here++; /* just skip + */ + else if (*here == '-') { + here++; /* skip over minus sign */ + expsgn = -1; /* and make a negative exponent */ + /* now look for the digits of the exponent */ + } + + while (isdigit_c(*here)) { + expo2 = 10 * expo2 + *here - '0'; + here++; + } + } + + /* now we have all of the numeric part of the number, time to + * look for the scale factor (alphabetic) + */ + switch (*here) { + case 't': + case 'T': + expo1 = expo1 + 12; + here++; + break; + case 'g': + case 'G': + expo1 = expo1 + 9; + here++; + break; + case 'k': + case 'K': + expo1 = expo1 + 3; + here++; + break; + case 'u': + case 'U': + expo1 = expo1 - 6; + here++; + break; + case 'n': + case 'N': + expo1 = expo1 - 9; + here++; + break; + case 'p': + case 'P': + expo1 = expo1 - 12; + here++; + break; + case 'f': + case 'F': + expo1 = expo1 - 15; + here++; + break; + case 'a': + case 'A': + expo1 = expo1 - 18; + here++; + break; + case 'm': + case 'M': + if (((here[1] == 'E') || (here[1] == 'e')) && + ((here[2] == 'G') || (here[2] == 'g'))) + { + expo1 = expo1 + 6; /* Meg */ + here += 3; + } + else if (((here[1] == 'I') || (here[1] == 'i')) && + ((here[2] == 'L') || (here[2] == 'l'))) + { + expo1 = expo1 - 6; + mantis *= 25.4; /* Mil */ + here += 3; + } + else { + expo1 = expo1 - 3; /* m, milli */ + here++; + } + break; + default: + break; + } + + if (gobble) { + FREE(token); + } + else { + *line = here; + } + + return (sign * mantis * + pow(10.0, (double)(expo1 + expsgn * expo2))); +} + + + diff --git a/src/spinit.in b/src/spinit.in index f9bfde40e..ee3794b65 100644 --- a/src/spinit.in +++ b/src/spinit.in @@ -11,7 +11,7 @@ set x11lineararcs *set askquit ** set the number of threads in openmp ** default (if compiled with --enable-openmp) is: 2 -*set num_threads=4 +set num_threads=8 * comment out if central osdi management is set up unset osdi_enabled diff --git a/src/xspice/cmpp/cmpp.h b/src/xspice/cmpp/cmpp.h index ab93f9ce4..ff5bd45c2 100644 --- a/src/xspice/cmpp/cmpp.h +++ b/src/xspice/cmpp/cmpp.h @@ -208,8 +208,8 @@ typedef struct { char *name; /* Name of this parameter */ char *description; /* Description of this parameter */ Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */ - bool has_default; /* True if there is a default value */ - Value_t default_value; /* The default value */ + int default_value_idx;/* Start of default_values.. */ + int default_value_cnt;/* Number of default_values.. */ bool has_lower_limit; /* True if there is a lower limit */ Value_t lower_limit; /* The lower limit for this parameter */ bool has_upper_limit; /* True if there is a upper limit */ @@ -239,7 +239,14 @@ typedef struct { } Inst_Var_Info_t; +/* Structure used when parsing default values from the IFS file, used below. */ +typedef struct { + bool has_value; + bool advance; // Used for vector default values. + Data_Type_t kind; + Value_t u; // Union holding the value. +} My_Value_t; /* * The all encompassing structure for the ifs table information @@ -254,7 +261,8 @@ typedef struct { Param_Info_t *param; /* Array of parameter info structs */ int num_inst_var; /* Number of entries in the instance var table(s) */ Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */ - + int num_default_values; + My_Value_t *defaults_var; /* Array of annotated values. */ } Ifs_Table_t; diff --git a/src/xspice/cmpp/ifs_yacc.y b/src/xspice/cmpp/ifs_yacc.y index 6bc55a3a7..a0a97512d 100644 --- a/src/xspice/cmpp/ifs_yacc.y +++ b/src/xspice/cmpp/ifs_yacc.y @@ -115,16 +115,14 @@ Ifs_Table_t *parser_ifs_table; int ifs_num_errors; -static size_t alloced_size [4]; +/* Allocated and initial sizes of tables for parse results. */ -/* - * !!!!! Make sure these are large enough so that they never get realloced - * !!!!! since that will cause garbage uninitialized data... - * !!!!! (FIX THIS!) - */ -#define DEFAULT_SIZE_CONN 100 -#define DEFAULT_SIZE_PARAM 100 -#define DEFAULT_SIZE_INST_VAR 100 +static size_t alloced_size [5]; + +#define DEFAULT_SIZE_CONN 10 +#define DEFAULT_SIZE_PARAM 10 +#define DEFAULT_SIZE_INST_VAR 10 +#define DEFAULT_SIZE_DEFAULTS 100 #define GROW_SIZE 10 typedef enum { @@ -132,6 +130,7 @@ typedef enum { TBL_PORT, TBL_PARAMETER, TBL_STATIC_VAR, + TBL_DEFAULTS, } Table_t; typedef struct { @@ -368,15 +367,19 @@ assign_limits (Data_Type_t type, Param_Info_t *param, Range_t range) } /*---------------------------------------------------------------------------*/ +/* Advance the item variable, checking for table overflow. */ + static void check_item_num (void) { + item++; if (item-item_offset >= ITEM_BUFFER_SIZE) { - fatal ("Too many items in table - split into sub-tables"); + fatal("Too many items in table - split into sub-tables"); } - if (item > (int) alloced_size [context.table] ) { + if (item >= (int) alloced_size [context.table] ) { switch (context.table) { - case TBL_NAME: + case TBL_NAME: // Fixed size. + case TBL_DEFAULTS: // Handled in store_default_value(). break; case TBL_PORT: alloced_size[context.table] += GROW_SIZE; @@ -407,7 +410,6 @@ check_item_num (void) break; } } - item++; } /*---------------------------------------------------------------------------*/ @@ -429,6 +431,7 @@ check_end_item_num (void) num_items_fixed = true; switch (context.table) { case TBL_NAME: + case TBL_DEFAULTS: break; case TBL_PORT: TBL->num_conn = num_items; @@ -445,11 +448,38 @@ check_end_item_num (void) } #define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = false -#define ITEM check_item_num() -#define END check_end_item_num() +#define ITEM check_item_num() // Advances the item_buffer index. +#define END check_end_item_num() // Check for excessive values in later row. +/* Store a default value for a parameter. */ + +static void store_default_value(My_Value_t *vp) +{ + if (TBL->num_default_values >= alloced_size[TBL_DEFAULTS]) { + /* Expand table. */ + + alloced_size [TBL_DEFAULTS] += GROW_SIZE * 5; + TBL->defaults_var = (My_Value_t *) realloc(TBL->defaults_var, + alloced_size[TBL_DEFAULTS] * sizeof (My_Value_t)); + if (!TBL->defaults_var) { + fatal ("Error allocating memory for default parameter values"); + } + } + TBL->defaults_var[TBL->num_default_values++] = *vp; + if (vp->advance) + ITEM; // Count another parameter sub-table. +} + %} +/* The parser perfoms a double scan for each row (labelled line), with the + * row spanning multiple sub-tables (individual connection definitions etc.). + * Values and other information are copied into the item_buffer[] + * array as they are recognised and then moved to their destination stucture + * TBL->xxxx[index] when the whole row has been parsed. Default parameter + * values are hndled differently and copied directly to TBL->defaults_var. + */ + %token TOK_ALLOWED_TYPES %token TOK_ARRAY %token TOK_ARRAY_BOUNDS @@ -501,6 +531,10 @@ check_end_item_num (void) %token TOK_SPICE_MODEL_NAME %token TOK_STRING_LITERAL + /* This declares the type of Bison's "semantic values" (the value associated + * with an instance of a symbol of the grammer, $$), defining YYSTYPE. + */ + %union { Ctype_List_t *ctype_list; Dir_t dir; @@ -549,6 +583,7 @@ YYSTYPE item_buffer [ITEM_BUFFER_SIZE]; ifs_file : {TBL->num_conn = 0; TBL->num_param = 0; TBL->num_inst_var = 0; + TBL->num_default_values = 0; saw_function_name = false; saw_model_name = false; @@ -556,14 +591,18 @@ ifs_file : {TBL->num_conn = 0; alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN; alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM; alloced_size [TBL_STATIC_VAR] = DEFAULT_SIZE_INST_VAR; + alloced_size [TBL_DEFAULTS] = DEFAULT_SIZE_DEFAULTS; TBL->conn = (Conn_Info_t*) calloc(DEFAULT_SIZE_CONN, sizeof (Conn_Info_t)); TBL->param = (Param_Info_t*) - calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t)); + calloc (DEFAULT_SIZE_PARAM, sizeof (Param_Info_t)); TBL->inst_var = (Inst_Var_Info_t*) - calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t)); - if (! (TBL->conn && TBL->param && TBL->inst_var) ) { + calloc (DEFAULT_SIZE_INST_VAR, sizeof (Inst_Var_Info_t)); + TBL->defaults_var = (My_Value_t *) + calloc(DEFAULT_SIZE_DEFAULTS, sizeof (My_Value_t)); + if (! (TBL->conn && TBL->param && + TBL->inst_var && TBL->defaults_var) ) { fatal ("Could not allocate enough memory"); } } @@ -701,18 +740,8 @@ parameter_table_item : TOK_PARAMETER_NAME list_of_ids check_dtype_not_pointer (ITEM_BUF(i).dtype); TBL->param[i].type = ITEM_BUF(i).dtype; }} - | TOK_DEFAULT_VALUE list_of_values - {int i; - END; - FOR_ITEM (i) { - TBL->param[i].has_default = - ITEM_BUF(i).value.has_value; - if (TBL->param[i].has_default) { - assign_value (TBL->param[i].type, - &TBL->param[i].default_value, - ITEM_BUF(i).value); - } - }} + | TOK_DEFAULT_VALUE list_of_default_values + {END; } // Check against current sub-table count. | TOK_LIMITS list_of_ranges {int i; END; @@ -870,15 +899,22 @@ number_or_dash : TOK_DASH {$$.has_bound = false;} $$.bound = $1;} ; -list_of_values : /* empty */ - | list_of_values value_or_dash {ITEM; BUF.value = $2;} +list_of_pure_values : value { $1.advance = 1; store_default_value(&$1); } + | list_of_pure_values value + { $2.advance = 0; store_default_value(&$2); } ; +list_of_default_values : /* empty */ + | list_of_default_values value_or_dash + { $2.advance = 1; store_default_value(&$2); } + | list_of_default_values + TOK_LBRACKET list_of_pure_values TOK_RBRACKET + value_or_dash : TOK_DASH {$$.has_value = false;} | value ; -value : string {$$.has_value = true; +value : string {$$.has_value = true; $$.kind = CMPP_STRING; $$.u.svalue = $1;} | btype {$$.has_value = true; diff --git a/src/xspice/cmpp/ifs_yacc_y.h b/src/xspice/cmpp/ifs_yacc_y.h index 745e06cd0..88083fcdc 100644 --- a/src/xspice/cmpp/ifs_yacc_y.h +++ b/src/xspice/cmpp/ifs_yacc_y.h @@ -39,18 +39,6 @@ NON-STANDARD FEATURES #include "cmpp.h" -typedef struct { - bool has_value; - Data_Type_t kind; - union { - bool bvalue; - int ivalue; - double rvalue; - Complex_t cvalue; - char *svalue; - } u; -} My_Value_t; - typedef struct { bool has_bound; My_Value_t bound; diff --git a/src/xspice/cmpp/pp_lst.c b/src/xspice/cmpp/pp_lst.c index 1edaaf226..e38ac96ae 100644 --- a/src/xspice/cmpp/pp_lst.c +++ b/src/xspice/cmpp/pp_lst.c @@ -250,7 +250,8 @@ int output_paths_from_lst_file(const char *filename) bool f_have_path = false; /* do not have a path to store */ FBTYPE fbtype; - FBOBJ fbobj; + FBOBJ fbobj = { .dbl_value = 0.0}; // Placate MS compiler. + for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ if (!f_have_path) { @@ -378,7 +379,8 @@ static int read_modpath( bool f_have_path = false; /* do not have a path to store */ FBTYPE fbtype; - FBOBJ fbobj; + FBOBJ fbobj = { .dbl_value = 0.0}; + for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ if (!f_have_path) { @@ -553,7 +555,7 @@ static int read_udnpath( bool f_have_path = false; /* do not have a path to store */ FBTYPE fbtype; - FBOBJ fbobj; + FBOBJ fbobj = { .dbl_value = 0.0}; for ( ; ; ) { /* Read items until end of file */ /* Get the next path if not found yet */ diff --git a/src/xspice/cmpp/writ_ifs.c b/src/xspice/cmpp/writ_ifs.c index 21b46f8af..907451b48 100644 --- a/src/xspice/cmpp/writ_ifs.c +++ b/src/xspice/cmpp/writ_ifs.c @@ -42,6 +42,10 @@ NON-STANDARD FEATURES #include #include #include +#ifndef _MSC_VER +#include +#endif + #include "cmpp.h" /* Local function prototypes */ @@ -183,6 +187,8 @@ EXITPOINT: filename, strerror(errno)); xrc = -1; } + if (xrc < 0 && filename) + unlink(filename); // So "make" will not see it. } if (filename != (char *) NULL) { @@ -680,29 +686,101 @@ static int write_param_info( FILE *fp, /* File to write to */ Ifs_Table_t *ifs_table) /* Table of Interface Specification data */ { - int xrc = 0; - int i; - const char *str; - + Param_Info_t * const param = ifs_table->param; + const int num_param = ifs_table->num_param; + int rc, xrc = 0; + int i, dv_idx; + const char *str; /* Only write the paramTable if there is something to put in it. */ /* Otherwise, we will put NULL in the SPICEdev structure in its slot */ - if (ifs_table->num_param == 0) { + if (num_param <= 0) { return 0; } + /* Write the default values for each parameter. */ - /* Write the structure beginning */ - int rc = 0; + for (i = 0, dv_idx = 0, rc = 0; i < num_param; i++) { + Param_Info_t * p_param_cur = param + i; + My_Value_t * p_val = ifs_table->defaults_var + dv_idx; + int start_index = dv_idx; + + if (dv_idx >= ifs_table->num_default_values) { + fprintf(stderr, "Not enough default values for parameter: %s.\n", + p_param_cur->name); + return 1; + } + + if (!p_val->has_value) { + /* Dummy entry, no default values. */ + + ++dv_idx; + p_param_cur->default_value_cnt = 0; + continue; + } + + if (!p_param_cur->null_allowed) { + fprintf(stderr, + "Default value given for parameter %s but " + "the user must set instance value (Null_Allowed: no).", + p_param_cur->name); + return 1; + } + + rc |= fprintf(fp, + "static union Mif_Parse_Value %s_default[] = {\n", + p_param_cur->name); + + do { // Write the default values for this parameter. + if (!p_val->advance && !p_param_cur->is_array) { + fprintf(stderr, + "Vector initialisation of default values " + "for non-vector parameter: %s.\n", + p_param_cur->name); + return 1; + } + + if (p_val->kind != p_param_cur->type) { + if (p_val->kind == CMPP_INTEGER && + p_param_cur->type == CMPP_REAL) { + /* Promote it. */ + + p_val->u.rvalue = p_val->u.ivalue; + } else { + fprintf(stderr, + "Data type of default value does not match for " + "parameter: %s.\n", + p_param_cur->name); + return 1; + } + } + + str = value_to_str(p_param_cur->type, p_val->u); + rc |= fprintf(fp, " %s,\n", str); + ++dv_idx; ++p_val; + } while (dv_idx < ifs_table->num_default_values && !p_val->advance); + + rc |= fprintf(fp, "};\n\n"); + p_param_cur->default_value_cnt = dv_idx - start_index; + } + + /* Check outputs */ + + if (rc < 0) { + print_error("Writing of default param values failed."); + return -1; + } + + /* Write the main parameter structure beginning. */ + + rc = 0; rc |= fprintf(fp, "\n" "static Mif_Param_Info_t MIFparamTable[] = {\n"); - /* Write out an entry for each parameter in the table */ - const Param_Info_t * const param = ifs_table->param; - const int num_param = ifs_table->num_param; + for (i = 0; i < num_param; i++) { const Param_Info_t * const p_param_cur = param + i; @@ -713,14 +791,11 @@ static int write_param_info( rc |= fprintf(fp, " %s,\n", data_type_to_str(p_param_cur->type)); - str = boolean_to_str(p_param_cur->has_default); - rc |= fprintf(fp, " %s,\n", str); - - if (p_param_cur->has_default == true) - str = value_to_str(p_param_cur->type, p_param_cur->default_value); + rc |= fprintf(fp, " %d,\n", p_param_cur->default_value_cnt); + if (p_param_cur->default_value_cnt) + rc |= fprintf(fp, " %s_default,\n", p_param_cur->name); else - str = no_value_to_str(); - rc |= fprintf(fp, " %s,\n", str); + rc |= fprintf(fp, " NULL,\n"); str = boolean_to_str(p_param_cur->has_lower_limit); rc |= fprintf(fp, " %s,\n", str); @@ -1205,20 +1280,20 @@ static char *value_to_str(Data_Type_t type, Value_t value) case CMPP_BOOLEAN: bool_str = boolean_to_str(value.bvalue); - sprintf(str, "{%s, 0, 0.0, {0.0, 0.0}, NULL}", bool_str); + sprintf(str, "{ .bvalue=%s }", bool_str); break; case CMPP_INTEGER: - sprintf(str, "{MIF_FALSE, %d, 0.0, {0.0, 0.0}, NULL}", value.ivalue); + sprintf(str, "{ .ivalue=%d }", value.ivalue); break; case CMPP_REAL: - sprintf(str, "{MIF_FALSE, 0, %e, {0.0, 0.0}, NULL}", value.rvalue); + sprintf(str, "{ .rvalue=%e }", value.rvalue); break; case CMPP_COMPLEX: - sprintf(str, "{MIF_FALSE, 0, 0.0, {%e, %e}, NULL}", - value.cvalue.real, value.cvalue.imag); + sprintf(str, "{ .cvalue={%e, %e} }", + value.cvalue.real, value.cvalue.imag); break; case CMPP_STRING: @@ -1238,7 +1313,7 @@ static char *value_to_str(Data_Type_t type, Value_t value) max_len += str_len; } /* end of resize */ - sprintf(str, "{MIF_FALSE, 0, 0.0, {0.0, 0.0}, \"%s\"}", value.svalue); + sprintf(str, "{ .svalue=\"%s\" }", value.svalue); break; default: @@ -1273,8 +1348,5 @@ static char *integer_to_str(int value) static const char *no_value_to_str(void) { - return "{MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL}"; + return "{ .bvalue=MIF_FALSE }"; } - - - diff --git a/src/xspice/evt/evtload.c b/src/xspice/evt/evtload.c index a0b75326a..cd570805c 100644 --- a/src/xspice/evt/evtload.c +++ b/src/xspice/evt/evtload.c @@ -108,7 +108,6 @@ int EVTload_with_event( Evt_Node_Data_t *node_data; Mif_Private_t cm_data; - void *value_ptr; /* ***************************** */ /* Prepare the code model inputs */ diff --git a/src/xspice/icm/analog/multi_input_pwl/ifspec.ifs b/src/xspice/icm/analog/multi_input_pwl/ifspec.ifs index 852c2bda9..0da489a85 100644 --- a/src/xspice/icm/analog/multi_input_pwl/ifspec.ifs +++ b/src/xspice/icm/analog/multi_input_pwl/ifspec.ifs @@ -15,7 +15,7 @@ AUTHORS SUMMARY - This file contains the interface specification file for the + This file contains the interface specification file for the analog multi-input gate pwl code model. ===============================================================================*/ @@ -44,7 +44,7 @@ PARAMETER_TABLE: Parameter_Name: x y model Description: "x array" "y array" "model type" Data_Type: real real string -Default_Value: 0.0 0.0 "and" +Default_Value: - - "and" Limits: - - - Vector: yes yes no Vector_Bounds: [2 -] [2 -] - diff --git a/src/xspice/icm/analog/oneshot/ifspec.ifs b/src/xspice/icm/analog/oneshot/ifspec.ifs index b56ac2aa4..e14464ab3 100644 --- a/src/xspice/icm/analog/oneshot/ifspec.ifs +++ b/src/xspice/icm/analog/oneshot/ifspec.ifs @@ -6,14 +6,14 @@ Georgia Tech Research Corporation Atlanta, Georgia 30332 -AUTHORS +AUTHORS 20 Mar 1991 Harry Li SUMMARY - This file contains the interface specification file for the + This file contains the interface specification file for the analog oneshot code model. ===============================================================================*/ @@ -28,92 +28,92 @@ Description: "one-shot" PORT_TABLE: -Port_Name: clk cntl_in -Description: "clock input" "input" -Direction: in in +Port_Name: clk cntl_in +Description: "clock input" "input" +Direction: in in Default_Type: v v -Allowed_Types: [v,vd,vnam,i,id] [v,vnam,vd,i,id] -Vector: no no -Vector_Bounds: - - -Null_Allowed: no yes +Allowed_Types: [v,vd,vnam,i,id] [v,vnam,vd,i,id] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no yes PORT_TABLE: Port_Name: clear out Description: "clear signal" "output" -Direction: in out +Direction: in out Default_Type: v v -Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id] -Vector: no no -Vector_Bounds: - - +Allowed_Types: [v,vd,vnam,i,id] [v,vd,i,id] +Vector: no no +Vector_Bounds: - - Null_Allowed: yes no PARAMETER_TABLE: -Parameter_Name: cntl_array pw_array +Parameter_Name: cntl_array pw_array Description: "control in array" "pulse width array" -Data_Type: real real -Default_Value: 0.0 1.0e-6 -Limits: - [0 -] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Data_Type: real real +Default_Value: [0.0 1.0] [1.0e-6 0.9999999] +Limits: - [0 -] +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: Parameter_Name: clk_trig pos_edge_trig Description: "clock trigger value" "pos/neg edge trigger switch" -Data_Type: real boolean -Default_Value: 0.5 TRUE -Limits: - - -Vector: no no -Vector_Bounds: - - -Null_Allowed: no no +Data_Type: real boolean +Default_Value: 0.5 TRUE +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: Parameter_Name: out_low out_high Description: "output low value" "output high value" -Data_Type: real real -Default_Value: 0.0 1.0 -Limits: - - -Vector: no no -Vector_Bounds: - - +Data_Type: real real +Default_Value: 0.0 1.0 +Limits: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes PARAMETER_TABLE: Parameter_Name: rise_time -Description: "output rise time" -Data_Type: real -Default_Value: 1.0e-9 -Limits: - -Vector: no -Vector_Bounds: - +Description: "output rise time" +Data_Type: real +Default_Value: 1.0e-9 +Limits: - +Vector: no +Vector_Bounds: - Null_Allowed: yes PARAMETER_TABLE: -Parameter_Name: rise_delay fall_delay -Description: "output delay from trigger" "output delay from pw" -Data_Type: real real -Default_Value: 1.0e-9 1.0e-9 +Parameter_Name: rise_delay fall_delay +Description: "output delay from trigger" "output delay from pw" +Data_Type: real real +Default_Value: 1.0e-9 1.0e-9 Limits: - - -Vector: no no -Vector_Bounds: - - -Null_Allowed: yes yes +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: Parameter_Name: fall_time retrig -Description: "output rise time" "retrigger switch" +Description: "output rise time" "retrigger switch" Data_Type: real boolean Default_Value: 1.0e-9 FALSE Limits: - - -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes diff --git a/src/xspice/icm/analog/sine/ifspec.ifs b/src/xspice/icm/analog/sine/ifspec.ifs index 96895294b..747b193a9 100644 --- a/src/xspice/icm/analog/sine/ifspec.ifs +++ b/src/xspice/icm/analog/sine/ifspec.ifs @@ -33,8 +33,8 @@ Description: "input" "output" Direction: in out Default_Type: v v Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: no no PARAMETER_TABLE: @@ -42,11 +42,11 @@ PARAMETER_TABLE: Parameter_Name: cntl_array freq_array Description: "control in array" "frequency array" Data_Type: real real -Default_Value: 0.0 1.0e3 +Default_Value: [0.0 1.0] [1.0e3 2.0e3] Limits: - [0 -] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: @@ -56,7 +56,6 @@ Description: "output low value" "output high value" Data_Type: real real Default_Value: -1.0 1.0 Limits: - - -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes - diff --git a/src/xspice/icm/analog/square/ifspec.ifs b/src/xspice/icm/analog/square/ifspec.ifs index 9a350445e..9f4fc7aca 100644 --- a/src/xspice/icm/analog/square/ifspec.ifs +++ b/src/xspice/icm/analog/square/ifspec.ifs @@ -33,8 +33,8 @@ Description: "input" "output" Direction: in out Default_Type: v v Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: no no PARAMETER_TABLE: @@ -42,11 +42,11 @@ PARAMETER_TABLE: Parameter_Name: cntl_array freq_array Description: "control in array" "frequency array" Data_Type: real real -Default_Value: 0.0 1.0e3 +Default_Value: [0.0 1.0] [1.0e3 2.0e3] Limits: - [0 -] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: @@ -56,8 +56,8 @@ Description: "output low value" "output high value" Data_Type: real real Default_Value: -1.0 1.0 Limits: - - -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes PARAMETER_TABLE: @@ -67,8 +67,8 @@ Description: "duty cycle" "rise time" Data_Type: real real Default_Value: 0.5 1.0e-9 Limits: [1e-6 .999999] - -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes PARAMETER_TABLE: @@ -78,8 +78,8 @@ Description: "fall time" Data_Type: real Default_Value: 1.0e-9 Limits: - -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: yes diff --git a/src/xspice/icm/analog/triangle/ifspec.ifs b/src/xspice/icm/analog/triangle/ifspec.ifs index ad870f93a..075d8b3e8 100644 --- a/src/xspice/icm/analog/triangle/ifspec.ifs +++ b/src/xspice/icm/analog/triangle/ifspec.ifs @@ -28,25 +28,25 @@ Description: "controlled triangle wave oscillator" PORT_TABLE: -Port_Name: cntl_in out -Description: "input" "output" -Direction: in out -Default_Type: v v -Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] -Vector: no no -Vector_Bounds: - - -Null_Allowed: no no +Port_Name: cntl_in out +Description: "input" "output" +Direction: in out +Default_Type: v v +Allowed_Types: [v,vd,i,id,vnam] [v,vd,i,id] +Vector: no no +Vector_Bounds: - - +Null_Allowed: no no PARAMETER_TABLE: Parameter_Name: cntl_array freq_array Description: "control in array" "frequency array" Data_Type: real real -Default_Value: 0.0 1.0e3 +Default_Value: [0.0 1.0] [1.0e3 2.0e3] Limits: - [0 -] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: diff --git a/src/xspice/icm/digital/bidi_bridge/cfunc.mod b/src/xspice/icm/digital/bidi_bridge/cfunc.mod index 6f9371b4a..2776723e6 100644 --- a/src/xspice/icm/digital/bidi_bridge/cfunc.mod +++ b/src/xspice/icm/digital/bidi_bridge/cfunc.mod @@ -147,7 +147,7 @@ void cm_bidi_bridge(ARGS) out = 0.0; /* AtoD, no analogue output. */ svoc = 0.5; } else { - double target, iota, interval[2], range, partial; + double target, iota, interval[2], range, partial = 0.0; int step, step_count; Digital_t drive, *dp; @@ -274,7 +274,6 @@ void cm_bidi_bridge(ARGS) voc = out_low + (out_high - out_low) * voc; target = 0.0; - partial = 0.0; /* Calculate new value for output current. */ diff --git a/src/xspice/icm/digital/d_cosim/cfunc.mod b/src/xspice/icm/digital/d_cosim/cfunc.mod index e85d9e5f7..c22b393f4 100644 --- a/src/xspice/icm/digital/d_cosim/cfunc.mod +++ b/src/xspice/icm/digital/d_cosim/cfunc.mod @@ -140,9 +140,9 @@ void accept_output(struct co_info *pinfo, unsigned int bit_num, Digital_t *val) static void output(struct instance *ip, ARGS) { - double delay; - Digital_t *out_vals; // XSPICE rotating memory - int i, j; + double delay; + Digital_t *out_vals; // XSPICE rotating memory + unsigned int i, j; delay = PARAM(delay) - (TIME - ip->info.vtime); if (delay <= 0) { @@ -314,7 +314,7 @@ static bool check_input(struct instance *ip, Digital_t *ovp, { if (ovp->state != rp->what.state || ovp->strength != rp->what.strength) { - if (++ip->q_index < ip->q_length) { + if (++ip->q_index < (int) ip->q_length) { /* Record this event. */ ip->q[ip->q_index] = *rp; @@ -345,10 +345,10 @@ void ucm_d_cosim(ARGS) { struct instance *ip; Digital_t *in_vals; // XSPICE rotating memory - int i, index; + unsigned int i, index; if (INIT) { - int ins, outs, inouts; + unsigned int ins, outs, inouts; unsigned int alloc_size; void *handle; void (*ifp)(struct co_info *); @@ -380,7 +380,7 @@ void ucm_d_cosim(ARGS) cm_message_send(dlerror()); return; } - ifp = dlsym(handle, "Cosim_setup"); + ifp = (void (*)(struct co_info *))dlsym(handle, "Cosim_setup"); if (*ifp == NULL) { cm_message_printf("ERROR: no entry function in %s", fn); cm_message_send(dlerror()); @@ -468,7 +468,7 @@ void ucm_d_cosim(ARGS) ip = STATIC_VAR(cosim_instance); if (!ip) { - int ports; + unsigned int ports; /* Error state. Do nothing at all. */ diff --git a/src/xspice/icm/digital/d_genlut/ifspec.ifs b/src/xspice/icm/digital/d_genlut/ifspec.ifs index c29c537be..831cdc038 100644 --- a/src/xspice/icm/digital/d_genlut/ifspec.ifs +++ b/src/xspice/icm/digital/d_genlut/ifspec.ifs @@ -64,7 +64,7 @@ PARAMETER_TABLE: Parameter_Name: table_values Description: "lookup table values" Data_Type: string -Default_Value: "0" +Default_Value: - Limits: - Vector: no Vector_Bounds: - diff --git a/src/xspice/icm/digital/d_lut/ifspec.ifs b/src/xspice/icm/digital/d_lut/ifspec.ifs index 05f6ca6e0..7e3fb1f2e 100644 --- a/src/xspice/icm/digital/d_lut/ifspec.ifs +++ b/src/xspice/icm/digital/d_lut/ifspec.ifs @@ -55,8 +55,8 @@ Description: "input load value (F)" Data_Type: real Default_Value: 1.0e-12 Limits: - -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: yes PARAMETER_TABLE: @@ -64,10 +64,10 @@ PARAMETER_TABLE: Parameter_Name: table_values Description: "lookup table values" Data_Type: string -Default_Value: "0" +Default_Value: - Limits: - -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: no STATIC_VAR_TABLE: diff --git a/src/xspice/icm/digital/d_osc/cfunc.mod b/src/xspice/icm/digital/d_osc/cfunc.mod index 8a598bd89..ab15042cd 100644 --- a/src/xspice/icm/digital/d_osc/cfunc.mod +++ b/src/xspice/icm/digital/d_osc/cfunc.mod @@ -17,8 +17,6 @@ struct pwl { static void cm_d_osc_callback(ARGS, Mif_Callback_Reason_t reason) { - struct panel_instance *instance; - if (reason == MIF_CB_DESTROY) { struct pwl *table = STATIC_VAR(locdata); diff --git a/src/xspice/icm/digital/d_osc/ifspec.ifs b/src/xspice/icm/digital/d_osc/ifspec.ifs index b70c86058..5bc4e70ec 100644 --- a/src/xspice/icm/digital/d_osc/ifspec.ifs +++ b/src/xspice/icm/digital/d_osc/ifspec.ifs @@ -32,8 +32,8 @@ Description: "control input" "output" Direction: in out Default_Type: v d Allowed_Types: [v,vd,i,id] [d] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: no no @@ -43,11 +43,11 @@ PARAMETER_TABLE: Parameter_Name: cntl_array freq_array Description: "control array" "frequency array" Data_Type: real real -Default_Value: 0.0 1.0e6 +Default_Value: [0.0 1.0] [1.0e6 2.0e6] Limits: - [0 -] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: diff --git a/src/xspice/icm/digital/d_process/ifspec.ifs b/src/xspice/icm/digital/d_process/ifspec.ifs index 07da5123c..33d6fe235 100644 --- a/src/xspice/icm/digital/d_process/ifspec.ifs +++ b/src/xspice/icm/digital/d_process/ifspec.ifs @@ -70,7 +70,7 @@ PARAMETER_TABLE: Parameter_Name: process_file Description: "file name of the executable process" Data_Type: string -Default_Value: "process" +Default_Value: - Limits: - Vector: no Vector_Bounds: - @@ -100,7 +100,7 @@ Default_Value: 0 Limits: - Vector: no Vector_Bounds: - -Null_Allowed: no +Null_Allowed: yes PARAMETER_TABLE: @@ -113,7 +113,7 @@ Default_Value: 1.0e-12 Limits: - Vector: no Vector_Bounds: - -Null_Allowed: no +Null_Allowed: yes PARAMETER_TABLE: @@ -126,7 +126,7 @@ Default_Value: 1.0e-12 Limits: - Vector: no Vector_Bounds: - -Null_Allowed: no +Null_Allowed: yes PARAMETER_TABLE: @@ -138,7 +138,7 @@ Default_Value: 1.0e-12 Limits: - Vector: no Vector_Bounds: - -Null_Allowed: no +Null_Allowed: yes STATIC_VAR_TABLE: diff --git a/src/xspice/icm/digital/d_pwm/ifspec.ifs b/src/xspice/icm/digital/d_pwm/ifspec.ifs index cde238f16..31dfb02e0 100644 --- a/src/xspice/icm/digital/d_pwm/ifspec.ifs +++ b/src/xspice/icm/digital/d_pwm/ifspec.ifs @@ -34,8 +34,8 @@ Description: "control input" "output" Direction: in out Default_Type: v d Allowed_Types: [v,vd,i,id] [d] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: no no @@ -45,11 +45,11 @@ PARAMETER_TABLE: Parameter_Name: cntl_array dc_array Description: "control array" "duty cycle array" Data_Type: real real -Default_Value: 0.0 0.5 -Limits: - [0 1] -Vector: yes yes -Vector_Bounds: [2 -] [2 -] -Null_Allowed: no no +Default_Value: [-1 1] [0 1] +Limits: - [0 1] +Vector: yes yes +Vector_Bounds: [2 -] [2 -] +Null_Allowed: yes yes PARAMETER_TABLE: @@ -59,9 +59,9 @@ Description: "oscillator frequency" "initial phase of output" Data_Type: real real Default_Value: 1e6 0 Limits: [1e-6 -] [-180.0 +360.0] -Vector: no no -Vector_Bounds: - - -Null_Allowed: yes yes +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: @@ -71,9 +71,9 @@ Description: "rise delay" "fall delay" Data_Type: real real Default_Value: 1e-9 1e-9 Limits: [0 -] [0 -] -Vector: no no -Vector_Bounds: - - -Null_Allowed: yes yes +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes STATIC_VAR_TABLE: diff --git a/src/xspice/icm/digital/d_source/ifspec.ifs b/src/xspice/icm/digital/d_source/ifspec.ifs index d8cc2778b..0739838de 100644 --- a/src/xspice/icm/digital/d_source/ifspec.ifs +++ b/src/xspice/icm/digital/d_source/ifspec.ifs @@ -14,7 +14,7 @@ AUTHORS SUMMARY - This file contains the interface specification file for the + This file contains the interface specification file for the digital d_source code model. ===============================================================================*/ @@ -33,8 +33,8 @@ Description: "output" Direction: out Default_Type: d Allowed_Types: [d] -Vector: yes -Vector_Bounds: - +Vector: yes +Vector_Bounds: - Null_Allowed: no @@ -42,25 +42,25 @@ Null_Allowed: no PARAMETER_TABLE: Parameter_Name: input_file -Description: "digital input vector filename" -Data_Type: string -Default_Value: "source.txt" -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "digital input vector filename" +Data_Type: string +Default_Value: "source.txt" +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes PARAMETER_TABLE: Parameter_Name: input_load -Description: "input loading capacitance (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "input loading capacitance (F)" +Data_Type: real +Default_Value: 1.0e-12 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes STATIC_VAR_TABLE: diff --git a/src/xspice/icm/digital/d_state/ifspec.ifs b/src/xspice/icm/digital/d_state/ifspec.ifs index dcb8efa0c..3f1197ff0 100644 --- a/src/xspice/icm/digital/d_state/ifspec.ifs +++ b/src/xspice/icm/digital/d_state/ifspec.ifs @@ -13,7 +13,7 @@ AUTHORS SUMMARY - This file contains the interface specification file for the + This file contains the interface specification file for the digital d_state (state machine) code model. ===============================================================================*/ @@ -35,8 +35,8 @@ Description: "input" "clock" Direction: in in Default_Type: d d Allowed_Types: [d] [d] -Vector: yes no -Vector_Bounds: - - +Vector: yes no +Vector_Bounds: - - Null_Allowed: yes no @@ -48,8 +48,8 @@ Description: "reset" "output" Direction: in out Default_Type: d d Allowed_Types: [d] [d] -Vector: no yes -Vector_Bounds: - [1 -] +Vector: no yes +Vector_Bounds: - [1 -] Null_Allowed: yes no @@ -61,73 +61,75 @@ Parameter_Name: clk_delay reset_delay Description: "delay from CLK" "delay from reset" Data_Type: real real Default_Value: 1.0e-9 1.0e-9 -Limits: - - -Vector: no no -Vector_Bounds: - - -Null_Allowed: yes yes +Limits: - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: Parameter_Name: state_file -Description: "state transition specification file name" -Data_Type: string -Default_Value: "state.txt" -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "state transition specification file name" +Data_Type: string +Default_Value: "state.txt" +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes PARAMETER_TABLE: Parameter_Name: reset_state -Description: "default state on RESET & at DC" -Data_Type: int -Default_Value: 0 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "default state on RESET & at DC" +Data_Type: int +Default_Value: 0 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes PARAMETER_TABLE: Parameter_Name: input_load -Description: "input loading capacitance (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "input loading capacitance (F)" +Data_Type: real +Default_Value: 1.0e-12 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes PARAMETER_TABLE: Parameter_Name: clk_load -Description: "clock loading capacitance (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "clock loading capacitance (F)" +Data_Type: real +Default_Value: 1.0e-12 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes + + PARAMETER_TABLE: Parameter_Name: reset_load -Description: "reset loading capacitance (F)" -Data_Type: real -Default_Value: 1.0e-12 -Limits: - -Vector: no -Vector_Bounds: - -Null_Allowed: no +Description: "reset loading capacitance (F)" +Data_Type: real +Default_Value: 1.0e-12 +Limits: - +Vector: no +Vector_Bounds: - +Null_Allowed: yes STATIC_VAR_TABLE: diff --git a/src/xspice/icm/dlmain.c b/src/xspice/icm/dlmain.c index b86839e34..8c005cf56 100644 --- a/src/xspice/icm/dlmain.c +++ b/src/xspice/icm/dlmain.c @@ -13,6 +13,7 @@ #include #include +#include "ngspice/config.h" #include "ngspice/cpextern.h" #include "ngspice/devdefs.h" #include "ngspice/dstring.h" diff --git a/src/xspice/icm/table/table3D/cfunc.mod b/src/xspice/icm/table/table3D/cfunc.mod index 606dc1dc6..a9c2d318a 100644 --- a/src/xspice/icm/table/table3D/cfunc.mod +++ b/src/xspice/icm/table/table3D/cfunc.mod @@ -8,7 +8,7 @@ FILE table3D/cfunc.mod The ngspice team All Rights Reserved GPL - (see COPYING or https://opensource.org/licenses/BSD-3-Clause) + (see COPYING or https://opensource.org/licenses/GPL-2.0) ------------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify diff --git a/src/xspice/icm/xtradev/capacitor/ifspec.ifs b/src/xspice/icm/xtradev/capacitor/ifspec.ifs index 453296848..7e41bb5ad 100644 --- a/src/xspice/icm/xtradev/capacitor/ifspec.ifs +++ b/src/xspice/icm/xtradev/capacitor/ifspec.ifs @@ -51,8 +51,8 @@ Description: "capacitor terminals" Direction: inout Default_Type: hd Allowed_Types: [hd] -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: no @@ -63,9 +63,6 @@ Description: "capacitance" "voltage initial condition" Data_Type: real real Default_Value: - 0.0 Limits: - - -Vector: no no -Vector_Bounds: - - -Null_Allowed: no no - - - +Vector: no no +Vector_Bounds: - - +Null_Allowed: no yes \ No newline at end of file diff --git a/src/xspice/icm/xtradev/inductor/ifspec.ifs b/src/xspice/icm/xtradev/inductor/ifspec.ifs index 05ea7cf91..aedf800ed 100644 --- a/src/xspice/icm/xtradev/inductor/ifspec.ifs +++ b/src/xspice/icm/xtradev/inductor/ifspec.ifs @@ -51,8 +51,8 @@ Description: "inductor terminals" Direction: inout Default_Type: gd Allowed_Types: [gd] -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: no @@ -63,8 +63,8 @@ Description: "inductance" "current initial condition" Data_Type: real real Default_Value: - 0.0 Limits: - - -Vector: no no -Vector_Bounds: - - -Null_Allowed: no no +Vector: no no +Vector_Bounds: - - +Null_Allowed: no yes diff --git a/src/xspice/icm/xtradev/memristor/ifspec.ifs b/src/xspice/icm/xtradev/memristor/ifspec.ifs index 7080d7e87..1002b2a7d 100644 --- a/src/xspice/icm/xtradev/memristor/ifspec.ifs +++ b/src/xspice/icm/xtradev/memristor/ifspec.ifs @@ -25,10 +25,10 @@ SUMMARY This file contains the definition of a memristor code model with threshold according to - Y. V. Pershin, M. Di Ventra: "SPICE model of memristive devices with threshold", - arXiv:1204.2600v1 [physics.comp-ph] 12 Apr 2012, + Y. V. Pershin, M. Di Ventra: "SPICE model of memristive devices with threshold", + arXiv:1204.2600v1 [physics.comp-ph] 12 Apr 2012, http://arxiv.org/pdf/1204.2600.pdf. - + ** Experimental, still to be tested in circuits !! ** INTERFACES @@ -59,8 +59,8 @@ Description: "memristor terminals" Direction: inout Default_Type: gd Allowed_Types: [gd] -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: no @@ -71,9 +71,9 @@ Description: "minimum resistance" "maximum resistance" "initial Data_Type: real real real Default_Value: 10.0 10000.0 7000.0 Limits: - - - -Vector: no no no -Vector_Bounds: - - - -Null_Allowed: no no no +Vector: no no no +Vector_Bounds: - - - +Null_Allowed: yes yes yes PARAMETER_TABLE: @@ -84,6 +84,6 @@ Default_Value: 0.0 1.0 0.0 Limits: - - - Vector: no no no Vector_Bounds: - - - -Null_Allowed: no no no +Null_Allowed: yes yes yes diff --git a/src/xspice/icm/xtradev/pswitch/cfunc.mod b/src/xspice/icm/xtradev/pswitch/cfunc.mod index d0cf2ff43..3b8d0b6a3 100644 --- a/src/xspice/icm/xtradev/pswitch/cfunc.mod +++ b/src/xspice/icm/xtradev/pswitch/cfunc.mod @@ -177,8 +177,8 @@ void cm_pswitch(ARGS) /* structure holding parms, r_off = (r_off > 1.0e12) ? 1.0e12 : r_off; /* Set maximum 'OFF' resistance */ - if(INIT == 1) { /* first time through, allocate memory, set static parameters */ - char *cntl_error = "\n*****ERROR*****\nPSWITCH: CONTROL voltage delta less than 1.0e-12\n"; + if(INIT == 1) { + /* First time through, allocate memory, set static parameters. */ cntl_on = PARAM(cntl_on); cntl_off = PARAM(cntl_off); diff --git a/src/xspice/icm/xtradev/sidiode/ifspec.ifs b/src/xspice/icm/xtradev/sidiode/ifspec.ifs index 33614c7f7..ba0754e93 100644 --- a/src/xspice/icm/xtradev/sidiode/ifspec.ifs +++ b/src/xspice/icm/xtradev/sidiode/ifspec.ifs @@ -36,8 +36,8 @@ Description: "diode port" Direction: inout Default_Type: gd Allowed_Types: [gd] -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: no @@ -49,9 +49,9 @@ Description: "resistance on-state" "resistance off-state" Data_Type: real real Default_Value: 1 1 Limits: [1e-6 - ] [1e-12 -] -Vector: no no -Vector_Bounds: - - -Null_Allowed: no no +Vector: no no +Vector_Bounds: - - +Null_Allowed: yes yes PARAMETER_TABLE: @@ -61,7 +61,7 @@ Description: "forward voltage" "reverse breakdown voltage" Data_Type: real real Default_Value: 0. 1e30 Limits: [0. -] [0. -] -Vector: no no +Vector: no no Vector_Bounds: - - Null_Allowed: yes yes @@ -74,8 +74,8 @@ Description: "limit of on-current" "limit of breakdown current" Data_Type: real real Default_Value: 1e30 1e30 Limits: [1e-15 -] [1e-15 -] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes @@ -86,8 +86,8 @@ Description: "width quadrat. r 1" "width quadratic region 2" Data_Type: real real Default_Value: 0. 0. Limits: [0. -] [0. -] -Vector: no no -Vector_Bounds: - - +Vector: no no +Vector_Bounds: - - Null_Allowed: yes yes @@ -99,8 +99,8 @@ Description: "resistance in breakdown" Data_Type: real Default_Value: 0. Limits: - -Vector: no -Vector_Bounds: - +Vector: no +Vector_Bounds: - Null_Allowed: yes diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c index e09d8c378..1368b9ba2 100644 --- a/src/xspice/mif/mif_inp2.c +++ b/src/xspice/mif/mif_inp2.c @@ -567,28 +567,33 @@ MIF_INP2A ( param_info = &(DEVices[type]->DEVpublic.param[i]); - if(mdfast->param[i]->is_null) { - char* emessage; + if (mdfast->param[i]->is_null) { + char* emessage = NULL; - if(! param_info->has_default) { + if (!param_info->null_allowed) { + emessage = tprintf("Null not allowed for parameter %s " + "on model %s.", + param_info->name, mdfast->gen.GENmodName); + } else if (param_info->default_value_siz == 0) { if (param_info->type == MIF_STRING) continue; // Allow NULL emessage = tprintf("Parameter %s on model %s has no default", param_info->name, mdfast->gen.GENmodName); + } + + if (emessage) { LITERR(emessage); tfree(emessage); gc_end(); return; } - } - if((! mdfast->param[i]->is_null) && (param_info->is_array)) { - if(param_info->has_conn_ref) { - if(fast[0]->conn[param_info->conn_ref]->size != fast[0]->param[i]->size) { - LITERR("Array parameter size on model does not match connection size"); - gc_end(); - return; - } - } + } else if (param_info->is_array && param_info->has_conn_ref && + fast[0]->conn[param_info->conn_ref]->size != + fast[0]->param[i]->size) { + LITERR("Array parameter size on model does not match " + "connection size"); + gc_end(); + return; } } gc_end(); diff --git a/src/xspice/mif/mifsetup.c b/src/xspice/mif/mifsetup.c index 8bac8705f..f280503a2 100644 --- a/src/xspice/mif/mifsetup.c +++ b/src/xspice/mif/mifsetup.c @@ -135,7 +135,6 @@ MIFsetup( for( ; model != NULL; model = MIFnextModel(model)) { - /* For each parameter not given explicitly on the .model */ /* card, default it */ @@ -151,42 +150,66 @@ MIFsetup( model->param[i]->size = 1; model->param[i]->element = TMALLOC(Mif_Value_t, 1); } else { /* parameter is an array */ - /* MIF_INP2A() parser assures that there is an associated array connection */ - /* Since several instances may share this model, we have to create an array */ - /* big enough for the instance with the biggest connection array */ - max_size = 0; - for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) { - size = here->conn[param_info->conn_ref]->size; - if(size > max_size) - max_size = size; + /* If there is an associated array connection, take the + * size from there. Since several instances may share + * this model, create an array big enough for the + * instance with the biggest connection array. + * Otherwise, use the size of the default. + */ + + if (param_info->has_conn_ref) { + for (here = MIFinstances(model), max_size = 0; + here != NULL; + here = MIFnextInstance(here)) { + size = here->conn[param_info->conn_ref]->size; + if (size > max_size) + max_size = size; + } + } else { + max_size = param_info->default_value_siz; + if (param_info->has_lower_bound && + param_info->lower_bound > max_size) { + max_size = param_info->lower_bound; + } } model->param[i]->size = max_size; model->param[i]->element = TMALLOC(Mif_Value_t, max_size); } /* end if parameter is an array */ - /* set the parameter element(s) to default value */ - for(j = 0; j < model->param[i]->size; j++) { + if (param_info->default_value_siz == 0) + continue; + /* Set the parameter element(s) to default value(s). */ + + for(j = 0; j < model->param[i]->size; j++) { + Mif_Parse_Value_t *dvp; + + if (j >= param_info->default_value_siz) { + dvp = param_info->default_values + + param_info->default_value_siz - 1; + } else { + dvp = param_info->default_values + j; + } switch(param_info->type) { case MIF_BOOLEAN: - model->param[i]->element[j].bvalue = param_info->default_value.bvalue; + model->param[i]->element[j].bvalue = dvp->bvalue; break; case MIF_INTEGER: - model->param[i]->element[j].ivalue = param_info->default_value.ivalue; + model->param[i]->element[j].ivalue = dvp->ivalue; break; case MIF_REAL: - model->param[i]->element[j].rvalue = param_info->default_value.rvalue; + model->param[i]->element[j].rvalue = dvp->rvalue; break; case MIF_COMPLEX: - model->param[i]->element[j].cvalue = param_info->default_value.cvalue; + model->param[i]->element[j].cvalue = dvp->cvalue; break; case MIF_STRING: - model->param[i]->element[j].svalue = param_info->default_value.svalue; + model->param[i]->element[j].svalue = dvp->svalue; break; default: diff --git a/visualc/spinit_all b/visualc/spinit_all index ba2a29ec5..21bdae5ef 100644 --- a/visualc/spinit_all +++ b/visualc/spinit_all @@ -11,8 +11,8 @@ set filetype=ascii *set askquit ** set the number of threads in openmp ** default (if compiled with --enable-openmp) is: 2 -set num_threads=4 -set interactive +set num_threads=8 +*set interactive * comment out if central osdi management is set up unset osdi_enabled @@ -38,7 +38,7 @@ if $?osdi_enabled osdi ../lib/ngspice/BSIMBULK107.osdi osdi ../lib/ngspice/BSIMCMG.osdi osdi ../lib/ngspice/HICUMl0-2.0.osdi - osdi ../lib/ngspice/psp103.osdi + osdi ../lib/ngspice/psp103_nqs.osdi osdi ../lib/ngspice/r2_cmc.osdi osdi ../lib/ngspice/vbic_4T_et_cf.osdi diff --git a/visualc/spinitd b/visualc/spinitd index 2fbad4772..7a8a1399a 100644 --- a/visualc/spinitd +++ b/visualc/spinitd @@ -39,7 +39,7 @@ if $?osdi_enabled osdi C:/Spiced/lib/ngspice/BSIMBULK107.osdi osdi C:/Spiced/lib/ngspice/BSIMCMG.osdi osdi C:/Spiced/lib/ngspice/HICUMl0-2.0.osdi - osdi C:/Spiced/lib/ngspice/psp103.osdi + osdi C:/Spiced/lib/ngspice/psp103_nqs.osdi osdi C:/Spiced/lib/ngspice/r2_cmc.osdi osdi C:/Spiced/lib/ngspice/vbic_4T_et_cf.osdi diff --git a/visualc/spinitd64 b/visualc/spinitd64 index 75b3dec31..c7dc1dbec 100644 --- a/visualc/spinitd64 +++ b/visualc/spinitd64 @@ -11,8 +11,8 @@ set filetype=ascii *set askquit ** set the number of threads in openmp ** default (if compiled with --enable-openmp) is: 2 -set num_threads=4 -set interactive +set num_threads=8 +*set interactive * comment out if central osdi management is set up unset osdi_enabled diff --git a/visualc/spinitr b/visualc/spinitr index 4ab0be7eb..31de1dc45 100644 --- a/visualc/spinitr +++ b/visualc/spinitr @@ -38,7 +38,7 @@ if $?osdi_enabled osdi C:/Spice/lib/ngspice/BSIMBULK107.osdi osdi C:/Spice/lib/ngspice/BSIMCMG.osdi osdi C:/Spice/lib/ngspice/HICUMl0-2.0.osdi - osdi C:/Spice/lib/ngspice/psp103.osdi + osdi C:/Spice/lib/ngspice/psp103_nqs.osdi osdi C:/Spice/lib/ngspice/r2_cmc.osdi osdi C:/Spice/lib/ngspice/vbic_4T_et_cf.osdi diff --git a/visualc/spinitr64 b/visualc/spinitr64 index a476da0a2..19cefe139 100644 --- a/visualc/spinitr64 +++ b/visualc/spinitr64 @@ -39,7 +39,7 @@ if $?osdi_enabled osdi C:/Spice64/lib/ngspice/BSIMBULK107.osdi osdi C:/Spice64/lib/ngspice/BSIMCMG.osdi osdi C:/Spice64/lib/ngspice/HICUMl0-2.0.osdi - osdi C:/Spice64/lib/ngspice/psp103.osdi + osdi C:/Spice64/lib/ngspice/psp103_nqs.osdi osdi C:/Spice64/lib/ngspice/r2_cmc.osdi osdi C:/Spice64/lib/ngspice/vbic_4T_et_cf.osdi