diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index c6d678386..6b12c2b7c 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1283,6 +1283,13 @@ struct card *inp_readall(FILE *fp, const char *dir_name, const char* file_name, return cc; } +static char *skip_token(char *s) +{ + s = skip_ws(s); /* Advance past space chars. */ + s = skip_non_ws(s); /* Skip over token. */ + return skip_ws(s); +} + static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name, const char* file_name, bool comfile, bool intfile) @@ -1420,8 +1427,8 @@ static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name /* now handle .title statement */ if (ciprefix(".title", buffer)) { char* s; - s = skip_non_ws(buffer); /* skip over .title */ - s = skip_ws(s); /* advance past space chars */ + + s = skip_token(buffer); /* only the last title line remains valid */ tfree(new_title); @@ -2800,13 +2807,11 @@ static void inp_fix_macro_param_func_paren_io(struct card *card) if (ciprefix(".subckt", card->line) || ciprefix("x", card->line)) { /* remove () */ - str_ptr = skip_non_ws(card->line); - // skip over .subckt, instance name - str_ptr = skip_ws(str_ptr); - if (ciprefix(".subckt", card->line)) { - str_ptr = skip_non_ws(str_ptr); // skip over subckt name - str_ptr = skip_ws(str_ptr); - } + + str_ptr = skip_token(card->line); // Skip over .subckt. + if (ciprefix(".subckt", card->line)) + str_ptr = skip_token(str_ptr); // Skip over subckt name. + if (*str_ptr == '(') { *str_ptr = ' '; while (*str_ptr != '\0') { @@ -2824,8 +2829,8 @@ static void inp_fix_macro_param_func_paren_io(struct card *card) if (ciprefix(".para", card->line)) { bool is_func = FALSE; - str_ptr = skip_non_ws(card->line); // skip over .param - str_ptr = skip_ws(str_ptr); + + str_ptr = skip_token(card->line); // skip over .param while (!isspace_c(*str_ptr) && *str_ptr != '=') { if (*str_ptr == '(') is_func = TRUE; @@ -2874,13 +2879,8 @@ static char *get_subckt_model_name(char *line) { char *name, *end_ptr; - name = skip_non_ws(line); // eat .subckt|.model - name = skip_ws(name); - - - + name = skip_token(line); // Eat .subckt or .model end_ptr = skip_non_ws(name); - return copy_substring(name, end_ptr); } @@ -2890,23 +2890,16 @@ static char *get_model_name(char *line, int num_terminals) char *beg_ptr, *end_ptr; int i = 0; - beg_ptr = skip_non_ws(line); /* eat device name */ - beg_ptr = skip_ws(beg_ptr); - - for (i = 0; i < num_terminals; i++) { /* skip the terminals */ - beg_ptr = skip_non_ws(beg_ptr); - beg_ptr = skip_ws(beg_ptr); - } + beg_ptr = skip_token(line); // Eat device name. + for (i = 0; i < num_terminals; i++) + beg_ptr = skip_token(beg_ptr); // Eat terminal. if (*line == 'r') /* special dealing for r models */ if ((*beg_ptr == '+') || (*beg_ptr == '-') || isdigit_c(*beg_ptr)) { /* looking for a value before model */ - beg_ptr = skip_non_ws(beg_ptr); /* skip the value */ - beg_ptr = skip_ws(beg_ptr); + beg_ptr = skip_token(beg_ptr); /* Skip the value, */ } - end_ptr = skip_non_ws(beg_ptr); - return copy_substring(beg_ptr, end_ptr); } @@ -2918,12 +2911,8 @@ static char *get_model_type(char *line) if (!ciprefix(".model", line)) return NULL; - beg_ptr = skip_non_ws(line); /* eat .model */ - beg_ptr = skip_ws(beg_ptr); - - beg_ptr = skip_non_ws(beg_ptr); /* eat model name */ - beg_ptr = skip_ws(beg_ptr); - + beg_ptr = skip_token(line); /* Eat .model */ + beg_ptr = skip_token(beg_ptr); /* Eat model name. */ return gettok_noparens(&beg_ptr); } @@ -3655,8 +3644,8 @@ static char *inp_fix_subckt(struct names *subckt_w_params, char *s) if (equal && (!strstr(s, "params:") || !isspace_c(s[-1]))) { /* get subckt name (ptr1 will point to name) */ - ptr1 = skip_non_ws(s); - ptr1 = skip_ws(ptr1); + + ptr1 = skip_token(s); for (ptr2 = ptr1; *ptr2 && !isspace_c(*ptr2) && !isquote(*ptr2); ptr2++) ; @@ -4275,8 +4264,8 @@ static void inp_fix_inst_calls_for_numparam( continue; if (d) { char *subckt_line = d->line; - subckt_line = skip_non_ws(subckt_line); - subckt_line = skip_ws(subckt_line); + + subckt_line = skip_token(subckt_line); int num_subckt_params = inp_get_params(subckt_line, subckt_param_names, subckt_param_values); @@ -4385,8 +4374,7 @@ static void inp_get_func_from_line(struct function_env *env, char *line) struct function *function; /* skip `.func' */ - line = skip_non_ws(line); - line = skip_ws(line); + line = skip_token(line); /* get function name */ end = line; @@ -5501,8 +5489,7 @@ static void inp_add_params_to_subckt( if (!strstr(subckt_line, "params:")) { new_line = tprintf("%s params: %s", subckt_line, param_ptr); - subckt_name = skip_non_ws(subckt_line); - subckt_name = skip_ws(subckt_name); + subckt_name = skip_token(subckt_line); end_ptr = skip_non_ws(subckt_name); add_name(subckt_w_params, copy_substring(subckt_name, end_ptr)); } @@ -7867,9 +7854,7 @@ static void inp_fix_temper_in_param(struct card *deck) controlled_exit(EXIT_FAILURE); } - lhs_b = skip_non_ws(curr_line); // eat .param - lhs_b = skip_ws(lhs_b); - + lhs_b = skip_token(curr_line); // Eat .param. lhs_e = skip_back_ws(equal_ptr, curr_line); /* skip if this is a function already */ @@ -8094,9 +8079,7 @@ static void inp_fix_agauss_in_param(struct card *deck, char *fcn) controlled_exit(EXIT_FAILURE); } - lhs_b = skip_non_ws(curr_line); // eat .param - lhs_b = skip_ws(lhs_b); - + lhs_b = skip_token(curr_line); // Eat .param. lhs_e = skip_back_ws(equal_ptr, curr_line); /* skip if this is a function already */ @@ -8332,10 +8315,8 @@ static void inp_quote_params(struct card *c, struct card *end_c, char *s = curr_line; - for (j = 0; j < num_terminals + 1; j++) { - s = skip_non_ws(s); - s = skip_ws(s); - } + for (j = 0; j < num_terminals + 1; j++) + s = skip_token(s); while ((s = ya_search_identifier( s, deps[i].param_name, curr_line)) != NULL) { @@ -8403,7 +8384,6 @@ static void inp_quote_params(struct card *c, struct card *end_c, } } - /* VDMOS special: Check for 'vdmos' in .model line. check if 'pchan', then add p to vdmos and ignore 'pchan'. @@ -8429,16 +8409,17 @@ static int inp_vdmos_model(struct card *deck) curr_line = card->line; if (ciprefix(".model", curr_line)) { - cut_line = search_plain_identifier(curr_line, "vdmos"); - if (cut_line) { + cut_line = skip_token(curr_line); + cut_line = skip_token(cut_line); + if (!strncmp(cut_line, "vdmos", 5)) { + /* A VDMOS model line, may be vdmosn or vdmosp if re-input. */ + wl_append_word(&wl, &wl, copy_substring(curr_line, cut_line)); wlb = wl; - if (search_plain_identifier(cut_line, "pchan")) { + if (search_plain_identifier(cut_line, "pchan") || + cut_line[5] == 'p') { wl_append_word(NULL, &wl, copy("vdmosp (")); } - else if (search_plain_identifier(cut_line, "nchan")) { - wl_append_word(NULL, &wl, copy("vdmosn (")); - } else { wl_append_word(NULL, &wl, copy("vdmosn (")); } @@ -9199,9 +9180,10 @@ static struct modellist *inp_find_model_1( struct nscope *scope, const char *name) { struct modellist *p = scope->models; - for (; p; p = p->next) + for (; p; p = p->next) { if (model_name_match(name, p->modelname)) break; + } return p; } diff --git a/src/frontend/subckt.c b/src/frontend/subckt.c index 4cb7be417..d7ec7ce7c 100644 --- a/src/frontend/subckt.c +++ b/src/frontend/subckt.c @@ -583,11 +583,18 @@ doit(struct card *deck, wordlist *modnames) { scale = 1; error = 0; - /* Second pass: do the replacements. */ + /* Second pass: do the replacements. + Check if binning is used for .model inside of the subcircuit. + Reduce .model lines to the one with appropriate w and l. + (Inspired by Skywater PDK with excessive use of binning (161 bins) + in the subcircuit referencing a MOS device) */ do { /* while (!error && numpasses-- && gotone) */ struct card *c = deck; struct card *prev_of_c = NULL; + bool foundmodel = FALSE; + gotone = FALSE; + for (; c; prev_of_c = c, c = c->nextcard) { if (ciprefix(invoke, c->line)) { /* found reference to .subckt (i.e. component with refdes X) */ @@ -597,16 +604,13 @@ doit(struct card *deck, wordlist *modnames) { gotone = TRUE; t = tofree = s = copy(c->line); /* s & t hold copy of component line */ - /* make scname point to first non-whitepace chars after refdes invocation - * e.g. if invocation is Xreference, *scname = reference - */ + /* scname contains the refdes Xname */ tofree2 = scname = gettok(&s); - /*scname += strlen(invoke); */ while ((*scname == ' ') || (*scname == '\t') || (*scname == ':')) scname++; - /* Now set s to point to last non-space chars in line (i.e. - * the name of the model invoked + /* Now set s to point to last non-space chars in the x line (i.e. + * the name of the model invoked) */ while (*s) s++; @@ -617,38 +621,47 @@ doit(struct card *deck, wordlist *modnames) { s--; s++; - /* iterate through .subckt list and look for .subckt name invoked */ + /* Iterate through .subckt list and look for .subckt name + corresponding to the subckt name extracted from the x line */ for (sss = subs; sss; sss = sss->su_next) if (eq(sss->su_name, s)) break; - - /* At this point, sss points to the .subckt invoked, - * and scname points to the netnames - * involved. + /* At this point, + * c is the card with the x line. + * scname points to the netname of the x line involved. + * s is the subckt name extracted from the x line. + * sss points to the subcircuit referenced by the x line + * sss->su_def is the contents of the subcircuit. */ - /* If no .subckt is found, don't complain -- this might be an * instance of a subckt that is defined above at higher level. */ if (sss) { // tprint(sss->su_def); + + /* copy of the contents between .subckt and .ends */ struct card *su_deck = inp_deckcopy(sss->su_def); /* If we have modern PDKs, we have to reduce the amount of memory required. We try to reduce the models to the one really used. - Otherwise su_deck is full of unused binning models.*/ + Otherwise su_deck is full of unused binning models. + c->w > 0 and c->l > 0 point to an x line with given w and l + (typically a call to a MOS device). */ if ((newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { /* extract wmin, wmax, lmin, lmax */ - struct card* new_deck = su_deck; + struct card* enter_su_deck = su_deck; struct card* prev = NULL; while (su_deck) { + /* find a .model line */ if (!ciprefix(".model", su_deck->line)) { prev = su_deck; su_deck = su_deck->nextcard; continue; } - + /* check if line contains wmin, wmax, lmin, lmax + if available, extract its values, + if not, go to next line */ char* curr_line = su_deck->line; float fwmin, fwmax, flmin, flmax; char *wmin = strstr(curr_line, " wmin="); @@ -716,32 +729,39 @@ doit(struct card *deck, wordlist *modnames) { su_deck = su_deck->nextcard; continue; } - + /* check if x line's w and l are withing the limites of wmin, wmax, lmin, lmax */ float csl = (float)scale * c->l; /* scale by nf */ float csw = (float)scale * c->w / c->nf; /*fprintf(stdout, "Debug: nf = %f\n", c->nf);*/ if (csl >= flmin && csl < flmax && csw >= fwmin && csw < fwmax) { - /* use the current .model card */ + /* if within the limits, use the current .model card */ prev = su_deck; su_deck = su_deck->nextcard; + foundmodel = TRUE; continue; } else { + /* if not within the limits, + delete the .model line not fitting the device */ struct card* tmpcard = su_deck->nextcard; line_free_x(prev->nextcard, FALSE); su_deck = prev->nextcard = tmpcard; } } - su_deck = new_deck; + /* go back to the first card of su_deck */ + su_deck = enter_su_deck; } - if (!su_deck) { - fprintf(stderr, "\nError: Could not find a model for device %s in subcircuit %s\n", - scname, sss->su_name); + if (!foundmodel && (newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) { + fprintf(stderr, "\nError: Could not find a model\n" + " for device %s in transistor subcircuit %s\n", scname, sss->su_name); + fprintf(stderr, " with w = %.3g and l = %.3g\n\n", c->w, c->l); controlled_exit(1); } + foundmodel = FALSE; + struct card *rest_of_c = c->nextcard; /* Now we have to replace this line with the @@ -782,8 +802,8 @@ doit(struct card *deck, wordlist *modnames) { tfree(tofree); tfree(tofree2); - } - } + } /* if (ciprefix(invoke, c->line)) */ + } /* for (; c; prev_of_c = c, c = c->nextcard) */ } while (!error && numpasses-- && gotone); diff --git a/src/spicelib/analysis/cktdltn.c b/src/spicelib/analysis/cktdltn.c index deca3b294..7be581fb6 100644 --- a/src/spicelib/analysis/cktdltn.c +++ b/src/spicelib/analysis/cktdltn.c @@ -12,15 +12,15 @@ Copyright 1992 Regents of the University of California. All rights reserved. /* ARGSUSED */ int -CKTdltNod(CKTcircuit *ckt, CKTnode *node) +CKTdltNod(CKTcircuit* ckt, CKTnode* node) { return CKTdltNNum(ckt, node->number); } int -CKTdltNNum(CKTcircuit *ckt, int num) +CKTdltNNum(CKTcircuit* ckt, int num) { - CKTnode *n, *prev, *node, *sprev; + CKTnode* n, * prev, * node, * sprev; int error; if (!ckt->prev_CKTlastNode->number || num <= ckt->prev_CKTlastNode->number) { @@ -28,32 +28,33 @@ CKTdltNNum(CKTcircuit *ckt, int num) controlled_exit(EXIT_FAILURE); } - prev = NULL; - node = NULL; + prev = NULL; + node = NULL; sprev = NULL; for (n = ckt->CKTnodes; n; n = n->next) { - if (n->number == num) { - node = n; - sprev = prev; - } - prev = n; + if (n->number == num) { + node = n; + sprev = prev; + } + prev = n; } if (!node) - return OK; + return OK; ckt->CKTmaxEqNum -= 1; if (!sprev) { - ckt->CKTnodes = node->next; - } else { - sprev->next = node->next; + ckt->CKTnodes = node->next; + } + else { + sprev->next = node->next; } if (node == ckt->CKTlastNode) - ckt->CKTlastNode = sprev; + ckt->CKTlastNode = sprev; - error = SPfrontEnd->IFdelUid (ckt, node->name, UID_SIGNAL); + error = SPfrontEnd->IFdelUid(ckt, node->name, UID_SIGNAL); tfree(node); return error; diff --git a/src/spicelib/devices/mos1/mos1noi.c b/src/spicelib/devices/mos1/mos1noi.c index dcd31a497..7b3f9f696 100644 --- a/src/spicelib/devices/mos1/mos1noi.c +++ b/src/spicelib/devices/mos1/mos1noi.c @@ -145,9 +145,9 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, N_GAIN, inst->MOS1dNodePrime, inst->MOS1sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef * exp(model->MOS1fNexp * - log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) / (data->freq * inst->MOS1w * (inst->MOS1l - 2 * model->MOS1latDiff) * @@ -155,18 +155,18 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, } else { switch (model->MOS1nlev) { case 0: - noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef * exp(model->MOS1fNexp * - log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) / (data->freq * (inst->MOS1l - 2 * model->MOS1latDiff) * (inst->MOS1l - 2 * model->MOS1latDiff) * sqrt(coxSquared)); break; case 1: - noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * + noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef * exp(model->MOS1fNexp * - log(MAX(fabs(inst->MOS1cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) / (data->freq * inst->MOS1w * (inst->MOS1l - 2 * model->MOS1latDiff) * @@ -174,7 +174,7 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, break; case 2: case 3: noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef * - inst->MOS1gm * inst->MOS1gm / + inst->MOS1gm * inst->MOS1gm / inst->MOS1m / (pow(data->freq, model->MOS1fNexp) * inst->MOS1w * (inst->MOS1l - 2 * model->MOS1latDiff) * diff --git a/src/spicelib/devices/mos2/mos2load.c b/src/spicelib/devices/mos2/mos2load.c index 161a1641a..c82f927d2 100644 --- a/src/spicelib/devices/mos2/mos2load.c +++ b/src/spicelib/devices/mos2/mos2load.c @@ -34,7 +34,7 @@ MOS2load(GENmodel *inModel, CKTcircuit *ckt) double GateBulkOverlapCap; double GateDrainOverlapCap; double GateSourceOverlapCap; - double OxideCap; + double OxideCap, unscaledOxideCap; double SourceSatCur; double arg; double cbhat; @@ -144,8 +144,8 @@ MOS2load(GENmodel *inModel, CKTcircuit *ckt) here->MOS2m * EffectiveLength; Beta = here->MOS2tTransconductance * here->MOS2w * here->MOS2m/EffectiveLength; - OxideCap = model->MOS2oxideCapFactor * EffectiveLength * - here->MOS2m * here->MOS2w; + unscaledOxideCap = model->MOS2oxideCapFactor * EffectiveLength * here->MOS2w; + OxideCap = unscaledOxideCap*here->MOS2m; if(SenCond){ @@ -599,7 +599,7 @@ next1: if(vbs <= -3*vt) { /*XXX constant per device */ factor = 0.125*model->MOS2narrowFactor*2.0*M_PI*EPSSIL/ - OxideCap*EffectiveLength; + unscaledOxideCap*EffectiveLength; /*XXX constant per device */ eta = 1.0+factor; vbin = here->MOS2tVbi*model->MOS2type+factor*phiMinVbs; @@ -664,7 +664,7 @@ next1: if(vbs <= -3*vt) { 1e4 /*(cm**2/m**2)*/; cdonco = -(gamasd*dsrgdb+dgddvb*sarg1)+factor; - xn = 1.0+cfs/OxideCap*here->MOS2m* + xn = 1.0+cfs/unscaledOxideCap* here->MOS2w*EffectiveLength+cdonco; tmp = vt*xn; diff --git a/src/spicelib/devices/mos2/mos2noi.c b/src/spicelib/devices/mos2/mos2noi.c index 1d208b5d9..fdbecb7f6 100644 --- a/src/spicelib/devices/mos2/mos2noi.c +++ b/src/spicelib/devices/mos2/mos2noi.c @@ -134,9 +134,9 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, N_GAIN, inst->MOS2dNodePrime, inst->MOS2sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef * exp(model->MOS2fNexp * - log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) / (data->freq * inst->MOS2w * (inst->MOS2l - 2 * model->MOS2latDiff) * @@ -144,18 +144,18 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, } else { switch (model->MOS2nlev) { case 0: - noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef * exp(model->MOS2fNexp * - log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) / (data->freq * (inst->MOS2l - 2 * model->MOS2latDiff) * (inst->MOS2l - 2 * model->MOS2latDiff) * model->MOS2oxideCapFactor); break; case 1: - noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * + noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef * exp(model->MOS2fNexp * - log(MAX(fabs(inst->MOS2cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) / (data->freq * inst->MOS2w * (inst->MOS2l - 2 * model->MOS2latDiff) * @@ -163,7 +163,7 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, break; case 2: case 3: noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef * - inst->MOS2gm * inst->MOS2gm / + inst->MOS2gm * inst->MOS2gm / inst->MOS2m / (pow(data->freq, model->MOS2fNexp) * inst->MOS2w * (inst->MOS2l - 2 * model->MOS2latDiff) * diff --git a/src/spicelib/devices/mos3/mos3noi.c b/src/spicelib/devices/mos3/mos3noi.c index 4787fa335..65afec9e7 100644 --- a/src/spicelib/devices/mos3/mos3noi.c +++ b/src/spicelib/devices/mos3/mos3noi.c @@ -134,9 +134,9 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, N_GAIN, inst->MOS3dNodePrime, inst->MOS3sNodePrime, (double) 0.0); if (newcompat.s3) { - noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef * exp(model->MOS3fNexp * - log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) / (data->freq * (inst->MOS3w - 2 * model->MOS3widthNarrow) * (inst->MOS3l - 2 * model->MOS3latDiff) * @@ -144,18 +144,18 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, } else { switch (model->MOS3nlev) { case 0: - noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef * exp(model->MOS3fNexp * - log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) / (data->freq * (inst->MOS3l - 2 * model->MOS3latDiff) * (inst->MOS3l - 2 * model->MOS3latDiff) * model->MOS3oxideCapFactor); break; case 1: - noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * + noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef * exp(model->MOS3fNexp * - log(MAX(fabs(inst->MOS3cd), N_MINLOG))) / + log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) / (data->freq * (inst->MOS3w - 2 * model->MOS3widthNarrow) * (inst->MOS3l - 2 * model->MOS3latDiff) * @@ -163,7 +163,7 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt, break; case 2: case 3: noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef * - inst->MOS3gm * inst->MOS3gm / + inst->MOS3gm * inst->MOS3gm / inst->MOS3m / (pow(data->freq, model->MOS3fNexp) * (inst->MOS3w - 2 * model->MOS3widthNarrow) * (inst->MOS3l - 2 * model->MOS3latDiff) * diff --git a/src/spicelib/devices/mos9/mos9noi.c b/src/spicelib/devices/mos9/mos9noi.c index 69f9bfd80..63dbe3146 100644 --- a/src/spicelib/devices/mos9/mos9noi.c +++ b/src/spicelib/devices/mos9/mos9noi.c @@ -94,12 +94,11 @@ MOS9noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, NevalSrc(&noizDens[MOS9FLNOIZ], NULL, ckt, N_GAIN,inst->MOS9dNodePrime, inst->MOS9sNodePrime, (double)0.0); - noizDens[MOS9FLNOIZ] *= model->MOS9fNcoef * + noizDens[MOS9FLNOIZ] *= inst->MOS9m * model->MOS9fNcoef * exp(model->MOS9fNexp * - log(MAX(fabs(inst->MOS9cd),N_MINLOG))) / + log(MAX(fabs(inst->MOS9cd / inst->MOS9m),N_MINLOG))) / (data->freq * (inst->MOS9w - 2*model->MOS9widthNarrow) * - inst->MOS9m * (inst->MOS9l - 2*model->MOS9latDiff) * model->MOS9oxideCapFactor * model->MOS9oxideCapFactor); lnNdens[MOS9FLNOIZ] = diff --git a/src/spicelib/devices/vsrc/vsrcacct.c b/src/spicelib/devices/vsrc/vsrcacct.c index df890ed76..cd7d1111a 100644 --- a/src/spicelib/devices/vsrc/vsrcacct.c +++ b/src/spicelib/devices/vsrc/vsrcacct.c @@ -65,7 +65,7 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel) && here->VSRCcoeffs[4] != 0.0 ? here->VSRCcoeffs[4] : ckt->CKTstep; PW = here->VSRCfunctionOrder > 5 - && here->VSRCcoeffs[5] != 0.0 + && here->VSRCcoeffs[5] >= 0.0 ? here->VSRCcoeffs[5] : ckt->CKTfinalTime; PER = here->VSRCfunctionOrder > 6 && here->VSRCcoeffs[6] != 0.0 diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index c74c9a756..0ecf99c25 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -112,7 +112,7 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) && here->VSRCcoeffs[4] != 0.0 ? here->VSRCcoeffs[4] : ckt->CKTstep; PW = here->VSRCfunctionOrder > 5 - && here->VSRCcoeffs[5] != 0.0 + && here->VSRCcoeffs[5] >= 0.0 ? here->VSRCcoeffs[5] : ckt->CKTfinalTime; PER = here->VSRCfunctionOrder > 6 && here->VSRCcoeffs[6] != 0.0 diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index bc98e770b..ac7e88b09 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -149,12 +149,18 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab) if (p) { char *value; - INPgetTok(&line, &value, 1); - modtmp->INPmodfast->defaults = - wl_cons(copy(parm), - wl_cons(value, - modtmp->INPmodfast->defaults)); + INPgetTok(&line, &value, 1); + if (p->dataType & IF_SET) { + modtmp->INPmodfast->defaults = + wl_cons(copy(parm), + wl_cons(value, modtmp->INPmodfast->defaults)); + } else { + fprintf(stderr, + "Ignoring attempt to set a default " + "for read-only instance parameter %s in:\n %s\n", + p->keyword, modtmp->INPmodLine->line); + } } else { double dval; @@ -286,6 +292,7 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) { + /* exact: 1, with binning extension .[0-9]: 2*/ if (model_name_match(name, modtmp->INPmodName) < 2) continue; @@ -328,8 +335,8 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char *model = modtmp; return NULL; } + fprintf(stderr, "Warning: no model found for w=%.3e and l=%.3e\n", w, l); } - return NULL; } diff --git a/src/xspice/verilog/icarus_shim.c b/src/xspice/verilog/icarus_shim.c index ff1c6fb3f..9d540fcd6 100644 --- a/src/xspice/verilog/icarus_shim.c +++ b/src/xspice/verilog/icarus_shim.c @@ -4,7 +4,7 @@ * an Icarus Verilog simulation (libvvp.so). * Licensed on the same terms as Ngspice. * - * Copyright (c) 2024 Giles Atkinson + * Copyright (c) 2024-2025 Giles Atkinson */ #include @@ -18,6 +18,12 @@ #include "coroutine_shim.h" +#ifdef _MSC_VER +#include "../../../visualc/src/include/ngspice/config.h" +#else +#include "ngspice/config.h" // For NGSPICELIBDIR +#endif + #include "ngspice/cmtypes.h" // For Digital_t #include "ngspice/cosim.h" diff --git a/src/xspice/verilog/vlnggen b/src/xspice/verilog/vlnggen index 0486259ae..bd846d373 100644 --- a/src/xspice/verilog/vlnggen +++ b/src/xspice/verilog/vlnggen @@ -342,7 +342,7 @@ else if $fh > 0 fclose $fh else - echo Can not find bulid file $msvcfile + echo Can not find build file $msvcfile quit end