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
|
GENinstance *GENinstances; /* pointer to list of instances that have this
|
||||||
* model */
|
* model */
|
||||||
IFuid GENmodName; /* pointer to character string naming 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/devdefs.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
|
#include "ngspice/wordlist.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -31,6 +32,7 @@ CKTmodCrt(CKTcircuit *ckt, int type, GENmodel **modfast, IFuid name)
|
||||||
if (!model)
|
if (!model)
|
||||||
return E_NOMEM;
|
return E_NOMEM;
|
||||||
|
|
||||||
|
model->defaults = NULL;
|
||||||
model->GENmodType = type;
|
model->GENmodType = type;
|
||||||
model->GENmodName = name;
|
model->GENmodName = name;
|
||||||
model->GENnextModel = ckt->CKThead[type];
|
model->GENnextModel = ckt->CKThead[type];
|
||||||
|
|
@ -54,5 +56,6 @@ GENinstanceFree(GENinstance *inst)
|
||||||
void
|
void
|
||||||
GENmodelFree(GENmodel *model)
|
GENmodelFree(GENmodel *model)
|
||||||
{
|
{
|
||||||
|
wl_free(model->defaults);
|
||||||
txfree(model);
|
txfree(model);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,44 @@ INPdevParse(char **line, CKTcircuit *ckt, int dev, GENinstance *fast,
|
||||||
else
|
else
|
||||||
*leading = 0.0;
|
*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') {
|
while (**line != '\0') {
|
||||||
error = INPgetTok(line, &parm, 1);
|
error = INPgetTok(line, &parm, 1);
|
||||||
if (!*parm) {
|
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
|
* code moved from INPgetMod
|
||||||
*/
|
*/
|
||||||
|
|
@ -113,6 +127,18 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
|
||||||
INPgetValue(ckt, &line, IF_REAL, tab);
|
INPgetValue(ckt, &line, IF_REAL, tab);
|
||||||
} else {
|
} 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;
|
double dval;
|
||||||
|
|
||||||
/* want only the parameter names in output - not the values */
|
/* 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,
|
err = INPerrCat(err,
|
||||||
tprintf("unrecognized parameter (%s) - ignored",
|
tprintf("unrecognized parameter (%s) - ignored",
|
||||||
parm));
|
parm));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FREE(parm);
|
FREE(parm);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
## Process this file with automake to produce Makefile.in
|
## 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
|
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