correct alter of mos geometries for binned models

This commit is contained in:
dwarning 2012-08-05 12:11:16 +02:00
parent 96dd397251
commit 99b167b272
2 changed files with 57 additions and 7 deletions

View File

@ -27,6 +27,7 @@ static wordlist *devexpand(char *name);
static void all_show(wordlist *wl, int mode);
static void all_show_old(wordlist *wl, int mode);
static void com_alter_mod(wordlist *wl);
static void if_set_binned_model(CKTcircuit *, char *, char *, struct dvec *);
/*
* devhelp: lists available devices and information on parameters
@ -1079,6 +1080,40 @@ com_altermod(wordlist *wl)
com_alter_common(wl, 1);
}
static void
if_set_binned_model(CKTcircuit *ckt, char *devname, char *param, struct dvec *val)
{
char *width_length;
double w=0.0, l=0.0;
struct variable *v;
v = if_getparam(ckt, &devname, "w", 0, 0);
if (!v) {
fprintf(cp_err, "Error: Can't access width instance parameter.\n");
return;
}
w = v->va_V.vV_real;
v = if_getparam(ckt, &devname, "l", 0, 0);
if (!v) {
fprintf(cp_err, "Error: Can't access length instance parameter.\n");
return;
}
l = v->va_V.vV_real;
if (param[0] == 'w') {
w = *val->v_realdata; /* overwrite the width with the alter param */
} else {
l = *val->v_realdata; /* overwrite the length with the alter param */
}
width_length = TMALLOC(char, 36);
(void) sprintf(width_length,"w=%15.7e l=%15.7e", w, l);
if_setparam_model(ft_curckt->ci_ckt, &devname, width_length);
FREE(width_length);
}
static void
com_alter_common(wordlist *wl, int do_model)
{
@ -1328,6 +1363,12 @@ com_alter_common(wordlist *wl, int do_model)
return;
}
/* If we want alter the geometry of a MOS device
we have to ensure that we are in the valid model bin. */
if ( (dev[0] == 'm') && ((param[0] == 'w') || (param[0] == 'l')) ) {
if_set_binned_model(ft_curckt->ci_ckt, dev, param, dv);
}
if_setparam(ft_curckt->ci_ckt, &dev, param, dv, do_model);
/* va: garbage collection for dv, if pnode names is no simple value */

View File

@ -160,7 +160,9 @@ if_inpdeck(struct line *deck, INPtables **tab)
INPpas1( ckt, (card *) deck->li_next, *tab);
INPpas2( ckt, (card *) deck->li_next, *tab, ft_curckt->ci_defTask);
INPkillMods();
/* INPkillMods(); FIXME: modtab should removed later -
because needed for alter geometry of binned MOS models,
see below if_setparam_model */
/* INPpas2 has been modified to ignore .NODESET and .IC
* cards. These are left till INPpas3 so that we can check for
@ -820,7 +822,7 @@ spif_getparam(CKTcircuit *ckt, char **name, char *param, int ind, int do_model)
/* 9/26/03 PJB : function to allow setting model of device */
void
if_setparam_model(CKTcircuit *ckt, char **name, char *val )
if_setparam_model(CKTcircuit *ckt, char **name, char *val)
{
GENinstance *dev = NULL;
GENinstance *prevDev = NULL;
@ -830,21 +832,29 @@ if_setparam_model(CKTcircuit *ckt, char **name, char *val )
GENinstance *iter;
GENmodel *mods, *prevMod;
int typecode;
char *modname;
/* retrieve device name from symbol table */
INPretrieve(name, ft_curckt->ci_symtab);
/* find the specified device */
typecode = finddev(ckt, *name, &dev, &curMod);
if (typecode == -1) {
fprintf(cp_err, "Error: no such device or model name %s\n", *name);
fprintf(cp_err, "Error: no such device name %s\n", *name);
return;
}
curMod = dev->GENmodPtr;
modname = copy(dev->GENmodPtr->GENmodName);
modname = strtok(modname, "."); /* want only have the parent model name */
/*
retrieve the model from the global model table; also add the model to 'ckt'
and indicate model is being used
*/
INPgetMod( ckt, val, &inpmod, ft_curckt->ci_symtab );
INPgetMod( ckt, modname, &inpmod, ft_curckt->ci_symtab );
/* check if using model binning -- pass in line since need 'l' and 'w' */
if ( inpmod == NULL ) {
INPgetModBin( ckt, modname, &inpmod, ft_curckt->ci_symtab, val );
}
tfree(modname);
if ( inpmod == NULL ) {
fprintf(cp_err, "Error: no such model %s.\n", val);
return;
@ -852,9 +862,8 @@ if_setparam_model(CKTcircuit *ckt, char **name, char *val )
newMod = inpmod->INPmodfast;
/* see if new model name same as current model name */
if ( newMod->GENmodName == curMod->GENmodName ) {
fprintf(cp_err, "Warning: new model same as current model; nothing changed.\n");
return;
if ( newMod->GENmodName != curMod->GENmodName ) {
printf("Notice: model has changed from %s to %s.\n", curMod->GENmodName, newMod->GENmodName);
}
if ( newMod->GENmodType != curMod->GENmodType ) {
fprintf(cp_err, "Error: new model %s must be same type as current model.\n", val);