codemodel instance parameters, working

This commit is contained in:
Florian Ballenegger 2020-10-01 16:39:59 +02:00
parent 7c0688cca4
commit 1b64cebf9a
16 changed files with 282 additions and 107 deletions

View File

@ -1968,14 +1968,28 @@ static char *get_model_type(char *line)
return gettok_noparens(&beg_ptr); return gettok_noparens(&beg_ptr);
} }
static inline char *skip_back_non_ws_nonc(const char *s, const char *start, char c) { while (s > start && !isspace_c(s[-1]) && (s[-1]!=c)) s--; return (char *) s; }
static char *get_adevice_model_name(char *line) static char *get_adevice_model_name(char *line)
{ {
char *ptr_end, *ptr_beg; char *ptr_end, *ptr_beg;
char *prev;
/* F.B. added backward skipping param=val */
for(ptr_end=strchr(line, '\0'); ptr_end>line; ) {
ptr_end = skip_back_ws(ptr_end, line);
ptr_beg = skip_back_non_ws_nonc(ptr_end, line, '=');
prev = skip_back_ws(ptr_beg, line);
if(prev>line && prev[-1]=='=') {
prev = skip_back_ws(prev-1, line); /* backskip \s*= */
ptr_end=skip_back_non_ws(prev, line); /* backskip param= */
} else
break; /* found model */
}
if(ptr_beg == line)
return copy_substring(ptr_beg,ptr_beg); /* did not found the model */
ptr_end = skip_back_ws(strchr(line, '\0'), line); printf("adev mod name: %s\n", ptr_beg);
ptr_beg = skip_back_non_ws(ptr_end, line);
return copy_substring(ptr_beg, ptr_end); return copy_substring(ptr_beg, ptr_end);
} }
@ -8297,7 +8311,7 @@ static void inp_check_syntax(struct card *deck)
} }
else { else {
if (!check_ch) { if (!check_ch) {
fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %\"!:,'\n", *cut_line); fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %%\"!:,'\n", *cut_line);
fprintf(stderr, " in netlist or included files, will be replaced with '*'\n"); fprintf(stderr, " in netlist or included files, will be replaced with '*'\n");
check_ch = 1; /* just one warning */ check_ch = 1; /* just one warning */
} }

View File

@ -97,6 +97,7 @@ static int numdevs(char *s);
static wordlist *modtranslate(struct card *deck, char *subname, wordlist *new_modnames); static wordlist *modtranslate(struct card *deck, char *subname, wordlist *new_modnames);
static void devmodtranslate(struct card *deck, char *subname, wordlist * const orig_modnames); static void devmodtranslate(struct card *deck, char *subname, wordlist * const orig_modnames);
static int inp_numnodes(char c); static int inp_numnodes(char c);
static char *search_adevice_model_name(char *line);
#define N_GLOBAL_NODES 1005 #define N_GLOBAL_NODES 1005
@ -1041,23 +1042,18 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha
translate_inst_name(&buffer, scname, name, NULL); translate_inst_name(&buffer, scname, name, NULL);
bxx_putc(&buffer, ' '); bxx_putc(&buffer, ' ');
if(name)
tfree(name);
/* Now translate the nodes, looking ahead one token to recognize */ /* search where the model name is and store in 'next_name' pointer */
/* when we reach the model name which should not be translated */ next_name = search_adevice_model_name(s);
/* here. */ if(next_name==NULL)
next_name=strchr(s,'\0'); /* not found, but process anyway */
next_name = MIFgettok(&s); /* Now translate the nodes */
for (;;) { while(s<next_name) {
/* rotate the tokens and get the the next one */ name = MIFgettok(&s);
if (name)
tfree(name);
name = next_name;
next_name = MIFgettok(&s);
/* if next token is NULL, name holds the model name, so exit */
if (next_name == NULL)
break;
/* Process the token in name. If it is special, then don't */ /* Process the token in name. If it is special, then don't */
/* translate it. */ /* translate it. */
@ -1073,8 +1069,7 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha
/* don't translate the port type identifier */ /* don't translate the port type identifier */
if (name) if (name)
tfree(name); tfree(name);
name = next_name; name = MIFgettok(&s);
next_name = MIFgettok(&s);
bxx_put_cstring(&buffer, name); bxx_put_cstring(&buffer, name);
break; break;
@ -1085,13 +1080,12 @@ translate(struct card *deck, char *formal, char *actual, char *scname, const cha
} }
bxx_putc(&buffer, ' '); bxx_putc(&buffer, ' ');
} if (name)
tfree(name);
};
/* copy in the last token, which is the model name */ /* copy the model name and the rest of the line */
if (name) { bxx_put_cstring(&buffer, s);
bxx_put_cstring(&buffer, name);
tfree(name);
}
break; /* case 'a' */ break; /* case 'a' */
@ -1614,6 +1608,32 @@ translate_mod_name(struct bxx_buffer *buffer, char *modname, char *subname, stru
bxx_printf(buffer, "%s:%s", subname, modname); bxx_printf(buffer, "%s:%s", subname, modname);
} }
#ifdef XSPICE
static inline char *skip_back_non_ws_nonc(const char *s, const char *start, char c) { while (s > start && !isspace_c(s[-1]) && (s[-1]!=c)) s--; return (char *) s; }
/* F.B: function to locate the model name in a A device (xspice coremodel) */
/* a similar function is found in inpcomp.c */
static char *search_adevice_model_name(char *line)
{
char *ptr_end, *ptr_beg;
char *prev;
for(ptr_end=strchr(line, '\0'); ptr_end>line; ) {
ptr_end = skip_back_ws(ptr_end, line);
ptr_beg = skip_back_non_ws_nonc(ptr_end, line, '=');
prev = skip_back_ws(ptr_beg, line);
if(prev>line && prev[-1]=='=') {
prev = skip_back_ws(prev-1, line); /* backskip \s*= */
ptr_end=skip_back_non_ws(prev, line); /* backskip param= */
} else
break; /* found model */
}
if(ptr_beg == line)
return NULL;
return ptr_beg;
}
#endif
static void static void
devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames) devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames)
@ -1658,42 +1678,24 @@ devmodtranslate(struct card *s, char *subname, wordlist * const orig_modnames)
/* SDB debug statement */ /* SDB debug statement */
printf("In devmodtranslate, found codemodel, line= %s\n", t); printf("In devmodtranslate, found codemodel, line= %s\n", t);
#endif #endif
next_name = search_adevice_model_name(t);
/* first do refdes. */ if(next_name && *next_name!='!') { /* if start with !, will use a default model */
name = gettok(&t); /* get refdes */ bxx_put_substring(&buffer, t, next_name); /* put everything before model name */
bxx_printf(&buffer, "%s ", name); t = next_name;
tfree(name); name = gettok(&t); /* get modname */
if(name==NULL) break; /* for safety but should not happen */
/* now do remainder of line. */ translate_mod_name(&buffer, name, subname, orig_modnames);
next_name = gettok(&t); tfree(name);
for (;;) { bxx_putc(&buffer, ' '); /* put a space after model name */
name = next_name; bxx_put_cstring(&buffer, t); /* put the end of the line */
next_name = gettok(&t); #ifdef TRACE
/* SDB debug statement */
if (next_name == NULL) { printf("In devmodtranslate, translated codemodel line= %s\n", buffer);
/* if next_name is NULL, we are at the line end. #endif
* name holds the model name. Therefore, break */ /* replace the line in the card */
break; tfree(s->line);
s->line = copy(bxx_buffer(&buffer));
} else { }
/* next_name holds something. Write name into the buffer and continue. */
bxx_printf(&buffer, "%s ", name);
tfree(name);
}
} /* while */
translate_mod_name(&buffer, name, subname, orig_modnames);
tfree(name);
bxx_putc(&buffer, ' ');
#ifdef TRACE
/* SDB debug statement */
printf("In devmodtranslate, translated codemodel line= %s\n", buffer);
#endif
bxx_put_cstring(&buffer, t);
tfree(s->line);
s->line = copy(bxx_buffer(&buffer));
break; break;
#endif /* XSPICE */ #endif /* XSPICE */

View File

@ -79,6 +79,7 @@ struct coreInfo_t {
/* added for instance parameters */ /* added for instance parameters */
int ((*dllitf_MIFParam)(int, IFvalue *, GENinstance*, IFvalue *)); int ((*dllitf_MIFParam)(int, IFvalue *, GENinstance*, IFvalue *));
void* nulltermination; /* For binary compatibility in future extensions */
}; };
#endif #endif

View File

@ -368,6 +368,7 @@ struct Mif_Private {
int num_inst_var; /* Number of instance variables */ int num_inst_var; /* Number of instance variables */
Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */ Mif_Inst_Var_Data_t **inst_var; /* Information about each inst variable */
Mif_Callback_t *callback; /* Callback function */ Mif_Callback_t *callback; /* Callback function */
/* new field for instance parameters - added to the end for binary compatibility */
Mif_Param_Data_t **iparam; /* Information about each inst parameter */ Mif_Param_Data_t **iparam; /* Information about each inst parameter */
}; };

View File

@ -115,9 +115,11 @@ struct Mif_Param_Info {
Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */ Mif_Boolean_t has_upper_bound; /* True if there is an array size upper bound */
int upper_bound; /* Array size upper bound */ int upper_bound; /* Array size upper bound */
Mif_Boolean_t null_allowed; /* True if null is allowed for this parameter */ Mif_Boolean_t null_allowed; /* True if null is allowed for this parameter */
#if 0
Mif_Boolean_t has_model_scope; /* True if the parameter is a model parameter */ Mif_Boolean_t has_model_scope; /* True if the parameter is a model parameter */
Mif_Boolean_t has_inst_scope; /* True if the parameter is an instance parameter */ Mif_Boolean_t has_inst_scope; /* True if the parameter is an instance parameter */
int inst_param_index; /* Index of instance parameter */ int inst_param_index; /* Index of instance parameter */
#endif
}; };

View File

@ -25,7 +25,7 @@ CKTparam(CKTcircuit *ckt, GENinstance *fast, int param, IFvalue *val, IFvalue *s
type = fast->GENmodPtr->GENmodType; type = fast->GENmodPtr->GENmodType;
if(DEVices[type]->DEVparam) { if(DEVices[type]->DEVparam) {
return(DEVices[type]->DEVparam (param, val, fast, selector)); return(DEVices[type]->DEVparam (param, val, fast, selector));
} else { } else {printf("no DEVparam function for type %d %s\n",type,fast->GENmodPtr->GENmodName);
return(E_BADPARM); return(E_BADPARM);
} }
} }

View File

@ -142,7 +142,7 @@ extern struct coreInfo_t coreInfo; /* cmexport.c */
#ifdef NDEV #ifdef NDEV
#include "ndev/ndevitf.h" #include "ndev/ndevitf.h"
#endif #endif
#define TRACE
static SPICEdev *(*static_devices[])(void) = { static SPICEdev *(*static_devices[])(void) = {
/* URC device MUST precede both resistors and capacitors */ /* URC device MUST precede both resistors and capacitors */
get_urc_info, get_urc_info,
@ -415,7 +415,7 @@ int load_opus(const char *name)
SPICEdev **devs; SPICEdev **devs;
Evt_Udn_Info_t **udns; Evt_Udn_Info_t **udns;
funptr_t fetch; funptr_t fetch;
printf("loading code model lib %s\n", name);
lib = dlopen(name, RTLD_NOW); lib = dlopen(name, RTLD_NOW);
if (!lib) { if (!lib) {
msg = dlerror(); msg = dlerror();

View File

@ -75,7 +75,7 @@ struct coreInfo_t coreInfo =
txfree, txfree,
tmalloc, tmalloc,
trealloc, trealloc,
txfree txfree,
#else #else
GC_malloc, GC_malloc,
tcalloc, tcalloc,
@ -83,6 +83,8 @@ struct coreInfo_t coreInfo =
no_free, no_free,
GC_malloc, GC_malloc,
GC_realloc, GC_realloc,
no_free no_free,
#endif #endif
MIFParam,
NULL
}; };

View File

@ -113,6 +113,18 @@ static int buf_len;
typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t; typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t;
static int inst_param_index(int param)
{
int i, iparam;
for (i = 0; (i < param) && (i < mod_ifs_table->num_param); i++)
if(mod_ifs_table->param[i].scope != CMPP_MODEL)
iparam++;
if(iparam>=mod_ifs_table->num_param)
yyerror ("Internal error: Instance parameter not found");
return iparam;
}
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
static char *subscript (Sub_Id_t sub_id) static char *subscript (Sub_Id_t sub_id)
{ {
@ -452,8 +464,8 @@ macro : TOK_INIT
fprintf (mod_yyout, "mif_private->param[%d]->element[%s]", fprintf (mod_yyout, "mif_private->param[%d]->element[%s]",
i, subscript ($3)); i, subscript ($3));
else else
fprintf (mod_yyout, "mif_private->iparam[mif_private->param[%d]->inst_param_index]->element[%s]", fprintf (mod_yyout, "mif_private->iparam[%d]->element[%s]",
i, subscript ($3)); inst_param_index(i), subscript ($3));
put_type (mod_yyout, mod_ifs_table->param[i].type); put_type (mod_yyout, mod_ifs_table->param[i].type);
} }
| TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN | TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN

View File

@ -892,6 +892,7 @@ static int write_param_info(
str = boolean_to_str(p_param_cur->null_allowed); str = boolean_to_str(p_param_cur->null_allowed);
rc |= fprintf(fp, " %s,\n", str); rc |= fprintf(fp, " %s,\n", str);
#if 0
/* F.B. info about instance parameters */ /* F.B. info about instance parameters */
str = boolean_to_str(p_param_cur->scope != CMPP_INSTANCE); str = boolean_to_str(p_param_cur->scope != CMPP_INSTANCE);
rc |= fprintf(fp, " %s,\n", str); rc |= fprintf(fp, " %s,\n", str);
@ -899,6 +900,7 @@ static int write_param_info(
rc |= fprintf(fp, " %s,\n", str); rc |= fprintf(fp, " %s,\n", str);
str = integer_to_str(p_param_cur->scope == CMPP_MODEL ? -1 : inst_param_index); str = integer_to_str(p_param_cur->scope == CMPP_MODEL ? -1 : inst_param_index);
rc |= fprintf(fp, " %s,\n", str); rc |= fprintf(fp, " %s,\n", str);
#endif
if(p_param_cur->scope != CMPP_MODEL) if(p_param_cur->scope != CMPP_MODEL)
inst_param_index++; inst_param_index++;
@ -1100,7 +1102,7 @@ static int write_SPICEdev(
/* Write the names of the generic code model functions */ /* Write the names of the generic code model functions */
rc |= fprintf(fp, rc |= fprintf(fp,
" .DEVparam = NULL,\n" " .DEVparam = MIFParam,\n"
" .DEVmodParam = MIFmParam,\n" " .DEVmodParam = MIFmParam,\n"
" .DEVload = MIFload,\n" " .DEVload = MIFload,\n"
" .DEVsetup = MIFsetup,\n" " .DEVsetup = MIFsetup,\n"

View File

@ -110,6 +110,8 @@ static void gc_end(void);
static char *alltokens[BSIZE_SP]; static char *alltokens[BSIZE_SP];
static int curtoknr = 0; static int curtoknr = 0;
static int MIFinp2_params(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, GENinstance* inst, int type);
/* ********************************************************************* */ /* ********************************************************************* */
@ -157,7 +159,8 @@ and error checks are performed.
At this point, nothing should be left in 'line' At this point, nothing should be left in 'line'
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
extern INPmodel *modtab;
#define TRACE
void void
MIF_INP2A ( MIF_INP2A (
CKTcircuit *ckt, /* circuit structure to put mod/inst structs in */ CKTcircuit *ckt, /* circuit structure to put mod/inst structs in */
@ -199,6 +202,7 @@ MIF_INP2A (
/* SDB debug statement */ /* SDB debug statement */
printf("In MIF_INP2A, line to process = %s . . . \n", current->line); printf("In MIF_INP2A, line to process = %s . . . \n", current->line);
#endif #endif
printf("->modtab %p\n", modtab);
/* get the line text from the card struct */ /* get the line text from the card struct */
line = current->line; line = current->line;
@ -210,11 +214,23 @@ MIF_INP2A (
name = copy(MIFgettok(&line)); name = copy(MIFgettok(&line));
INPinsert(&name, tab); INPinsert(&name, tab);
/* locate the last token on the line (i.e. model name) and put it into "model" */ printf("->modtab %p\n", modtab);
while(*line != '\0') {
model = MIFgettok(&line);
}
/* locate the last token on the line (i.e. model name) and put it into "model" */
/* locate the model name */
while(*line != '\0') {
char* linetmp;
tmp_token = MIFgettok(&line);
linetmp=line;
do
linetmp--;
while(linetmp > current->line && isspace_c(*linetmp));
if(*linetmp == '=')
break;
printf("model updated to %s, char %c, modtab %p\n", tmp_token, *linetmp,modtab);
model = tmp_token;
}
printf("->modtab %p\n", modtab);
/* make sure the model name was there. */ /* make sure the model name was there. */
if(model == NULL) { if(model == NULL) {
LITERR("Missing model on A type device"); LITERR("Missing model on A type device");
@ -222,6 +238,9 @@ MIF_INP2A (
return; return;
} }
/* if model name starts with !, use or create a default model */
/* TODO */
/* Locate model from pass 1. If it hasn't been processed yet, */ /* Locate model from pass 1. If it hasn't been processed yet, */
/* allocate a structure in ckt for it, process its parameters */ /* allocate a structure in ckt for it, process its parameters */
/* and return a pointer to its structure in 'thismodel' */ /* and return a pointer to its structure in 'thismodel' */
@ -230,7 +249,7 @@ MIF_INP2A (
gc_end(); gc_end();
return; return;
} }
printf("Device type %d\n", thismodel->INPmodType);
/* get the integer index into the DEVices data array for this */ /* get the integer index into the DEVices data array for this */
/* model */ /* model */
type = thismodel->INPmodType; type = thismodel->INPmodType;
@ -589,6 +608,10 @@ MIF_INP2A (
} }
} }
} }
/* parse the end of the line for reading instance parameters */
MIFinp2_params(line, ckt, tab, current, (GENinstance*) fast[0], type);
gc_end(); gc_end();
} }
@ -1028,6 +1051,48 @@ MIFget_port(
} }
static int
MIFinp2_params(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, GENinstance* inst, int type)
{
int error; /* error code temporary */
char *name;
int i;
IFvalue ptemp; /* a value structure */
IFvalue *parm;
while(*line)
{
INPgetTok(&line, &name, 0);
if(*line!='=') {
printf("Expect param=val format for %s, got %c\n", name, *line);
LITERR("Expect param=val format\n");
return(0);
}
line++; /* skip '=' */
for(i=0;i<*(DEVices[type]->DEVpublic.numInstanceParms);i++)
if(strcmp(name, DEVices[type]->DEVpublic.instanceParms[i].keyword)==0)
break;
if(0) tfree(name); /* don't it need anymore, we still know the keyword */
if(i<*(DEVices[type]->DEVpublic.numInstanceParms))
{
int dataType = DEVices[type]->DEVpublic.instanceParms[i].dataType;
if(0) printf("will set parameter %s to xspice instance\n", DEVices[type]->DEVpublic.instanceParms[i].keyword);
parm = INPgetValue(ckt, &line, dataType, tab);
printf("MIFinp2_params set %s id=%d i#%d\n", name, DEVices[type]->DEVpublic.instanceParms[i].id,i);
IFC(setInstanceParm, (ckt, (GENinstance*)inst, DEVices[type]->DEVpublic.instanceParms[i].id, parm, NULL));
/*GCA(INPapName, (ckt, job->JOBtype, job, ana->analysisParms[i].keyword, parm)); */
}
else
{
LITERR("Unrecognized parameter\n");
return(0);
}
}
}
#undef MIFgettok #undef MIFgettok
#undef MIFget_token #undef MIFget_token

View File

@ -291,7 +291,7 @@ int MIFaskInstParam(
value_type &= IF_VARTYPES; value_type &= IF_VARTYPES;
/* get index into inst->iparam */ /* get index into inst->iparam */
inst_index = DEVices[mod_type]->DEVpublic.param[param_index].inst_param_index; inst_index = i;
if(inst_index <0) if(inst_index <0)
return(E_BADPARM); return(E_BADPARM);

View File

@ -79,6 +79,7 @@ the .model card are not filled in by this function. They are
defaulted later by MIFsetup(). The function returns NULL when defaulted later by MIFsetup(). The function returns NULL when
successful, and an error string on failure. successful, and an error string on failure.
*/ */
#define TRACE
char *MIFgetMod( char *MIFgetMod(
CKTcircuit *ckt, /* The circuit structure */ CKTcircuit *ckt, /* The circuit structure */
@ -126,7 +127,6 @@ char *MIFgetMod(
/* loop through modtable looking for this model (*name) */ /* loop through modtable looking for this model (*name) */
for (modtmp = modtab; modtmp != NULL; modtmp = modtmp->INPnextModel) { for (modtmp = modtab; modtmp != NULL; modtmp = modtmp->INPnextModel) {
#ifdef TRACE #ifdef TRACE
/* SDB debug statement */ /* SDB debug statement */
printf("In MIFgetMod, checking model against stored model = %s . . .\n", modtmp->INPmodName); printf("In MIFgetMod, checking model against stored model = %s . . .\n", modtmp->INPmodName);

View File

@ -57,7 +57,7 @@ MIFParam(int param_index, IFvalue *value, GENinstance *inst_in, IFvalue *select)
/* Arrange for access to MIF specific data in the model */ /* Arrange for access to MIF specific data in the model */
inst = (MIFinstance*) inst_in; inst = (MIFinstance*) inst_in;
model = MIFmodPtr(inst); model = MIFmodPtr(inst);
printf("Mif param %d\n", param_index);
/* Get model type */ /* Get model type */
mod_type = model->MIFmodType; mod_type = model->MIFmodType;
if((mod_type < 0) || (mod_type >= DEVmaxnum)) if((mod_type < 0) || (mod_type >= DEVmaxnum))
@ -68,25 +68,14 @@ MIFParam(int param_index, IFvalue *value, GENinstance *inst_in, IFvalue *select)
if((param_index < 0) || (param_index >= model->num_param)) if((param_index < 0) || (param_index >= model->num_param))
return(E_BADPARM); return(E_BADPARM);
if(!DEVices[mod_type]->DEVpublic.param[param_index].has_inst_scope) /* search the instance parameter index */
return(E_BADPARM); for(iparam=0;iparam<*(DEVices[mod_type]->DEVpublic.numInstanceParms);iparam++)
if(DEVices[mod_type]->DEVpublic.instanceParms[iparam].id == param_index)
break;
iparam = DEVices[mod_type]->DEVpublic.param[param_index].inst_param_index; if((iparam < 0) || (iparam >= *(DEVices[mod_type]->DEVpublic.numInstanceParms)))
if((iparam < 0) || (iparam >= inst->num_iparam))
return(E_BADPARM); return(E_BADPARM);
/* find param_index */
/*
param_index=-1;
for(i=0;i<DEVices[mod_type]->DEVpublic.num_param;i++)
if(DEVices[mod_type]->DEVpublic.param[i].inst_param_index == iparam)
{
param_index=i;
break;
}
if(param_index<0)
return(E_BADPARM); */
/* get value type to know which members of unions to access */ /* get value type to know which members of unions to access */
value_type = DEVices[mod_type]->DEVpublic.modelParms[param_index].dataType; value_type = DEVices[mod_type]->DEVpublic.modelParms[param_index].dataType;
value_type &= IF_VARTYPES; value_type &= IF_VARTYPES;

View File

@ -140,9 +140,13 @@ MIFsetup(
/* For each parameter not given explicitly on the .model */ /* For each parameter not given explicitly on the .model */
/* card, default it */ /* card, default it */
for(i = 0; i < model->num_param; i++) { for(int imp=0; imp<*(DEVices[mod_type]->DEVpublic.numModelParms);imp++)
{
i = DEVices[mod_type]->DEVpublic.modelParms[imp].id;
if(i<0 || i>= model->num_param)
continue;
if(model->param[i]->is_null && DEVices[mod_type]->DEVpublic.param[i].has_model_scope) { if(model->param[i]->is_null) {
/* setup a pointer for quick access */ /* setup a pointer for quick access */
param_info = &(DEVices[mod_type]->DEVpublic.param[i]); param_info = &(DEVices[mod_type]->DEVpublic.param[i]);
@ -201,7 +205,87 @@ MIFsetup(
} /* end for number of parameters */ } /* end for number of parameters */
/* For each instance, initialize stuff used by cm_... functions */ /* For each instance, set default value for instance parameter */
/* if parameter is both for instance and model, copy model value */
for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) {
for(int ip=0; ip<*(DEVices[mod_type]->DEVpublic.numInstanceParms);ip++)
{
i = DEVices[mod_type]->DEVpublic.instanceParms[ip].id;
if(i<0 || i>= model->num_param)
break; /* not an instance parameter from ifspec.ifs */
if(here->iparam[ip]->is_null) {
int alsomodidx;
/* setup a pointer for quick access */
param_info = &(DEVices[mod_type]->DEVpublic.param[i]);
/* look if it is also a model parameter */
for(alsomodidx=0; alsomodidx<*(DEVices[mod_type]->DEVpublic.numModelParms);alsomodidx++)
if(DEVices[mod_type]->DEVpublic.modelParms[alsomodidx].id == i)
break;
if(alsomodidx<*(DEVices[mod_type]->DEVpublic.numModelParms))
{
/* copy from model */
size = model->param[i]->size;
here->iparam[ip]->is_null = 0;
here->iparam[ip]->size = size;
here->iparam[ip]->element = TMALLOC(Mif_Value_t, size);
for(j = 0; j < size; j++)
here->iparam[ip]->element[j] = model->param[i]->element[j];
}
else
{
/* copy default value from ifspec.ifs */
/* determine the size and allocate the parameter element(s) */
if(! param_info->is_array) {
here->iparam[ip]->size = 1;
here->iparam[ip]->element = TMALLOC(Mif_Value_t, 1);
} else { /* parameter is an array */
/* MIF_INP2A() parser assures that there is an associated array connection */
size = here->conn[param_info->conn_ref]->size;
here->iparam[ip]->size = size;
here->iparam[ip]->element = TMALLOC(Mif_Value_t, size);
} /* end if parameter is an array */
/* set the parameter element(s) to default value */
for(j = 0; j < here->iparam[ip]->size; j++) {
switch(param_info->type) {
case MIF_BOOLEAN:
here->iparam[ip]->element[j].bvalue = param_info->default_value.bvalue;
break;
case MIF_INTEGER:
here->iparam[ip]->element[j].ivalue = param_info->default_value.ivalue;
break;
case MIF_REAL:
here->iparam[ip]->element[j].rvalue = param_info->default_value.rvalue;
break;
case MIF_COMPLEX:
here->iparam[ip]->element[j].cvalue = param_info->default_value.cvalue;
break;
case MIF_STRING:
here->iparam[ip]->element[j].svalue = param_info->default_value.svalue;
break;
default:
return(E_BADPARM);
}
} /* end for number of elements in param array */
} /* end copy from default */
} /* end param is null */
} /* end for ip instance parameter */
} /* end for instance here */
/* For each instance, initialize stuff used by cm_... functions */
for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) { for(here = MIFinstances(model); here != NULL; here = MIFnextInstance(here)) {

View File

@ -84,4 +84,5 @@ struct coreInfo_t coreInfo =
no_free, no_free,
#endif #endif
MIFParam, MIFParam,
NULL
}; };