From ffe920117cdbd70d78bb70d8227914a89135c3c3 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Sun, 13 Nov 2022 16:16:38 +0100 Subject: [PATCH 1/7] calculate log frequency sweep such that start frequency and stop frequency are always exactly included --- src/spicelib/analysis/acan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/spicelib/analysis/acan.c b/src/spicelib/analysis/acan.c index da8d5bd39..1c45856c9 100644 --- a/src/spicelib/analysis/acan.c +++ b/src/spicelib/analysis/acan.c @@ -86,8 +86,9 @@ ACan(CKTcircuit *ckt, int restart) fprintf(stderr, "ERROR: AC startfreq <= 0\n"); return E_PARMVAL; } - job->ACfreqDelta = - exp(log(10.0)/job->ACnumberSteps); + double num_steps = floor(fabs(log10(job->ACstopFreq/job->ACstartFreq))*job->ACnumberSteps); + job->ACfreqDelta = exp((log(job->ACstopFreq/job->ACstartFreq))/ num_steps); + break; case OCTAVE: if (job->ACstartFreq <= 0) { From 8e5c76d8b33069c569d0bf776aa86062de068001 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 16 Nov 2022 11:37:35 +0100 Subject: [PATCH 2/7] Add error messages when controlled_exit is called: No exit without message. --- src/frontend/diff.c | 3 +++ src/frontend/inpcom.c | 16 +++++++++------- src/frontend/numparam/mystring.c | 5 +++++ src/frontend/numparam/xpressn.c | 1 + src/frontend/vectors.c | 3 +++ src/misc/string.c | 1 + src/spicelib/devices/txl/txlload.c | 1 + 7 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/frontend/diff.c b/src/frontend/diff.c index e11e6ece0..4412bb7da 100644 --- a/src/frontend/diff.c +++ b/src/frontend/diff.c @@ -44,6 +44,7 @@ canonical_name(const char *name, DSTRINGPTR dbuf_p, f_ok &= ds_cat_mem(dbuf_p, sz_branch, sizeof sz_branch / sizeof *sz_branch - 1) == DS_E_OK; if (!f_ok) { + fprintf(stderr, "Error: DS could not convert %s\n", name); controlled_exit(-1); } return ds_get_buf(dbuf_p); @@ -56,6 +57,7 @@ canonical_name(const char *name, DSTRINGPTR dbuf_p, f_ok &= ds_cat_str(dbuf_p, name) == DS_E_OK; f_ok &= ds_cat_char(dbuf_p, ')') == DS_E_OK; if (!f_ok) { + fprintf(stderr, "Error: DS could not convert %s\n", name); controlled_exit(-1); } return ds_get_buf(dbuf_p); @@ -68,6 +70,7 @@ canonical_name(const char *name, DSTRINGPTR dbuf_p, * changing the original, but in the current use cases that is * not an issue. */ if (ds_cat_str(dbuf_p, name) != DS_E_OK) { + fprintf(stderr, "Error: DS could not convert %s\n", name); controlled_exit(-1); } return ds_get_buf(dbuf_p); diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index c4851a8b1..7b6ad0f89 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1273,6 +1273,7 @@ struct inp_read_t inp_read( FILE *fp, int call_depth, const char *dir_name, strcat(buffer, "\n"); } else { /* No good way to report this so just die */ + fprintf(stderr, "Error: IPC status not o.k.\n"); controlled_exit(EXIT_FAILURE); } } @@ -1758,7 +1759,7 @@ static char *inp_pathresolve(const char *name) name[2] == DIR_TERM_LINUX) { DS_CREATE(ds, 100); if (ds_cat_str(&ds, name) != 0) { - fprintf(stderr, "Unable to copy string while resolving path"); + fprintf(stderr, "Error: Unable to copy string while resolving path"); controlled_exit(EXIT_FAILURE); } char *const buf = ds_get_buf(&ds); @@ -1821,7 +1822,7 @@ static char *inp_pathresolve(const char *name) if (rc_ds != 0) { /* unable to build string */ (void) fprintf(cp_err, - "Unable to build path name in inp_pathresolve"); + "Error: Unable to build path name in inp_pathresolve"); controlled_exit(EXIT_FAILURE); } @@ -1873,7 +1874,7 @@ static char *inp_pathresolve_at(const char *name, const char *dir) DS_CREATE(ds, 100); if (ds_cat_printf(&ds, ".%c%s", DIR_TERM, name) != 0) { (void) fprintf(cp_err, - "Unable to build \".\" path name in inp_pathresolve_at"); + "Error: Unable to build \".\" path name in inp_pathresolve_at"); controlled_exit(EXIT_FAILURE); } char * const r = inp_pathresolve(ds_get_buf(&ds)); @@ -1901,7 +1902,7 @@ static char *inp_pathresolve_at(const char *name, const char *dir) rc_ds |= ds_cat_str(&ds, name); /* append the file name */ if (rc_ds != 0) { - (void) fprintf(cp_err, "Unable to build \"dir\" path name " + (void) fprintf(cp_err, "Error: Unable to build \"dir\" path name " "in inp_pathresolve_at"); controlled_exit(EXIT_FAILURE); } @@ -3051,7 +3052,7 @@ static void inp_change_quotes(char *s) static void add_name(struct names *p, char *name) { if (p->num_names >= N_SUBCKT_W_PARAMS) { - fprintf(stderr, "ERROR, N_SUBCKT_W_PARMS overflow\n"); + fprintf(stderr, "ERROR: N_SUBCKT_W_PARMS overflow, more than %d subcircuits\n", N_SUBCKT_W_PARAMS); controlled_exit(EXIT_FAILURE); } @@ -3748,7 +3749,7 @@ static void free_function(struct function *fcn) static void new_function_parameter(struct function *fcn, char *parameter) { if (fcn->num_parameters >= N_PARAMS) { - fprintf(stderr, "ERROR, N_PARAMS overflow\n"); + fprintf(stderr, "ERROR, N_PARAMS overflow, more than %d parameters\n", N_PARAMS); controlled_exit(EXIT_FAILURE); } @@ -4926,6 +4927,7 @@ static struct card *inp_reorder_params_subckt( } /* the terminating `.ends' deck wasn't found */ + fprintf(stderr, "Error: Missing .ends statement\n"); controlled_exit(EXIT_FAILURE); } @@ -10091,7 +10093,7 @@ struct nscope *inp_add_levels(struct card *deck) } else if (ciprefix(".ends", curr_line)) { if (lvl == root) { - fprintf(stderr, ".subckt/.ends not balanced\n"); + fprintf(stderr, "Error: .subckt/.ends not balanced\n"); controlled_exit(1); } card->level = lvl; diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index 7793473b1..fe58576e1 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -74,6 +74,7 @@ void sadd(DSTRINGPTR dstr_p, const char *t) { if (ds_cat_str(dstr_p, t) != DS_E_OK) { + fprintf(stderr, "Error: DS could not add string %s\n", t); controlled_exit(-1); } } @@ -86,6 +87,7 @@ void cadd(DSTRINGPTR dstr_p, char c) { if (ds_cat_char(dstr_p, c) != DS_E_OK) { + fprintf(stderr, "Error: DS could not add character %c\n", c); controlled_exit(-1); } } @@ -100,6 +102,7 @@ scopyd(DSTRINGPTR dst, const DSTRINGPTR src) /* returns success flag */ { ds_clear(dst); if (ds_cat_ds(dst, src) != DS_E_OK) { + fprintf(stderr, "Error: DS could not copy string\n"); controlled_exit(-1); } } @@ -114,6 +117,7 @@ scopys(DSTRINGPTR s, const char *t) /* returns success flag */ { ds_clear(s); if (ds_cat_str(s, t) != DS_E_OK) { + fprintf(stderr, "Error: DS could not copy string %s\n", t); controlled_exit(-1); } } @@ -129,6 +133,7 @@ pscopy(DSTRINGPTR dstr_p, const char *t, const char *stop) ds_clear(dstr_p); if (ds_cat_mem(dstr_p, t, (size_t) (stop - t)) != DS_E_OK) { + fprintf(stderr, "Error: DS could not copy partially string %s\n", t); controlled_exit(-1); } diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index f4732ef74..1f523f66c 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -336,6 +336,7 @@ dicostack_pop(dico_t *dico) ds_clear(¶m_name); if (ds_cat_printf(¶m_name, "%s.%s", inst_name, entry->symbol) != DS_E_OK) { + fprintf(stderr, "Error: DS could not add string %s\n", inst_name); controlled_exit(-1); } nupa_add_inst_param(ds_get_buf(¶m_name), entry->vl); diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index 31933b892..bbd3801c2 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -69,6 +69,7 @@ static void vec_rebuild_lookup_table(struct plot *pl) for (d = pl->pl_dvecs; d; d = d->v_next) { ds_clear(&dbuf); if (ds_cat_str_case(&dbuf, d->v_name, ds_case_lower) != DS_E_OK) { + fprintf(stderr, "Error: DS could not add string %s\n", d->v_name); controlled_exit(-1); } char * const lower_name = ds_get_buf(&dbuf); @@ -181,6 +182,7 @@ static struct dvec *findvec(char *word, struct plot *pl) DS_CREATE(dbuf, 200); /* make dynamic buffer */ if (ds_cat_str_case(&dbuf, word, ds_case_lower) != DS_E_OK) { + fprintf(stderr, "Error: DS could not add string %s\n", word); controlled_exit(-1); } char * const lower_name = ds_get_buf(&dbuf); @@ -197,6 +199,7 @@ static struct dvec *findvec(char *word, struct plot *pl) ds_case_lower) == DS_E_OK; f_ok &= ds_cat_char(&dbuf, ')') == DS_E_OK; if (!f_ok) { + fprintf(stderr, "Error: DS could not add string V() around %s\n", word); controlled_exit(-1); } char * const node_name = ds_get_buf(&dbuf); diff --git a/src/misc/string.c b/src/misc/string.c index 5a06b9599..147fe3648 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -110,6 +110,7 @@ char *tvprintf(const char *fmt, va_list args) * memory was exhausted) with the old behavior */ if (nchars < 0) { + fprintf(stderr, "Error: tvprintf failed\n"); controlled_exit(-1); } diff --git a/src/spicelib/devices/txl/txlload.c b/src/spicelib/devices/txl/txlload.c index 212fad344..2206550f5 100644 --- a/src/spicelib/devices/txl/txlload.c +++ b/src/spicelib/devices/txl/txlload.c @@ -296,6 +296,7 @@ copy_tx(TXLine *new, TXLine *old) new->ifImg = old->ifImg; if (new->vi_tail != old->vi_tail) { /* someting wrong */ + fprintf(stderr, "Error during evaluating TXL line\n"); controlled_exit(0); } From ef86fcd6bdc04a96513e927bf57b59d110728680 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 18 Nov 2022 14:38:29 +0100 Subject: [PATCH 3/7] Remove mentioning line number 0, which has been incomprehensible. --- src/frontend/inp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index e6660442e..fc9b5b5a3 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -1307,6 +1307,12 @@ inp_dodeck( if (strstr(dd->line, ".model")) fprintf(stderr, "Warning: Model issue on line %d :\n %.*s ...\n%s\n", dd->linenum_orig, 72, dd->line, dd->error); + else if (dd->linenum_orig == 0) { + fprintf(stderr, "Error on line:\n %s\n%s\n", + dd->line, dd->error); + have_err = TRUE; + return 1; + } else { fprintf(stderr, "Error on line %d or its substitute:\n %s\n%s\n", dd->linenum_orig, dd->line, dd->error); From b31b4759e67f91f8943aadde23af0bf15c510450 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Sat, 12 Nov 2022 22:53:49 -0800 Subject: [PATCH 4/7] Use tilde '~' inputs instead of creating inverters. --- src/frontend/logicexp.c | 62 ++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index e16d32732..a29dff2e2 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -583,6 +583,16 @@ static int lookahead = 0; static int adepth = 0; static int max_adepth = 0; static DSTRING d_curr_line; +static int number_of_instances = 0; + +static BOOL inverters_needed(void) +{ +#ifdef LOGICEXP_INVERTERS + return TRUE; +#else + return FALSE; +#endif +} static char *get_inst_name(void) { @@ -590,6 +600,7 @@ static char *get_inst_name(void) static int number = 0; number++; (void) sprintf(name, "a_%d", number); + number_of_instances++; return name; } @@ -723,8 +734,9 @@ static void amatch(int t) static void bfactor(void) { - /* factor is : [~] (optional) rest - where rest is: id (input_name) | ( expr ) | error + /* factor is : ['~'] rest + where rest is: input_name_id | '(' expr ')' | error + [] means optional */ BOOL is_not = FALSE; SYM_TAB entry = NULL; @@ -792,7 +804,9 @@ static void bfactor(void) static void bexpr(void) { - /* expr is: factor { gate_op factor } (0 or more times). */ + /* expr is: factor { gate_op factor }+ + where {}+ means 0 or more times. + */ bfactor(); while (lex_gate_op(lookahead)) { @@ -805,7 +819,7 @@ static void bexpr(void) static void bstmt(void) { - /* A stmt is: output_name = { expr } */ + /* A stmt is: output_name_id = '{' expr '}' */ SYM_TAB entry = NULL; LEXER lx = parse_lexer; DS_CREATE(tname, 64); @@ -1010,8 +1024,6 @@ static PTABLE optimize_gen_tab(PTABLE pt) new_gen = NULL; goto quick_return; } - if (val == '~') - found_tilde = TRUE; ds_cat_printf(&scratch, "%c ", val); } val = lexer_scan(lxr); @@ -1077,6 +1089,7 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) LEXER lxr = NULL; int val, tok_count = 0, gate_op = 0, idnum = 0, in_count = 0; BOOL found_tilde = FALSE; + BOOL prit = PRINT_ALL; DS_CREATE(out_name, 64); DS_CREATE(in_names, 64); DS_CREATE(gate_name, 64); @@ -1110,7 +1123,22 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) ds_cat_str(&out_name, lxr->lexer_buf); } else { // input name in_count++; - ds_cat_printf(&in_names, " %s", lxr->lexer_buf); + if (!inverters_needed()) { + char *tail = NULL; + tail = get_inv_tail(lxr->lexer_buf); + if (tail && strlen(tail) > 0) { + ds_cat_printf(&in_names, " ~%s", tail); + if (prit) { + printf( + "change input name \"%s\" tail \"~%s\"\n", + lxr->lexer_buf, tail); + } + } else { + ds_cat_printf(&in_names, " %s", lxr->lexer_buf); + } + } else { + ds_cat_printf(&in_names, " %s", lxr->lexer_buf); + } } } else if (val == '~') { found_tilde = TRUE; @@ -1150,8 +1178,12 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) ds_cat_printf(&instance, "%s %s ", tail, ds_get_buf(&out_name)); ent = member_sym_tab(tail, parser_symbols); - if (!ent) goto quick_return; - if ((ent->attribute & SYM_INVERTER) == 0) goto quick_return; + if (!ent) { + goto quick_return; + } + if ((ent->attribute & SYM_INVERTER) == 0) { + goto quick_return; + } ent->ref_count--; } else { ds_cat_printf(&instance, "%s %s ", ds_get_buf(&in_names), @@ -1168,7 +1200,9 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) delete_lexer(lxr); lxr = new_lexer(t->line); } - u_add_instance(ds_get_buf(&instance)); + if (ds_get_length(&instance) > 0) { + u_add_instance(ds_get_buf(&instance)); + } } quick_return: @@ -1216,10 +1250,11 @@ static void bevaluate(TLINE t, int deep) if (strstr(t->line + ds_get_length(&this), " ~ ")) { ds_cat_printf(&new_line, "%s = ~ ", ds_get_buf(&this)); } else { - if (deep == 1) + if (deep == 1) { ds_cat_printf(&new_line, "%s ", parse_tab->first->line); - else + } else { ds_cat_printf(&new_line, "%s = ", ds_get_buf(&this)); + } } t = t->next; while (t) { @@ -1374,7 +1409,8 @@ static BOOL bparse(char *line, BOOL new_lexer) } ds_free(&d_curr_line); - gen_inverters(lx->lexer_sym_tab); + if (inverters_needed()) + gen_inverters(lx->lexer_sym_tab); gen_models(); ds_free(&stmt); delete_lexer(lx); From 2ec9e6a38e11c0d89a75a04ba3fdfe398def6ba8 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 15 Nov 2022 14:59:58 -0800 Subject: [PATCH 5/7] Add more debug instrumentation. --- src/frontend/logicexp.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index a29dff2e2..6bbdfbf87 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -490,7 +490,7 @@ static char *get_temp_from_line(char *line, BOOL begin) /* If begin is TRUE then "tmp" must be at the start of line */ static char lbuf[64]; char *p, *q; - int j; + int j = 0; p = strstr(line, "tmp"); if (!p) return NULL; @@ -619,7 +619,7 @@ static char *get_inv_tail(char *str) { static char lbuf[64]; char *p = NULL, *q = NULL; - int j; + int j = 0; size_t slen = strlen("inv_out__"); p = strstr(str, "inv_out__"); @@ -820,6 +820,8 @@ static void bexpr(void) static void bstmt(void) { /* A stmt is: output_name_id = '{' expr '}' */ + BOOL verbose = PRINT_ALL; + int end_pos = 0, start_pos = 0; SYM_TAB entry = NULL; LEXER lx = parse_lexer; DS_CREATE(tname, 64); @@ -835,6 +837,11 @@ static void bstmt(void) if (adepth > max_adepth) max_adepth = adepth; + if (verbose) { + start_pos = lx->lexer_pos; + printf("* %s", lx->lexer_buf); + } + amatch(LEX_ID); amatch('='); @@ -860,6 +867,15 @@ static void bstmt(void) (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE); ds_clear(&d_curr_line); + if (verbose) { + DS_CREATE(stmt_str, 128); + end_pos = lx->lexer_pos; + ds_cat_mem(&stmt_str, &lx->lexer_line[start_pos], + (size_t) (end_pos - start_pos)); + printf("%s\n", ds_get_buf(&stmt_str)); + ds_free(&stmt_str); + } + amatch('}'); ds_free(&assign); @@ -1358,6 +1374,12 @@ static BOOL bparse(char *line, BOOL new_lexer) ds_cat_str(&stmt, lx->lexer_buf); bstmt(); + if (prit) { + printf("START parse_tab\n"); + ptable_print(parse_tab); + printf("END parse_tab\n"); + } + beval_order(); /* generate gates only when optimizations are successful */ From 8b85302da12ab95dc2c422190c5c3aacdee67b61 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 20 Nov 2022 12:10:40 +0100 Subject: [PATCH 6/7] Replace obscure warning "singular matrix: check nodes mymode1 and mynode1" by "singular matrix: check node mynode1", if both node names are equal. --- src/maths/ni/niiter.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index 94e64e25f..597391750 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -123,7 +123,10 @@ NIiter(CKTcircuit *ckt, int maxIter) */ if (ft_ngdebug || msgcount < 6) { SMPgetError(ckt->CKTmatrix, &i, &j); - SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j)); + if(eq(NODENAME(ckt, i), NODENAME(ckt, j))) + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check node %s\n", NODENAME(ckt, i)); + else + SPfrontEnd->IFerrorf(ERR_WARNING, "singular matrix: check nodes %s and %s\n", NODENAME(ckt, i), NODENAME(ckt, j)); msgcount += 1; } ckt->CKTstat->STATnumIter += iterno; From f2be3d681d3a9538baf261461f09c5d074d601b6 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sun, 20 Nov 2022 15:07:46 +0100 Subject: [PATCH 7/7] Allow resetting the limit for warning mesaages, when a new run is started. --- src/frontend/runcoms.c | 3 +++ src/include/ngspice/cktdefs.h | 1 + src/maths/ni/niiter.c | 9 +++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index e23623373..9d52e192e 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -34,6 +34,7 @@ Modified: 2000 AlansFixes static int dosim(char *what, wordlist *wl); extern struct INPmodel *modtab; extern struct dbcomm *dbs; +extern void NIresetwarnmsg(void); /* Routines for the commands op, tran, ac, dc, listing, device, state, * resume, stop, trace, run, end. Op, tran, ac, and dc cause the action @@ -261,6 +262,8 @@ static int dosim( return 0; } + NIresetwarnmsg(); + /* From now on until the next prompt, an interrupt will just * set a flag and let spice finish up, then control will be * passed back to the user. diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index b849c2b6f..b9b14a9cc 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -480,6 +480,7 @@ extern void NIdestroy(CKTcircuit *); extern int NIinit(CKTcircuit *); extern int NIintegrate(CKTcircuit *, double *, double *, double , int); extern int NIiter(CKTcircuit * , int); +extern void NIresetwarnmsg(void); extern int NIpzMuller(PZtrial **, PZtrial *); extern int NIpzComplex(PZtrial **, PZtrial *); extern int NIpzSym(PZtrial **, PZtrial *); diff --git a/src/maths/ni/niiter.c b/src/maths/ni/niiter.c index 597391750..fd7966dc9 100644 --- a/src/maths/ni/niiter.c +++ b/src/maths/ni/niiter.c @@ -20,6 +20,9 @@ Modified: 2001 AlansFixes #include "ngspice/sperror.h" #include "ngspice/fteext.h" +/* Limit the number of 'singular matrix' warnings */ +static int msgcount = 0; +void NIresetwarnmsg(void); /* NIiter() - return value is non-zero for convergence failure */ @@ -32,8 +35,6 @@ NIiter(CKTcircuit *ckt, int maxIter) int iterno = 0; int ipass = 0; - static int msgcount = 0; - /* some convergence issues that get resolved by increasing max iter */ if (maxIter < 100) maxIter = 100; @@ -283,3 +284,7 @@ NIiter(CKTcircuit *ckt, int maxIter) } /*NOTREACHED*/ } + +void NIresetwarnmsg(void) { + msgcount = 0; +};