From 7e39c10bee070ba21c068670a59b58e6e56c0028 Mon Sep 17 00:00:00 2001 From: dwarning Date: Wed, 13 Mar 2024 21:55:38 +0100 Subject: [PATCH 01/11] introduce jfet gate-drain and gate-source junction emission coefficient --- src/spicelib/devices/jfet/jfet.c | 1 + src/spicelib/devices/jfet/jfetdefs.h | 3 +++ src/spicelib/devices/jfet/jfetload.c | 2 +- src/spicelib/devices/jfet/jfetmask.c | 3 +++ src/spicelib/devices/jfet/jfetmpar.c | 4 ++++ src/spicelib/devices/jfet/jfetset.c | 3 +++ src/spicelib/devices/jfet/jfettemp.c | 7 ++++--- 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/spicelib/devices/jfet/jfet.c b/src/spicelib/devices/jfet/jfet.c index 29fc05982..f6da2ab18 100644 --- a/src/spicelib/devices/jfet/jfet.c +++ b/src/spicelib/devices/jfet/jfet.c @@ -62,6 +62,7 @@ IFparm JFETmPTable[] = { /* model parameters */ IOPA("cgd", JFET_MOD_CGD, IF_REAL,"G-D junction cap"), IOP("pb", JFET_MOD_PB, IF_REAL,"Gate junction potential"), IOP("is", JFET_MOD_IS, IF_REAL,"Gate junction saturation current"), + IOP("n", JFET_MOD_N, IF_REAL, "Emission Coefficient for gate-drain and gate-source diodes"), IOP("fc", JFET_MOD_FC, IF_REAL,"Forward bias junction fit parm."), /* Modification for Sydney University JFET model */ IOP("b", JFET_MOD_B, IF_REAL,"Doping tail parameter"), diff --git a/src/spicelib/devices/jfet/jfetdefs.h b/src/spicelib/devices/jfet/jfetdefs.h index c37a15fbd..3f25524bc 100644 --- a/src/spicelib/devices/jfet/jfetdefs.h +++ b/src/spicelib/devices/jfet/jfetdefs.h @@ -211,6 +211,7 @@ typedef struct sJFETmodel { /* model structure for a jfet */ double JFETcapGD; double JFETgatePotential; double JFETgateSatCurrent; + double JFETemissionCoeff; double JFETdepletionCapCoeff; double JFETfNcoef; double JFETfNexp; @@ -242,6 +243,7 @@ typedef struct sJFETmodel { /* model structure for a jfet */ unsigned JFETcapGDGiven : 1; unsigned JFETgatePotentialGiven : 1; unsigned JFETgateSatCurrentGiven : 1; + unsigned JFETemissionCoeffGiven: 1; unsigned JFETdepletionCapCoeffGiven : 1; /* Modification for Sydney University JFET model */ unsigned JFETbGiven : 1; @@ -290,6 +292,7 @@ enum { JFET_MOD_CGD, JFET_MOD_PB, JFET_MOD_IS, + JFET_MOD_N, JFET_MOD_FC, JFET_MOD_NJF, JFET_MOD_PJF, diff --git a/src/spicelib/devices/jfet/jfetload.c b/src/spicelib/devices/jfet/jfetload.c index cc0fc2d28..b1e0ac106 100644 --- a/src/spicelib/devices/jfet/jfetload.c +++ b/src/spicelib/devices/jfet/jfetload.c @@ -224,7 +224,7 @@ JFETload(GENmodel *inModel, CKTcircuit *ckt) */ vds=vgs-vgd; - vt_temp=here->JFETtemp*CONSTKoverQ; + vt_temp=here->JFETtemp*CONSTKoverQ*model->JFETemissionCoeff; if (vgs < -3*vt_temp) { arg=3*vt_temp/(vgs*CONSTe); arg = arg * arg * arg; diff --git a/src/spicelib/devices/jfet/jfetmask.c b/src/spicelib/devices/jfet/jfetmask.c index cc18dbaf8..853eed21c 100644 --- a/src/spicelib/devices/jfet/jfetmask.c +++ b/src/spicelib/devices/jfet/jfetmask.c @@ -62,6 +62,9 @@ JFETmAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case JFET_MOD_IS: value->rValue = model->JFETgateSatCurrent; return(OK); + case JFET_MOD_N: + value->rValue = model->JFETemissionCoeff; + return(OK); case JFET_MOD_FC: value->rValue = model->JFETdepletionCapCoeff; return(OK); diff --git a/src/spicelib/devices/jfet/jfetmpar.c b/src/spicelib/devices/jfet/jfetmpar.c index 4eac5efe0..459bc9e6f 100644 --- a/src/spicelib/devices/jfet/jfetmpar.c +++ b/src/spicelib/devices/jfet/jfetmpar.c @@ -58,6 +58,10 @@ JFETmParam(int param, IFvalue *value, GENmodel *inModels) model->JFETgateSatCurrentGiven = TRUE; model->JFETgateSatCurrent = value->rValue; break; + case JFET_MOD_N: + model->JFETemissionCoeff = value->rValue; + model->JFETemissionCoeffGiven = TRUE; + break; case JFET_MOD_FC: model->JFETdepletionCapCoeffGiven = TRUE; model->JFETdepletionCapCoeff = value->rValue; diff --git a/src/spicelib/devices/jfet/jfetset.c b/src/spicelib/devices/jfet/jfetset.c index 662549662..729b7c01d 100644 --- a/src/spicelib/devices/jfet/jfetset.c +++ b/src/spicelib/devices/jfet/jfetset.c @@ -59,6 +59,9 @@ JFETsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->JFETgateSatCurrentGiven) { model->JFETgateSatCurrent = 1e-14; } + if(!model->JFETemissionCoeffGiven) { + model->JFETemissionCoeff = 1; + } if(!model->JFETdepletionCapCoeffGiven) { model->JFETdepletionCapCoeff = .5; } diff --git a/src/spicelib/devices/jfet/jfettemp.c b/src/spicelib/devices/jfet/jfettemp.c index ab43aaf33..a9ab5bd6c 100644 --- a/src/spicelib/devices/jfet/jfettemp.c +++ b/src/spicelib/devices/jfet/jfettemp.c @@ -22,7 +22,7 @@ JFETtemp(GENmodel *inModel, CKTcircuit *ckt) JFETmodel *model = (JFETmodel*)inModel; JFETinstance *here; double xfc; - double vt; + double vt, vtn; double vtnom; double kt,kt1; double arg,arg1; @@ -87,12 +87,13 @@ JFETtemp(GENmodel *inModel, CKTcircuit *ckt) here->JFETtemp = ckt->CKTtemp + here->JFETdtemp; } vt = here->JFETtemp * CONSTKoverQ; + vtn = vt * model->JFETemissionCoeff; fact2 = here->JFETtemp/REFTEMP; ratio1 = here->JFETtemp/model->JFETtnom -1; if (model->JFETxtiGiven) { - here->JFETtSatCur = model->JFETgateSatCurrent * exp(ratio1*model->JFETeg/vt) * pow(ratio1+1,model->JFETxti); + here->JFETtSatCur = model->JFETgateSatCurrent * exp(ratio1*model->JFETeg/vtn) * pow(ratio1+1,model->JFETxti); } else { - here->JFETtSatCur = model->JFETgateSatCurrent * exp(ratio1*model->JFETeg/vt); + here->JFETtSatCur = model->JFETgateSatCurrent * exp(ratio1*model->JFETeg/vtn); } here->JFETtCGS = model->JFETcapGS * cjfact; here->JFETtCGD = model->JFETcapGD * cjfact; From 054a65c2d5dbef369bd2afc2302a0b107291d31d Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 15 Mar 2024 18:49:33 +0100 Subject: [PATCH 02/11] Fix a bug in 'reset', where .subckt are not transformed due to wrong line count in dynmaxline. --- src/frontend/inp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/frontend/inp.c b/src/frontend/inp.c index d59695a18..da24fa05f 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -72,6 +72,7 @@ static bool mc_reload = FALSE; void eval_opt(struct card *deck); extern bool ft_batchmode; +extern int dynmaxline; /* from inpcom.c */ extern struct nscope* inp_add_levels(struct card *deck); @@ -550,6 +551,10 @@ inp_spsource(FILE *fp, bool comfile, char *filename, bool intfile) expr_w_temper = TRUE; mc_reload = FALSE; fprintf(stdout, "Reset re-loads circuit %s\n", mc_deck->line); + dynmaxline = 0; + /* recover the number of lines in deck */ + for (dd = deck; dd; dd = dd->nextcard) + dynmaxline++; } /* re-load input deck from the current circuit structure */ else if (ft_curckt && ft_curckt->ci_mcdeck) { From 603c730260391955c02484f331954797800eea8f Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 15 Mar 2024 19:12:28 +0100 Subject: [PATCH 03/11] If TRACE is defined, print out everything without comment lines, to improve readability. Redo printing of global nodes when TRACE is defined. --- src/frontend/subckt.c | 54 +++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 9fd8a2924..287b38ddb 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -144,6 +144,8 @@ static char start[32], sbend[32], invoke[32], model[32]; static void collect_global_nodes(struct card *c) { + int num_global_nodes; + /* hash table for global nodes */ glonodes = nghash_init(NGHASH_MIN_SIZE); @@ -152,7 +154,7 @@ collect_global_nodes(struct card *c) #ifdef XSPICE nghash_insert(glonodes, "null", DUMMYDATA); #endif - + num_global_nodes = 2; /* already two in hash table*/ for (; c; c = c->nextcard) if (ciprefix(".global", c->line)) { char *s = c->line; @@ -168,20 +170,14 @@ collect_global_nodes(struct card *c) tfree(gnode); s = skip_ws(t); } + num_global_nodes++; +#ifdef TRACE + if (num_global_nodes == 3) + fprintf(stderr, "***Global node option has been found.***\n"); + fprintf(stderr, "***Global node no.%d is %s.***\n", num_global_nodes, c->line); +#endif c->line[0] = '*'; /* comment it out */ } - - -#ifdef TRACE - { - int i; - printf("***Global node option has been found.***\n"); - for (i = 0; i < num_global_nodes; i++) - printf("***Global node no.%d is %s.***\n", i, global_nodes[i]); - printf("\n"); - } -#endif - } @@ -238,15 +234,18 @@ inp_subcktexpand(struct card *deck) { #ifdef TRACE fprintf(stderr, "Numparams is processing this deck:\n"); - for (c = deck; c; c = c->nextcard) + for (c = deck; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; fprintf(stderr, "%3d:%s\n", c->linenum, c->line); + } #endif nupa_signal(NUPADECKCOPY); /* get the subckt names from the deck */ for (c = deck; c; c = c->nextcard) { /* first Numparam pass */ if (ciprefix(".subckt", c->line)) { - nupa_scan(c); + nupa_scan(c); } } @@ -260,8 +259,11 @@ inp_subcktexpand(struct card *deck) { #ifdef TRACE fprintf(stderr, "Numparams transformed deck:\n"); - for (c = deck; c; c = c->nextcard) + for (c = deck; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; fprintf(stderr, "%3d:%s\n", c->linenum, c->line); + } #endif } @@ -391,8 +393,11 @@ inp_subcktexpand(struct card *deck) { #ifdef TRACE fprintf(stderr, "Numparams converted deck:\n"); - for (c = deck; c; c = c->nextcard) + for (c = deck; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; fprintf(stderr, "%3d:%s\n", c->linenum, c->line); + } #endif /*nupa_list_params(stdout);*/ @@ -453,8 +458,11 @@ doit(struct card *deck, wordlist *modnames) { { struct card *c; printf("In doit, about to start first pass through deck.\n"); - for (c = deck; c; c = c->nextcard) + for (c = deck; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; printf(" %s\n", c->line); + } } #endif @@ -557,8 +565,11 @@ doit(struct card *deck, wordlist *modnames) { { struct card *c; printf("In doit, about to start second pass through deck.\n"); - for (c = deck; c; c = c->nextcard) + for (c = deck; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; printf(" %s\n", c->line); + } } #endif @@ -781,8 +792,11 @@ doit(struct card *deck, wordlist *modnames) { { struct card *c = deck; printf("Converted deck\n"); - for (; c; c = c->nextcard) + for (; c; c = c->nextcard) { + if (ciprefix("*", c->line)) + continue; printf("%s\n", c->line); + } } { wordlist *w = modnames; From 715ce8c809746624c3de8bb8fd801398e5c08782 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Wed, 13 Mar 2024 18:02:13 -0700 Subject: [PATCH 04/11] Return correct error statuses. Detect another illegally placed gate operator in an infix expression. --- src/frontend/logicexp.c | 99 ++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 7ca949d82..3d3df6ea9 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -748,17 +748,21 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) nlist = add_name_entry("first", NULL); ds_clear(postfix_p); while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop - if (ltok == '(') { lparen_count++; } - if (ltok == ')') { rparen_count++; } if (ltok == LEX_ID && last_tok == LEX_ID) { fprintf(stderr, "ERROR (1) no gate operator between two identifiers\n"); status = 1; goto err_return; } - if (lex_gate_op(ltok) && lex_gate_op(last_tok)) { - fprintf(stderr, "ERROR (2) two consecutive gate operators\n"); - status = 1; - goto err_return; + if (lex_gate_op(ltok)) { + if (lex_gate_op(last_tok)) { + fprintf(stderr, "ERROR (2) two consecutive gate operators\n"); + status = 1; + goto err_return; + } else if (last_tok != LEX_ID && last_tok != ')') { + fprintf(stderr, "ERROR (2a) gate operator not after ID or rparen\n"); + status = 1; + goto err_return; + } } if (last_tok == '~' && ltok != LEX_ID && ltok != '(') { fprintf(stderr, "ERROR (3) \'~\' is not followed by an ID or lparen\n"); @@ -785,15 +789,24 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) fflush(stdout); } } else if (ltok == '(') { + lparen_count++; entry = add_name_entry(makestr(ltok), nlist); - if (push(&stack, entry->name)) goto err_return; + status = push(&stack, entry->name); + if (status) { + goto err_return; + } } else if (ltok == ')') { + rparen_count++; while ( stack.top != -1 && !eq(stack.array[stack.top], "(") ) { ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); - if (status) goto err_return; + if (status) { + goto err_return; + } } pop(&stack, &status); - if (status) goto err_return; + if (status) { + goto err_return; + } } else if (lex_gate_op(ltok) || ltok == '~') { char *tokstr = makestr(ltok); if (ltok == '~') { // change ~ id --> tilde_id and continue @@ -809,10 +822,15 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) } while ( stack.top != -1 && !eq(stack.array[stack.top], "(") && get_precedence(stack.array[stack.top]) >= get_precedence(tokstr) ) { ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); - if (status) goto err_return; + if (status) { + goto err_return; + } } entry = add_name_entry(tokstr, nlist); - if (push(&stack, entry->name)) goto err_return; + status = push(&stack, entry->name); + if (status) { + goto err_return; + } } else { fprintf(stderr, "ERROR (6) unexpected infix token %d \'%s\'\n", ltok, lx->lexer_buf); @@ -832,9 +850,14 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) } while (stack.top != -1) { ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); - if (status) goto err_return; + if (status) { + goto err_return; + } } err_return: + if (status) { + fprintf(stderr, "ERROR invalid infix expression: %s\n", infix); + } delete_lexer(lx); clear_name_list(nlist); return status; @@ -869,42 +892,43 @@ static int evaluate_postfix(char* postfix) while ( ( ltok = lexer_scan(lx) ) != 0 ) { // while ltok loop if (ltok == LEX_ID) { entry = add_name_entry(lx->lexer_buf, nlist); - if (push(&stack, entry->name)) goto err_return; + status = push(&stack, entry->name); + if (status) { + goto err_return; + } } else if (ltok == '~') { operand1 = pop(&stack, &status); - if (status) goto err_return; + if (status) { + goto err_return; + } sprintf(tmp, "%s%d", TMP_PREFIX, count); count++; gp = new_gate('~', tmp, operand1, NULL); gp = insert_gate(gp); entry = add_name_entry(tmp, nlist); - if (push(&stack, entry->name)) goto err_return; + status = push(&stack, entry->name); + if (status) { + goto err_return; + } } else { operand2 = pop(&stack, &status); - if (status) goto err_return; + if (status) { + goto err_return; + } operand1 = pop(&stack, &status); - if (status) goto err_return; - if (ltok == '|') { + if (status) { + goto err_return; + } + if (lex_gate_op(ltok)) { sprintf(tmp, "%s%d", TMP_PREFIX, count); count++; - gp = new_gate('|', tmp, operand1, operand2); + gp = new_gate(ltok, tmp, operand1, operand2); gp = insert_gate(gp); entry = add_name_entry(tmp, nlist); - if (push(&stack, entry->name)) goto err_return; - } else if (ltok == '^') { - sprintf(tmp, "%s%d", TMP_PREFIX, count); - count++; - gp = new_gate('^', tmp, operand1, operand2); - gp = insert_gate(gp); - entry = add_name_entry(tmp, nlist); - if (push(&stack, entry->name)) goto err_return; - } else if (ltok == '&') { - sprintf(tmp, "%s%d", TMP_PREFIX, count); - count++; - gp = new_gate('&', tmp, operand1, operand2); - gp = insert_gate(gp); - entry = add_name_entry(tmp, nlist); - if (push(&stack, entry->name)) goto err_return; + status = push(&stack, entry->name); + if (status) { + goto err_return; + } } } prevtok = ltok; @@ -915,7 +939,9 @@ static int evaluate_postfix(char* postfix) sprintf(tmp, "%s%d", TMP_PREFIX, count); count++; n1 = tilde_tail(pop(&stack, &status), &ds1); - if (status) goto err_return; + if (status) { + goto err_return; + } if (!skip && n1[0] == '~') { gp = new_gate('~', tmp, n1 + 1, NULL); gp->is_not = TRUE; @@ -927,6 +953,9 @@ static int evaluate_postfix(char* postfix) ds_free(&ds1); } err_return: + if (status) { + fprintf(stderr, "ERROR invalid postfix expression: %s\n", postfix); + } delete_lexer(lx); clear_name_list(nlist); return status; From 0c2c10eb9cd72d802f8af635456b78b27f9d7085 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 16 Mar 2024 23:13:03 +0100 Subject: [PATCH 05/11] add 'option klu' to printout --- src/frontend/com_option.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c index edde7daca..7ba45e26f 100644 --- a/src/frontend/com_option.c +++ b/src/frontend/com_option.c @@ -50,6 +50,12 @@ com_option(wordlist *wl) printf("indverbosity = %d\n", circuit->CKTindverbosity); printf("epsmin = %g\n", circuit->CKTepsmin); + printf("\nMatrix solver:\n"); + if (circuit->CKTkluMODE == 0) + printf("Sparse 1.3\n"); + else + printf("KLU\n"); + printf("\nTolerances (absolute):\n"); printf("abstol (current) = %g\n", circuit->CKTabstol); printf("chgtol (charge) = %g\n", circuit->CKTchgtol); From e27f093fb72985c9ff543bf76af3d29a659fe49c Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 16 Mar 2024 23:18:13 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Prevent=20error:=20implicit=20declaration?= =?UTF-8?q?=20of=20function=20=E2=80=98get=5Flocal=5Fhome=E2=80=99=20=20[-?= =?UTF-8?q?Werror=3Dimplicit-function-declaration],=20if=20editline=20is?= =?UTF-8?q?=20selected.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.c b/src/main.c index 6b3f2cf36..698637cbb 100644 --- a/src/main.c +++ b/src/main.c @@ -26,6 +26,7 @@ It is not vailable with older libedit versions (pre-1.42.2) , thus we have to set it ourselves */ #ifdef HAVE_BSDEDITLINE #include +#include "../misc/tilde.h" #ifndef rl_hook_func_t typedef int rl_hook_func_t(void); #endif From 92b3a901c710db1c3442691b725e571404c63956 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 19 Mar 2024 16:41:27 +0100 Subject: [PATCH 07/11] The values used in the foreach loop my be given by a vector (in addition to plain numbers or a list variable). --- examples/loops/loop_foreach.cir | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/loops/loop_foreach.cir b/examples/loops/loop_foreach.cir index 1195c07b7..3abdd9a2c 100644 --- a/examples/loops/loop_foreach.cir +++ b/examples/loops/loop_foreach.cir @@ -1,14 +1,22 @@ example foreach loop .control +* set values by numbers foreach val -40 -20 0 20 40 echo var is $val end echo +*set values by variable set myvariable = ( -4 -2 0 2 4 ) foreach var $myvariable echo var is $var end +echo +* set values by vector +let myvec = vector(5) +foreach var $&myvec + echo var is $var +end .endc From 03a1010a657ddfd427afd130d01214979dd75296 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 19 Mar 2024 17:05:10 +0100 Subject: [PATCH 08/11] Repeat loop requires plain number, transformed vector, or transformed variable --- examples/loops/loop_repeat.cir | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/loops/loop_repeat.cir b/examples/loops/loop_repeat.cir index eb10974fe..526b24287 100644 --- a/examples/loops/loop_repeat.cir +++ b/examples/loops/loop_repeat.cir @@ -1,10 +1,21 @@ example repeat loop .control - +* plain number +repeat 3 + echo How many loops? Count yourself! +end +echo +* variable set loops = 7 repeat $loops echo How many loops? $loops end +echo +* vector +let loopvec = 4 +repeat $&loopvec + echo How many loops? $&loopvec +end .endc From 7722c3dc6b11006a5d1adeb254205e6b3ac9f615 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 25 Mar 2024 09:20:51 +0100 Subject: [PATCH 09/11] only access to CKTkluMODE if KLU configured --- src/frontend/com_option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c index 7ba45e26f..5ded8146e 100644 --- a/src/frontend/com_option.c +++ b/src/frontend/com_option.c @@ -51,10 +51,14 @@ com_option(wordlist *wl) printf("epsmin = %g\n", circuit->CKTepsmin); printf("\nMatrix solver:\n"); +#ifdef KLU if (circuit->CKTkluMODE == 0) printf("Sparse 1.3\n"); else printf("KLU\n"); +#else + printf("Sparse 1.3\n"); +#endif printf("\nTolerances (absolute):\n"); printf("abstol (current) = %g\n", circuit->CKTabstol); From a1210a257d61b0c7c5e83221b0e49b6f72a55395 Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 26 Mar 2024 19:59:23 +0100 Subject: [PATCH 10/11] use only magnitudes in ac noise analysis even if openvaf compiled models deliver negative noise contributions --- src/osdi/osdinoise.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osdi/osdinoise.c b/src/osdi/osdinoise.c index fc0eb05aa..7dba09fc6 100644 --- a/src/osdi/osdinoise.c +++ b/src/osdi/osdinoise.c @@ -124,6 +124,7 @@ int OSDInoise(int mode, int operation, GENmodel *inModel, CKTcircuit *ckt, node_mapping = (uint32_t *)(((char *)inst) + descr->node_mapping_offset); for (i = 0; i < descr->num_noise_src; i++) { + noise_dens[i] = fabs(noise_dens[i]); src = descr->noise_sources[i]; node1 = node_mapping[src.nodes.node_1]; if (src.nodes.node_2 == UINT32_MAX) { From 49951cd19716ccc9bfc77a7d66153441d4ed8bb4 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Tue, 26 Mar 2024 20:08:08 +0100 Subject: [PATCH 11/11] Bug 664: Report an error if token in meas statement is not a vector and cannot be evaluated as a number. --- src/frontend/com_measure2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index b36a510ce..1a4be8a97 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -1481,6 +1481,10 @@ measure_parse_when( correct_vec(meas); } else { meas->m_val = INPevaluate(&pVar2, &err, 1); + if (err) { + snprintf(errBuf, 99, "Cannot evaluate %s \n", pVar2); + return MEASUREMENT_FAILURE; + } } } else { if (measure_parse_stdParams(meas, wl, NULL, errBuf) == MEASUREMENT_FAILURE)