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 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 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) diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c index edde7daca..5ded8146e 100644 --- a/src/frontend/com_option.c +++ b/src/frontend/com_option.c @@ -50,6 +50,16 @@ com_option(wordlist *wl) printf("indverbosity = %d\n", circuit->CKTindverbosity); 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); printf("chgtol (charge) = %g\n", circuit->CKTchgtol); 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) { diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index a80da6fb1..8e1c5a688 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -581,7 +581,8 @@ static void scan_gates(DSTRING *lhs) || current->type == '|'); previous = current->prev; if (is_gate && current->is_possible) { - if (previous && previous->type == current->type) { + if (previous && previous->type == current->type + && previous->is_not == current->is_not) { if (eq(current->ins->name, previous->outp)) { move_inputs(current, previous); } @@ -608,6 +609,7 @@ static void scan_gates(DSTRING *lhs) prev = current->prev; while (prev) { if (prev->type == current->type + && prev->is_not == current->is_not && prev->finished == FALSE && strncmp(prev->outp, TMP_PREFIX, TMP_LEN) == 0 && eq(current->ins->name, prev->outp)) { @@ -636,6 +638,19 @@ static void scan_gates(DSTRING *lhs) } } +static void scan_gates_noopt(DSTRING *lhs) +{ + struct gate_data *current = NULL; + + current = last_gate; + if (ds_get_length(lhs) > 0) { + assert(current->finished == FALSE); + tfree(current->outp); + current->outp = TMALLOC(char, ds_get_length(lhs) + 1); + strcpy(current->outp, ds_get_buf(lhs)); + } +} + static void gen_scanned_gates(struct gate_data *gp) { DS_CREATE(instance, 64); @@ -1126,7 +1141,11 @@ static BOOL bstmt_postfix(void) retval = FALSE; goto bail_out; } +if (getenv("SCAN_NOOPT")) { + scan_gates_noopt(&lhs); +} else { scan_gates(&lhs); +} gen_scanned_gates(first_gate); lookahead = lex_scan(); while (lookahead != '}') { 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; 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 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) { 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;