From d19c8e7f41a7ba92570c271a8d83e9c8c06a54c2 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 3 Apr 2021 14:03:47 +0200 Subject: [PATCH] Efficiency: Remove setting the random seed to behind the options selection Evaluate '.options cshunt=xx' earlier to allow the following: Set the option by calling INPpas4() during parsing the circuit, before .ic is set. Ckt and Task cshunt are still set, but their values are available only too late for INPpas4(), but may be used by command 'option' (w/o parameters) for assessing the options and their values. --- src/frontend/com_option.c | 1 + src/frontend/inp.c | 97 ++++++++++++++++++-------------- src/frontend/spiceif.c | 4 ++ src/spicelib/analysis/cktntask.c | 1 + src/spicelib/parser/inppas4.c | 11 +++- 5 files changed, 69 insertions(+), 45 deletions(-) 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); }