spicelib/parser, support instance parameter defaults on .model lines

This commit is contained in:
rlar 2018-01-10 10:50:04 +01:00 committed by Holger Vogt
parent 7363532d11
commit 1a39d3f59d
7 changed files with 99 additions and 1 deletions

View File

@ -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 */
};

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 */
@ -128,6 +154,7 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
tprintf("unrecognized parameter (%s) - ignored",
parm));
}
}
FREE(parm);
}

View File

@ -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

View File

@ -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

View File

@ -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