spicelib/parser, support instance parameter defaults on .model lines
This commit is contained in:
parent
7363532d11
commit
1a39d3f59d
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue