📄 spiceif.c
字号:
return (NULL); } device = ft_sim->devices[typecode]; opt = parmlookup(device, &dev, param, do_model, 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));}voidif_setparam(ckt, name, param, val, do_model) char *ckt; char **name; char *param; struct dvec *val; int do_model;{ IFparm *opt; IFdevice *device; GENmodel *mod=(GENmodel *)NULL; GENinstance *dev=(GENinstance *)NULL; int typecode; INPretrieve(name,(INPtables *)ft_curckt->ci_symtab); typecode = finddev(ckt, *name, (GENERIC**)&dev, (GENERIC**)&mod); if (typecode == -1) { fprintf(cp_err, "Error: no such device or model name %s\n", *name); return; } device = ft_sim->devices[typecode]; opt = parmlookup(device, &dev, param, do_model, 1); if (!opt) { if (param) fprintf(cp_err, "Error: no such parameter %s.\n", param); else fprintf(cp_err, "Error: no default parameter.\n"); return; } if (do_model && !mod) { mod = dev->GENmodPtr; dev = (GENinstance *)NULL; } doset(ckt, typecode, dev, mod, opt, val);}static struct variable *parmtovar(pv, opt) IFvalue *pv; IFparm *opt;{ struct variable *vv = alloc(struct variable); struct variable *nv; int i = 0; switch (opt->dataType & IF_VARTYPES) { case IF_INTEGER: vv->va_type = VT_NUM; vv->va_num = pv->iValue; break; case IF_REAL: case IF_COMPLEX: vv->va_type = VT_REAL; vv->va_real = pv->rValue; break; case IF_STRING: vv->va_type = VT_STRING; vv->va_string = pv->sValue; break; case IF_FLAG: vv->va_type = VT_BOOL; vv->va_bool = pv->iValue ? true : false; break; case IF_REALVEC: vv->va_type = VT_LIST; 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; default: fprintf(cp_err, "parmtovar: Internal Error: bad PARM type %d.\n", opt->dataType); return (NULL); } /* It's not clear whether we want the keyword or the desc here... */ vv->va_name = copy(opt->description); vv->va_next = NULL; return (vv);}/* Extract the IFparm structure from the device. If isdev is true, then get * the DEVmodQuest, otherwise get the DEVquest. */static IFparm *parmlookup(dev, inptr, param, do_model, inout) IFdevice *dev; GENinstance **inptr; char *param; int do_model; int inout;{ int i; /* fprintf(cp_err, "Called: parmlookup(%x, %c, %s)\n", dev, isdev, param); */ /* First try the device questions... */ if (!do_model && dev->numInstanceParms) { for (i = 0; i < *(dev->numInstanceParms); i++) { if (!param && (dev->instanceParms[i].dataType & IF_PRINCIPAL)) return (&dev->instanceParms[i]); else if (!param) continue; else if ((((dev->instanceParms[i].dataType & IF_SET) && inout == 1) || ((dev->instanceParms[i].dataType & IF_ASK) && inout == 0)) && eq(dev->instanceParms[i].keyword, param)) { if (dev->instanceParms[i].dataType & IF_REDUNDANT) i -= 1; return (&dev->instanceParms[i]); } } return NULL; } if (dev->numModelParms) { for (i = 0; i < *(dev->numModelParms); i++) if ((((dev->modelParms[i].dataType & IF_SET) && inout == 1) || ((dev->modelParms[i].dataType & IF_ASK) && inout == 0)) && eq(dev->modelParms[i].keyword, param)) { if (dev->modelParms[i].dataType & IF_REDUNDANT) i -= 1; return (&dev->modelParms[i]); } } return (NULL);}/* Perform the CKTask call. We have both 'fast' and 'modfast', so the other * parameters aren't necessary. *//* ARGSUSED */static IFvalue *doask(ckt, typecode, dev, mod, opt, ind) char *ckt; GENinstance *dev; GENmodel *mod; IFparm *opt; int ind;{ static IFvalue pv; int err; pv.iValue = ind; /* Sometimes this will be junk and ignored... */ /* fprintf(cp_err, "Calling doask(%d, %x, %x, %x)\n", typecode, dev, mod, opt); */ if (dev) err = (*(ft_sim->askInstanceQuest))((GENERIC *)ckt, (GENERIC *)dev, opt->id, &pv, (IFvalue *)NULL); else err = (*(ft_sim->askModelQuest))((GENERIC*)ckt, (GENERIC*) mod, opt->id, &pv, (IFvalue *)NULL); if (err != OK) { ft_sperror(err, "if_getparam"); return (NULL); } return (&pv);}/* Perform the CKTset call. We have both 'fast' and 'modfast', so the other * parameters aren't necessary. *//* ARGSUSED */static intdoset(ckt, typecode, dev, mod, opt, val) char *ckt; GENinstance *dev; GENmodel *mod; IFparm *opt; struct dvec *val;{ IFvalue nval; int err; int n; int *iptr; double *dptr; int i; /* Count items */ if (opt->dataType & IF_VECTOR) { n = nval.v.numValue = val->v_length; dptr = val->v_realdata; /* XXXX compdata!!! */ switch (opt->dataType & (IF_VARTYPES & ~IF_VECTOR)) { case IF_FLAG: case IF_INTEGER: iptr = nval.v.vec.iVec = NEWN(int, n); for (i = 0; i < n; i++) *iptr++ = *dptr++; break; case IF_REAL: nval.v.vec.rVec = val->v_realdata; break; default: fprintf(cp_err, "Can't assign value to \"%s\" (unsupported vector type)\n", opt->keyword); return E_UNSUPP; } } else { switch (opt->dataType & IF_VARTYPES) { case IF_FLAG: case IF_INTEGER: nval.iValue = *val->v_realdata; break; case IF_REAL: nval.rValue = *val->v_realdata; break; default: fprintf(cp_err, "Can't assign value to \"%s\" (unsupported type)\n", opt->keyword); return E_UNSUPP; } } /* fprintf(cp_err, "Calling doask(%d, %x, %x, %x)\n", typecode, dev, mod, opt); */ if (dev) err = (*(ft_sim->setInstanceParm))((GENERIC *)ckt, (GENERIC *)dev, opt->id, &nval, (IFvalue *)NULL); else err = (*(ft_sim->setModelParm))((GENERIC*)ckt, (GENERIC*) mod, opt->id, &nval, (IFvalue *)NULL); return err;}/* 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. */static intfinddev(ck, name, devptr, modptr) char *ck; char *name; GENERIC **devptr; GENERIC **modptr;{ int err; int type = -1; err = (*(ft_sim->findInstance))((GENERIC *)ck,&type,devptr,name,NULL,NULL); if(err == OK) return(type); type = -1; *devptr = (GENERIC *)NULL; err = (*(ft_sim->findModel))((GENERIC *)ck,&type,modptr,name); if(err == OK) return(type); *modptr = (GENERIC *)NULL; return(-1);}#ifdef notdef/* XXX Not useful *//* Extract the node and device names from the line and add them to the command * completion structure. This is probably not a good thing to do if it * takes too much time. */ /* BLOW THIS AWAY */voidif_setndnames(line) char *line;{ char *t; int i; while (isspace(*line)) line++; if (!*line || (*line == '*') || (*line == '.')) return; t = gettok(&line); if (!(i = inp_numnodes(*t))) return; if ((*t == 'q') || (*t == 'Q')) i = 3; cp_addkword(CT_DEVNAMES, t); while (i-- > 0) { t = gettok(&line); if (t) cp_addkword(CT_NODENAMES, t); } return;}#endif/* get an analysis parameter by name instead of id */int if_analQbyName(ckt,which,anal,name,parm) GENERIC *ckt; int which; GENERIC *anal; char *name; IFvalue *parm;{ int i; for(i=0;i<ft_sim->analyses[which]->numParms;i++) { if(strcmp(ft_sim->analyses[which]->analysisParms[i].keyword,name)==0) { return( (*(ft_sim->askAnalysisQuest))(ckt,anal, ft_sim->analyses[which]->analysisParms[i].id,parm, (IFvalue *)NULL) ); } } return(E_BADPARM);}/* Get the parameters tstart, tstop, and tstep from the CKT struct. *//* BLOW THIS AWAY TOO */boolif_tranparams(ci, start, stop, step) struct circ *ci; double *start, *stop, *step;{ IFvalue tmp; int err; int which = -1; int i; GENERIC *anal; IFuid tranUid; if(!ci->ci_curTask) return(false); for(i=0;i<ft_sim->numAnalyses;i++) { if(strcmp(ft_sim->analyses[i]->name,"TRAN")==0){ which = i; break; } } if(which == -1) return(false); err = IFnewUid(ci->ci_ckt,&tranUid,(IFuid)NULL,"Transient Analysis", UID_ANALYSIS, (GENERIC**)NULL); if(err != OK) return(false); err =(*(ft_sim->findAnalysis))(ci->ci_ckt,&which, &anal,tranUid, ci->ci_curTask,(IFuid *)NULL); if(err != OK) return(false); err = if_analQbyName(ci->ci_ckt,which,anal,"tstart",&tmp); if(err != OK) return(false); *start = tmp.rValue; err = if_analQbyName(ci->ci_ckt,which,anal,"tstop",&tmp); if(err != OK) return(false); *stop = tmp.rValue; err = if_analQbyName(ci->ci_ckt,which,anal,"tstep",&tmp); if(err != OK) return(false); *step = tmp.rValue; return (true);}/* Get the statistic called 'name'. If this is NULL get all statistics * available. */struct variable *if_getstat(ckt, name) char *ckt; char *name;{ int i; struct variable *v, *vars; IFvalue parm; int which = -1; for(i=0;i<ft_sim->numAnalyses;i++) { if(strcmp(ft_sim->analyses[i]->name,"options")==0) { which = i; break; } } if(which==-1) { fprintf(cp_err,"Warning: statistics unsupported\n"); return(NULL); } if (name) { for (i = 0; i < ft_sim->analyses[which]->numParms; i++) if (eq(ft_sim->analyses[which]->analysisParms[i].keyword, name)) break; if (i == ft_sim->analyses[which]->numParms) return (NULL); if ((*(ft_sim->askAnalysisQuest))(ckt, ft_curckt->ci_curTask, ft_sim->analyses[which]->analysisParms[i].id, &parm, (IFvalue *)NULL) == -1) { fprintf(cp_err, "if_getstat: Internal Error: can't get %s\n", name); return (NULL); } return (parmtovar(&parm, &(ft_sim->analyses[which]->analysisParms[i]))); } else { for (i = 0, vars = v = NULL; i<ft_sim->analyses[which]->numParms; i++) { if(!(ft_sim->analyses[which]->analysisParms[i].dataType&IF_ASK)) { continue; } if ((*(ft_sim->askAnalysisQuest))(ckt, ft_curckt->ci_curTask, ft_sim->analyses[which]->analysisParms[i].id, &parm, (IFvalue *)NULL) == -1) { fprintf(cp_err, "if_getstat: Internal Error: can't get %s\n", name); return (NULL); } if (v) { v->va_next = parmtovar(&parm, &(ft_sim->analyses[which]->analysisParms[i])); v = v->va_next; } else { vars = v = parmtovar(&parm, &(ft_sim->analyses[which]->analysisParms[i])); } } return (vars); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -