diff --git a/src/include/ngspice/gendefs.h b/src/include/ngspice/gendefs.h index 27c89d2e3..a04790ab0 100644 --- a/src/include/ngspice/gendefs.h +++ b/src/include/ngspice/gendefs.h @@ -44,6 +44,7 @@ struct GENmodel { /* model structure for a resistor */ GENinstance *GENinstances; /* pointer to list of instances that have this * model */ IFuid GENmodName; /* pointer to character string naming this model */ + struct wordlist *defaults; /* default instance parameters */ }; diff --git a/src/spicelib/analysis/cktmcrt.c b/src/spicelib/analysis/cktmcrt.c index f8b6382c6..3c065e7d0 100644 --- a/src/spicelib/analysis/cktmcrt.c +++ b/src/spicelib/analysis/cktmcrt.c @@ -14,6 +14,7 @@ Author: 1985 Thomas L. Quarles #include "ngspice/devdefs.h" #include "ngspice/cktdefs.h" #include "ngspice/sperror.h" +#include "ngspice/wordlist.h" @@ -31,6 +32,7 @@ CKTmodCrt(CKTcircuit *ckt, int type, GENmodel **modfast, IFuid name) if (!model) return E_NOMEM; + model->defaults = NULL; model->GENmodType = type; model->GENmodName = name; model->GENnextModel = ckt->CKThead[type]; @@ -54,5 +56,6 @@ GENinstanceFree(GENinstance *inst) void GENmodelFree(GENmodel *model) { + wl_free(model->defaults); txfree(model); } diff --git a/src/spicelib/parser/inpdpar.c b/src/spicelib/parser/inpdpar.c index 64a19eaec..a7ae4f59c 100644 --- a/src/spicelib/parser/inpdpar.c +++ b/src/spicelib/parser/inpdpar.c @@ -60,6 +60,44 @@ INPdevParse(char **line, CKTcircuit *ckt, int dev, GENinstance *fast, else *leading = 0.0; + wordlist *x = fast->GENmodPtr->defaults; + for (; x; x = x->wl_next->wl_next) { + char *parameter = x->wl_word; + char *value = x->wl_next->wl_word; + + IFparm *p = find_instance_parameter(parameter, device); + + if (!p) { + errbuf = tprintf(" unknown parameter (%s) \n", parameter); + rtn = errbuf; + goto quit; + } + + val = INPgetValue(ckt, &value, p->dataType, tab); + if (!val) { + rtn = INPerror(E_PARMVAL); + goto quit; + } + + error = ft_sim->setInstanceParm (ckt, fast, p->id, val, NULL); + if (error) { + rtn = INPerror(error); + goto quit; + } + + /* delete the union val */ + switch (p->dataType & IF_VARTYPES) { + case IF_REALVEC: + tfree(val->v.vec.rVec); + break; + case IF_INTVEC: + tfree(val->v.vec.iVec); + break; + default: + break; + } + } + while (**line != '\0') { error = INPgetTok(line, &parm, 1); if (!*parm) { diff --git a/src/spicelib/parser/inpgmod.c b/src/spicelib/parser/inpgmod.c index 9ec2e27da..8a68dceb1 100644 --- a/src/spicelib/parser/inpgmod.c +++ b/src/spicelib/parser/inpgmod.c @@ -48,6 +48,20 @@ find_model_parameter(const char *name, IFdevice *device) } +static IFparm * +find_instance_parameter(const char *name, IFdevice *device) +{ + IFparm *p = device->instanceParms; + IFparm *p_end = p + *(device->numInstanceParms); + + for (; p < p_end; p++) + if (strcmp(name, p->keyword) == 0) + return p; + + return NULL; +} + + /* * code moved from INPgetMod */ @@ -113,6 +127,18 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab) INPgetValue(ckt, &line, IF_REAL, tab); } else { + p = find_instance_parameter(parm, device); + + if (p) { + char *value; + INPgetTok(&line, &value, 1); + + modtmp->INPmodfast->defaults = + wl_cons(copy(parm), + wl_cons(value, + modtmp->INPmodfast->defaults)); + } else { + double dval; /* want only the parameter names in output - not the values */ @@ -127,6 +153,7 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab) err = INPerrCat(err, tprintf("unrecognized parameter (%s) - ignored", parm)); + } } FREE(parm); } diff --git a/tests/regression/model/Makefile.am b/tests/regression/model/Makefile.am index 211269197..d2fcd85ba 100644 --- a/tests/regression/model/Makefile.am +++ b/tests/regression/model/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in -TESTS = binning-1.cir special-names-1.cir +TESTS = binning-1.cir special-names-1.cir instance-defaults.cir TESTS_ENVIRONMENT = ngspice_vpath=$(srcdir) $(SHELL) $(top_srcdir)/tests/bin/check.sh $(top_builddir)/src/ngspice diff --git a/tests/regression/model/instance-defaults.cir b/tests/regression/model/instance-defaults.cir new file mode 100644 index 000000000..2d52b2840 --- /dev/null +++ b/tests/regression/model/instance-defaults.cir @@ -0,0 +1,20 @@ +* check whether .model accepts instance defaults + +v1 1 0 dc=1 +r1 1 0 myres + +.model myres r(resistance=2k) + +.control + +op + +if abs(i(v1)/-0.5mA - 1) > 1e-9 + echo "ERROR: check failed" + quit 1 +else + echo "INFO: ok" + quit 0 +end + +.endc diff --git a/tests/regression/model/instance-defaults.out b/tests/regression/model/instance-defaults.out new file mode 100644 index 000000000..24e56ad12 --- /dev/null +++ b/tests/regression/model/instance-defaults.out @@ -0,0 +1,9 @@ + +Circuit: * check whether .model accepts instance defaults + +Doing analysis at TEMP = 27.000000 and TNOM = 27.000000 + + + +No. of Data Rows : 1 +INFO: ok