Introduced the possibility to look for parameters in models and not only
in devices.
This commit is contained in:
parent
59a2a6705c
commit
f0d3b7c976
11
ChangeLog
11
ChangeLog
|
|
@ -1,3 +1,14 @@
|
|||
2009-01-15 Paolo Nenzi
|
||||
* src/frontend/{spiceif.c, spiceif.h, vectors.c}, src/include/fteext.h,
|
||||
* src/main.c:
|
||||
3: A new function finddev_special() has been introduced to look for
|
||||
references like @BC107[is] and to verify if we asked for a model
|
||||
or a device and thus call the spif_getparam_special() correctly
|
||||
in vectors.c. The new @ syntax is @{model,device}[parameter].
|
||||
- A. Roldan - Espice.
|
||||
Note: I have modified the implementation putting the
|
||||
spif_getparam_special() in the if_getparam definition in main.c
|
||||
|
||||
2009-01-15 Dietmar Warning
|
||||
* src/include/wstdio.h: read fct. prototype for older MSC compiler
|
||||
* src/misc/alloc.c: heap also needed under windows with tcl
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ static int doset(void *ckt, int typecode, GENinstance *dev, GENmodel *mod,
|
|||
IFparm *opt, struct dvec *val);
|
||||
static int finddev(void *ck, char *name, void **devptr, void **modptr);
|
||||
|
||||
/*espice fix integration */
|
||||
static int finddev_special(char *ck, char *name, void **devptr, void **modptr, int *device_or_model);
|
||||
|
||||
/* Input a single deck, and return a pointer to the circuit. */
|
||||
|
||||
|
|
@ -550,6 +552,182 @@ if_errstring(int code)
|
|||
return (INPerror(code));
|
||||
}
|
||||
|
||||
/* Get pointers to a device, its model, and its type number given the name. If
|
||||
* there is no such device, try to find a model with that name
|
||||
* device_or_model says if we are referencing a device or a model.
|
||||
* finddev_special(ck, name, devptr, modptr,device_or_model):
|
||||
* Introduced to look for correct reference in expression like print @BC107 [is]
|
||||
* and find out whether a model or a device parameter is referenced and properly
|
||||
* call the spif_getparam_special (ckt, name, param, ind, do_model) function in
|
||||
* vector.c - A. Roldan (espice).
|
||||
*/
|
||||
static int
|
||||
finddev_special(
|
||||
char *ck,
|
||||
char *name,
|
||||
void **devptr,
|
||||
void **modptr,
|
||||
int *device_or_model)
|
||||
{
|
||||
int err;
|
||||
int type = -1;
|
||||
|
||||
err = (*(ft_sim->findInstance))((void *)ck,&type,devptr,name,NULL,NULL);
|
||||
if(err == OK)
|
||||
{
|
||||
*device_or_model=0;
|
||||
return(type);
|
||||
}
|
||||
type = -1;
|
||||
*devptr = (void *)NULL;
|
||||
err = (*(ft_sim->findModel))((void *)ck,&type,modptr,name);
|
||||
if(err == OK)
|
||||
{
|
||||
*device_or_model=1;
|
||||
return(type);
|
||||
}
|
||||
*modptr = (void *)NULL;
|
||||
*device_or_model=2;
|
||||
return(-1);
|
||||
|
||||
}
|
||||
|
||||
/* Get a parameter value from the circuit. If name is left unspecified,
|
||||
* we want a circuit parameter. Now works both for devices and models.
|
||||
* A.Roldan (espice)
|
||||
*/
|
||||
struct variable *
|
||||
spif_getparam_special(void *ckt,char **name,char *param,int ind,int do_model)
|
||||
{
|
||||
struct variable *vv = NULL, *tv;
|
||||
IFvalue *pv;
|
||||
IFparm *opt;
|
||||
int typecode, i, modelo_dispositivo;
|
||||
GENinstance *dev=(GENinstance *)NULL;
|
||||
GENmodel *mod=(GENmodel *)NULL;
|
||||
IFdevice *device;
|
||||
|
||||
/* fprintf(cp_err, "Calling if_getparam(%s, %s)\n", *name, param); */
|
||||
|
||||
if (!param || (param && eq(param, "all")))
|
||||
{
|
||||
INPretrieve(name,(INPtables *)ft_curckt->ci_symtab);
|
||||
typecode = finddev_special(ckt, *name, (void**)&dev, (void**)&mod,&modelo_dispositivo);
|
||||
if (typecode == -1)
|
||||
{
|
||||
fprintf(cp_err,"Error: no such device or model name %s\n",*name);
|
||||
return (NULL);
|
||||
}
|
||||
device = ft_sim->devices[typecode];
|
||||
if(!modelo_dispositivo)
|
||||
{
|
||||
/* It is a device */
|
||||
for (i = 0; i < *(device->numInstanceParms); i++)
|
||||
{
|
||||
opt = &device->instanceParms[i];
|
||||
if(opt->dataType & IF_REDUNDANT || !opt->description) continue;
|
||||
if(!(opt->dataType & IF_ASK)) continue;
|
||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||
if (pv)
|
||||
{
|
||||
tv = parmtovar(pv, opt);
|
||||
|
||||
/* With the following we pack the name and the acronym of the parameter */
|
||||
{
|
||||
char auxiliar[70],*aux_pointer;
|
||||
sprintf(auxiliar,"%s [%s]",tv->va_name, device->instanceParms[i].keyword);
|
||||
aux_pointer=tv->va_name;
|
||||
free(aux_pointer);
|
||||
tv->va_name = copy(auxiliar);
|
||||
}
|
||||
if (vv) tv->va_next = vv;
|
||||
vv = tv;
|
||||
}
|
||||
else
|
||||
fprintf(cp_err,"Internal Error: no parameter '%s' on device '%s'\n",
|
||||
device->instanceParms[i].keyword,device->name);
|
||||
}
|
||||
return (vv);
|
||||
}
|
||||
else /* Is it a model or a device ? */
|
||||
{
|
||||
/* It is a model */
|
||||
for (i = 0; i < *(device->numModelParms); i++)
|
||||
{
|
||||
opt = &device->modelParms[i];
|
||||
if(opt->dataType & IF_REDUNDANT || !opt->description) continue;
|
||||
|
||||
/* We check that the parameter is interesting and therefore is
|
||||
* implemented in the corresponding function ModelAsk. Originally
|
||||
* the argument of "if" was: || (opt->dataType & IF_STRING)) continue;
|
||||
* so, a model parameter defined like OP("type", MOS_SGT_MOD_TYPE,
|
||||
* IF_STRING, N-channel or P-channel MOS") would not be printed.
|
||||
*/
|
||||
|
||||
/* if(!(opt->dataType & IF_ASK ) || (opt->dataType & IF_UNINTERESTING ) || (opt->dataType & IF_STRING)) continue; */
|
||||
if(!(opt->dataType & IF_ASK ) || (opt->dataType & IF_UNINTERESTING )) continue;
|
||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||
if (pv)
|
||||
{
|
||||
tv = parmtovar(pv, opt);
|
||||
/* Inside parmtovar:
|
||||
* 1. tv->va_name = copy(opt->description);
|
||||
* 2. Copy the type of variable of IFparm into a variable (thus parm-to-var)
|
||||
* vv->va_type = opt->dataType
|
||||
* The long description of the parameter:
|
||||
* IFparm MOS_SGTmPTable[] = { /* model parameters */
|
||||
* OP("type", MOS_SGT_MOD_TYPE, IF_STRING, "N-channel or P-channel MOS")
|
||||
* goes into tv->va_name to put braces around the parameter of the model
|
||||
* tv->va_name += device->modelParms[i].keyword;
|
||||
*/
|
||||
{
|
||||
char auxiliar[70],*aux_pointer;
|
||||
sprintf(auxiliar,"%s [%s]",tv->va_name,device->modelParms[i].keyword);
|
||||
aux_pointer=tv->va_name;
|
||||
free(aux_pointer);
|
||||
tv->va_name = copy(auxiliar);
|
||||
/* strcpy(aux_pointer,auxiliar); */
|
||||
}
|
||||
/* tv->va_string=device->modelParms[i].keyword; Put the name of the variable */
|
||||
if (vv)
|
||||
{
|
||||
tv->va_next = vv;
|
||||
}
|
||||
vv = tv;
|
||||
}
|
||||
else
|
||||
fprintf(cp_err,"Internal Error: no parameter '%s' on device '%s'\n",device->modelParms[i].keyword,device->name);
|
||||
}
|
||||
return (vv);
|
||||
}
|
||||
}
|
||||
else if (param)
|
||||
{
|
||||
INPretrieve(name,(INPtables *)ft_curckt->ci_symtab);
|
||||
typecode = finddev_special(ckt, *name, (void**)&dev, (void**)&mod,&modelo_dispositivo);
|
||||
if (typecode == -1)
|
||||
{
|
||||
fprintf(cp_err,"Error: no such device or model name %s\n",*name);
|
||||
return (NULL);
|
||||
}
|
||||
device = ft_sim->devices[typecode];
|
||||
opt = parmlookup(device, &dev, param, modelo_dispositivo, 0);
|
||||
if (!opt)
|
||||
{
|
||||
fprintf(cp_err, "Error: no such parameter %s.\n",param);
|
||||
return (NULL);
|
||||
}
|
||||
pv = doask(ckt, typecode, dev, mod, opt, ind);
|
||||
if (pv)
|
||||
vv = parmtovar(pv, opt);
|
||||
return (vv);
|
||||
} else
|
||||
return (if_getstat(ckt, *name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Get a parameter value from the circuit. If name is left unspecified,
|
||||
* we want a circuit parameter.
|
||||
*/
|
||||
|
|
@ -764,14 +942,35 @@ parmtovar(IFvalue *pv, IFparm *opt)
|
|||
break;
|
||||
case IF_REALVEC:
|
||||
vv->va_type = VT_LIST;
|
||||
for (i = 0; i < pv->v.numValue; i++) {
|
||||
for (i = 0; i < pv->v.numValue; i++)
|
||||
{
|
||||
nv = alloc(struct variable);
|
||||
nv->va_next = vv->va_vlist;
|
||||
vv->va_vlist = nv;
|
||||
nv->va_type = VT_REAL;
|
||||
nv->va_real = pv->v.vec.rVec[i];
|
||||
}
|
||||
break;
|
||||
/* Change this so that the values are printed in order and
|
||||
* not in inverted order as happens in the conversion process.
|
||||
* Originally was nv->va_real = pv->v.vec.rVec[i];
|
||||
*/
|
||||
nv->va_real = pv->v.vec.rVec[pv->v.numValue-i-1];
|
||||
}
|
||||
/* It is a linked list where the first node is a variable
|
||||
* pointing to the different values of the variables.
|
||||
*
|
||||
* To access the values of the real variable vector must be
|
||||
* vv->va_V.vV_real=valor node ppal that is of no use.
|
||||
*
|
||||
* In the case of Vin_sin 1 0 sin (0 2 2000)
|
||||
* and of print @vin_sin[sin]
|
||||
*
|
||||
* vv->va_V.vV_list->va_V.vV_real=2000
|
||||
* vv->va_V.vV_list->va_next->va_V.vV_real=2
|
||||
* vv->va_V.vV_list->va_next->va_next->va_V.vV_real=0
|
||||
* So the list is starting from behind, but no problem
|
||||
* This works fine
|
||||
*/
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf(cp_err,
|
||||
"parmtovar: Internal Error: bad PARM type %d.\n",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ void if_dump(void *ckt, FILE *file);
|
|||
void if_cktfree(void *ckt, char *tab);
|
||||
char * if_errstring(int code);
|
||||
struct variable * spif_getparam(void *ckt, char **name, char *param, int ind, int do_model);
|
||||
struct variable * spif_getparam_special(void *ckt,char **name,char *param,int ind,int do_model);
|
||||
void if_setparam_model(void *ckt, char **name, char *val);
|
||||
void if_setparam(void *ckt, char **name, char *param, struct dvec *val, int do_model);
|
||||
int if_analQbyName(void *ckt, int which, void *anal, char *name, IFvalue *parm);
|
||||
|
|
|
|||
|
|
@ -476,7 +476,18 @@ vec_copy(struct dvec *v)
|
|||
nv->v_gridtype = v->v_gridtype;
|
||||
nv->v_plottype = v->v_plottype;
|
||||
nv->v_length = v->v_length;
|
||||
nv->v_rlength = 0; /*XXX???*/
|
||||
|
||||
/* Modified to copy the rlength of origin to destination vecor
|
||||
* instead of always putting it to 0.
|
||||
* As when it comes to make a print does not leave M1 @ @ M1 = 0.0,
|
||||
* to do so in the event that rlength = 0 not print anything on screen
|
||||
* nv-> v_rlength = 0;
|
||||
* Default -> v_rlength = 0 and only if you come from a print or M1 @
|
||||
* @ M1 [all] rlength = 1, after control is one of
|
||||
* if (v-> v_rlength == 0) com_print (wordlist * wl)
|
||||
*/
|
||||
nv->v_rlength = v->v_rlength;
|
||||
|
||||
nv->v_outindex = 0; /*XXX???*/
|
||||
nv->v_linestyle = 0; /*XXX???*/
|
||||
nv->v_color = 0; /*XXX???*/
|
||||
|
|
@ -621,7 +632,7 @@ vec_free_x(struct dvec *v)
|
|||
pl->pl_scale = NULL;
|
||||
}
|
||||
}
|
||||
tfree(v->v_name);
|
||||
if (v->v_name) tfree(v->v_name);
|
||||
if (v->v_realdata) tfree(v->v_realdata);
|
||||
if (v->v_compdata) tfree(v->v_compdata);
|
||||
tfree(v);
|
||||
|
|
|
|||
|
|
@ -449,6 +449,7 @@ extern int if_sens_run();
|
|||
extern struct variable *(*if_getparam)();
|
||||
extern struct variable *nutif_getparam();
|
||||
extern struct variable *spif_getparam();
|
||||
extern struct variable *spif_getparam_special();
|
||||
extern void if_cktfree();
|
||||
extern void if_dump();
|
||||
extern int if_option();
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ show_help(void)
|
|||
printf("Usage: %s [OPTION]... [FILE]...\n"
|
||||
"Simulate the electical circuits in FILE.\n"
|
||||
"\n"
|
||||
" -a --autorun run the loaded netlist\n"
|
||||
" -a --autorun run the loaded netlist\n"
|
||||
" -b, --batch process FILE in batch mode\n"
|
||||
" -c, --circuitfile=FILE set the circuitfile\n"
|
||||
" -i, --interactive run in interactive mode\n"
|
||||
|
|
@ -749,7 +749,7 @@ main(int argc, char **argv)
|
|||
{"help", 0, 0, 'h'},
|
||||
{"version", 0, 0, 'v'},
|
||||
{"batch", 0, 0, 'b'},
|
||||
{"autorun", 0, 0, 'a'},
|
||||
{"autorun", 0, 0, 'a'},
|
||||
{"circuitfile", 0, 0, 'c'},
|
||||
{"interactive", 0, 0, 'i'},
|
||||
{"no-spiceinit", 0, 0, 'n'},
|
||||
|
|
@ -873,7 +873,7 @@ main(int argc, char **argv)
|
|||
#endif
|
||||
} /* orflag */
|
||||
#ifdef SIMULATOR
|
||||
if_getparam = spif_getparam;
|
||||
if_getparam = spif_getparam_special;
|
||||
#else
|
||||
if_getparam = nutif_getparam;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue