diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c index 7ca4ce996..267520e7e 100644 --- a/src/frontend/com_option.c +++ b/src/frontend/com_option.c @@ -76,6 +76,7 @@ com_option(wordlist *wl) printf("gmin (devices) = %g\n", circuit->CKTgmin); printf("diaggmin (stepping) = %g\n", circuit->CKTdiagGmin); printf("gshunt = %g\n", circuit->CKTgshunt); + printf("cshunt = %g\n", circuit->CKTcshunt); printf("delmin = %g\n", circuit->CKTdelmin); diff --git a/src/frontend/inp.c b/src/frontend/inp.c index d04bbbaed..22e4b2608 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -394,49 +394,66 @@ inp_remove_recent(void) { line_free(recent_deck, TRUE); } -/* check for .option seed=[val|random] and set the random number generator */ + +/* Check for .option seed=[val|random] and set the random number generator. + Check for .option cshunt=val and set a global variable + Input is the option deck (already sorted for .option) */ void -eval_seed_opt(struct card *deck) +eval_opt(struct card* deck) { - struct card *card; + struct card* card; bool has_seed = FALSE; + bool has_cshunt = FALSE; for (card = deck; card; card = card->nextcard) { - char *line = card->line; - if (*line == '*') - continue; - if (ciprefix(".option", line) || ciprefix("option", line)) { - /* option seedinfo */ - if (strstr(line, "seedinfo")) - setseedinfo(); - char *begtok = strstr(line, "seed="); - if (begtok) - begtok = &begtok[5]; /*skip seed=*/ - if (begtok) { - if (has_seed) - fprintf(cp_err, "Warning: Multiple 'option seed=val|random' found!\n"); - char *token = gettok(&begtok); - /* option seed=random [seed='random'] */ - if (eq(token, "random") || eq(token, "{random}")) { - time_t acttime = time(NULL); - /* get random value from time in seconds since 1.1.1970 */ - int rseed = (int)(acttime - 1470000000); - cp_vset("rndseed", CP_NUM, &rseed); + char* line = card->line; + + if (strstr(line, "seedinfo")) + setseedinfo(); + char* begtok = strstr(line, "seed="); + if (begtok) + begtok = &begtok[5]; /*skip seed=*/ + if (begtok) { + if (has_seed) + fprintf(cp_err, "Warning: Multiple 'option seed=val|random' found!\n"); + char* token = gettok(&begtok); + /* option seed=random [seed='random'] */ + if (eq(token, "random") || eq(token, "{random}")) { + time_t acttime = time(NULL); + /* get random value from time in seconds since 1.1.1970 */ + int rseed = (int)(acttime - 1600000000); + cp_vset("rndseed", CP_NUM, &rseed); + com_sseed(NULL); + has_seed = TRUE; + } + /* option seed=val*/ + else { + int sr = atoi(token); + if (sr <= 0) + fprintf(cp_err, "Warning: Cannot convert 'option seed=%s' to seed value, skipped!\n", token); + else { + cp_vset("rndseed", CP_NUM, &sr); com_sseed(NULL); has_seed = TRUE; } - /* option seed=val*/ - else { - int sr = atoi(token); - if (sr <= 0) - fprintf(cp_err, "Warning: Cannot convert 'option seed=%s' to seed value, skipped!\n", token); - else { - cp_vset("rndseed", CP_NUM, &sr); - com_sseed(NULL); - has_seed = TRUE; - } - } - tfree(token); + } + tfree(token); + } + + begtok = strstr(line, "cshunt="); + if (begtok) + begtok = &begtok[7]; /*skip cshunt=*/ + if (begtok) { + int err = 0; + if (has_cshunt) + fprintf(cp_err, "Warning: Multiple '.option cshunt=val' found!\n"); + /* option cshunt=val*/ + double sr = INPevaluate(&begtok, &err, 0); + if (sr <= 0 || err) + fprintf(cp_err, "Warning: Cannot convert 'option cshunt=%s' to capacitor value, skipped!\n", begtok); + else { + cp_vset("cshunt_value", CP_REAL, &sr); + has_cshunt = TRUE; } } } @@ -483,8 +500,6 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) if (fp || intfile) { deck = inp_readall(fp, dir_name, comfile, intfile, &expr_w_temper); - /* here we check for .option seed=[val|random] and set the random number generator */ - eval_seed_opt(deck); /* files starting with *ng_script are user supplied command files */ if (deck && ciprefix("*ng_script", deck->line)) comfile = TRUE; @@ -557,7 +572,9 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) /* Extract the .option lines from the deck into 'options', and remove them from the deck. */ options = inp_getopts(deck); - + /* Check for .option seed=[val|random] and set the random number generator. + Check for .option cshunt=val and set a global variable cshunt_value */ + eval_opt(options); /* copy a deck before subckt substitution. */ realdeck = inp_deckcopy(deck); @@ -1336,10 +1353,6 @@ inp_dodeck( } } // if (!noparse) . . . - /* If option cshunt is given, add capacitors to each voltage node */ - if (ft_curckt->ci_defTask->TSKcshunt > 0.) - INPpas4(ckt, tab); - /* add title of deck to data base */ /* this won't work if the title is the empty string * cp_addkword() doesn't work for tt === "" diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 6c90c8d1a..b6ac034db 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -167,6 +167,9 @@ if_inpdeck(struct card *deck, INPtables **tab) /* Scan through the instance lines and parse the circuit. */ INPpas2(ckt, deck->nextcard, *tab, ft_curckt->ci_defTask); + /* If option cshunt is given, add capacitors to each voltage node */ + INPpas4(ckt, *tab); + /* Fill in .NODESET and .IC data. * nodeset/ic of non-existent nodes is rejected. */ INPpas3(ckt, deck->nextcard, @@ -1450,6 +1453,7 @@ void com_snload(wordlist *wl) _t(CKTgmin); _t(CKTgshunt); + _t(CKTcshunt); _t(CKTdelmin); _t(CKTtrtol); _t(CKTfinalTime); diff --git a/src/spicelib/analysis/cktntask.c b/src/spicelib/analysis/cktntask.c index ec7b8e5e6..201e8dc25 100644 --- a/src/spicelib/analysis/cktntask.c +++ b/src/spicelib/analysis/cktntask.c @@ -57,6 +57,7 @@ CKTnewTask(CKTcircuit *ckt, TSKtask **taskPtr, IFuid taskName, TSKtask **defPtr) tsk->TSKvoltTol = def->TSKvoltTol; tsk->TSKgmin = def->TSKgmin; tsk->TSKgshunt = def->TSKgshunt; + tsk->TSKcshunt = def->TSKcshunt; /* delmin */ tsk->TSKtrtol = def->TSKtrtol; tsk->TSKdefaultMosM = def->TSKdefaultMosM; diff --git a/src/spicelib/parser/inppas4.c b/src/spicelib/parser/inppas4.c index f3bda03fd..8155b0601 100644 --- a/src/spicelib/parser/inppas4.c +++ b/src/spicelib/parser/inppas4.c @@ -25,7 +25,7 @@ Author: 1985 Thomas L. Quarles /* pass 4 - If option cshunt is given, add a capacitor to each voltage node */ -void INPpas4(CKTcircuit *ckt, INPtables * tab) +void INPpas4(CKTcircuit *ckt, INPtables *tab) { CKTnode* node; int mytype = -1; @@ -34,6 +34,11 @@ void INPpas4(CKTcircuit *ckt, INPtables * tab) GENinstance* fast; /* pointer to the actual instance */ IFvalue ptemp; /* a value structure to package capacitance into */ int nadded = 0; /* capacitors added */ + double csval = 0.; /* cshunt capacitors value */ + + /* get the cshunt value */ + if (!cp_getvar("cshunt_value", CP_REAL, &csval, 0)) + return; if ((mytype = INPtypelook("Capacitor")) < 0) { fprintf(stderr, "Device type Capacitor not supported by this binary\n"); @@ -57,7 +62,7 @@ void INPpas4(CKTcircuit *ckt, INPtables * tab) (*(ft_sim->bindNode))(ckt, fast, 1, node); /* value of the capacitance */ - ptemp.rValue = ft_curckt->ci_defTask->TSKcshunt; + ptemp.rValue = csval; error = INPpName("capacitance", &ptemp, ckt, mytype, fast); /* add device numbers for statistics */ @@ -68,5 +73,5 @@ void INPpas4(CKTcircuit *ckt, INPtables * tab) nadded++; } } - printf("Option cshunt: %d capacitors added with %g F each\n", nadded, ft_curckt->ci_defTask->TSKcshunt); + printf("Option cshunt: %d capacitors added with %g F each\n", nadded, csval); }