You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
12 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
**********/
/* Do a run of the circuit, of the given type. Type "resume" is special --
* it means to resume whatever simulation that was in progress. The
* return value of this routine is 0 if the exit was ok, and 1 if there was
* a reason to interrupt the circuit (interrupt typed at the keyboard,
* error in the simulation, etc). args should be the entire command line,
* e.g. "tran 1 10 20 uic"
*/
#include "ngspice.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "fteinp.h"
#include "sim.h"
#include "devdefs.h"
#include "inpdefs.h"
#include "iferrmsg.h"
#include "ifsim.h"
#include "circuits.h"
#include "shyu.h"
int
if_sens_run(CKTcircuit *t, wordlist *args, INPtables *tab)
{
CKTcircuit *ckt = /* fixme, drop that */ t;
JOB *senseJob;
JOB *acJob;
JOB *opJob;
JOB *dcJob;
JOB *tranJob;
card *current;
IFvalue ptemp;
IFvalue *parm;
char buf[BSIZE_SP];
int err;
char *token;
char *steptype;
char *name;
char *line;
struct line deck;
int i;
int j;
int error;
int save ;
int flag = 0;
int which = -1;
(void) sprintf(buf, ".%s", wl_flatten(args));
deck.li_next = deck.li_actual = NULL;
deck.li_error = NULL;
deck.li_linenum = 0;
deck.li_line = buf;
current = (card *) &deck;
line = current->line;
INPgetTok(&line,&token,1);
if(ft_curckt->ci_specTask) {
err = ft_sim->deleteTask (ft_curckt->ci_ckt,
ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"deleteTask");
return(0); /* temporary */
}
}
err = ft_sim->newTask (ft_curckt->ci_ckt,
&(ft_curckt->ci_specTask), "special",
&(ft_curckt->ci_defTask));
if(err) {
ft_sperror(err,"newTask");
return(0); /* temporary */
}
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"options")==0) {
which = j;
break;
}
}
if(which != -1) {
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "options",
&(ft_curckt->ci_specOpt), ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createOptions");
return(0);/* temporary */
}
ft_curckt->ci_curOpt = ft_curckt->ci_specOpt;
}
else {
/* in DEEP trouble */
;
}
ft_curckt->ci_curTask = ft_curckt->ci_specTask;
which = -1;
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"SEN")==0) {
which = j;
break;
}
}
if(which != -1) {
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "sense",
&(senseJob),ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createSense");
return(0);/* temporary */
}
}
else{
current->error = INPerrCat(current->error,INPmkTemp(
"sensetivity analysis unsupported\n"));
return(0);
}
save = which;
INPgetTok(&line,&token,1);
if(strcmp(token ,"ac")==0){
which = -1;
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"AC")==0) {
which = j;
break;
}
}
if(which != -1) {
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "acan",
&(acJob),ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createAC"); /* or similar error message */
return(0);
}
}
else{
current->error = INPerrCat(current->error,INPmkTemp(
"ac analysis unsupported\n"));
}
INPgetTok(&line,&steptype,1); /* get DEC, OCT, or LIN */
ptemp.iValue=1;
error = INPapName(ckt,which,acJob,steptype,&ptemp);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
parm=INPgetValue(ckt,&line,IF_INTEGER,tab);/* number of points*/
error = INPapName(ckt,which,acJob,"numsteps",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* fstart */
error = INPapName(ckt,which,acJob,"start",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* fstop */
error = INPapName(ckt,which,acJob,"stop",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
}
if(strcmp(token ,"op")==0){
which = -1;
for(i=0;i<ft_sim->numAnalyses;i++) {
if(strcmp(ft_sim->analyses[i]->name,"DCOP")==0) {
which=i;
break;
}
}
if(which == -1) {
current->error = INPerrCat(current->error,INPmkTemp(
"DC operating point analysis unsupported\n"));
}
else {
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "dcop",
&(opJob),ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createOP"); /* or similar error message */
return(0);
}
}
}
if(strcmp(token ,"dc")==0){
/* .dc SRC1NAME Vstart1 Vstop1 Vinc1 [SRC2NAME Vstart2 */
/* Vstop2 Vinc2 */
which = -1;
for(i=0;i<ft_sim->numAnalyses;i++) {
if(strcmp(ft_sim->analyses[i]->name,"DCTransfer")==0) {
which=i;
break;
}
}
if(which==-1) {
current->error = INPerrCat(current->error,INPmkTemp(
"DC transfer curve analysis unsupported\n"));
}
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "DCtransfer",
&(dcJob),ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createOP"); /* or similar error message */
return(0);
}
INPgetTok(&line,&name,1);
INPinsert(&name,tab);
ptemp.uValue=name;
error = INPapName(ckt,which,dcJob,"name1",&ptemp);
if(error) current->error = INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vstart1 */
error = INPapName(ckt,which,dcJob,"start1",parm);
if(error) current->error = INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vstop1 */
error = INPapName(ckt,which,dcJob,"stop1",parm);
if(error) current->error = INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vinc1 */
error = INPapName(ckt,which,dcJob,"step1",parm);
if(error) current->error = INPerrCat(current->error,INPerror(error));
if(*line) {
if(*line == 'd') goto next;
INPgetTok(&line,&name,1);
INPinsert(&name,tab);
ptemp.uValue=name;
error = INPapName(ckt,which,dcJob,"name2",&ptemp);
if(error) current->error= INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vstart1 */
error = INPapName(ckt,which,dcJob,"start2",parm);
if(error) current->error= INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vstop1 */
error = INPapName(ckt,which,dcJob,"stop2",parm);
if(error) current->error= INPerrCat(current->error,INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* vinc1 */
error = INPapName(ckt,which,dcJob,"step2",parm);
if(error) current->error= INPerrCat(current->error,INPerror(error));
}
}
if(strcmp(token ,"tran")==0){
which = -1;
for(j=0;j<ft_sim->numAnalyses;j++) {
if(strcmp(ft_sim->analyses[j]->name,"TRAN")==0) {
which = j;
break;
}
}
if(which != -1) {
err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "tranan",
&(tranJob),ft_curckt->ci_specTask);
if(err) {
ft_sperror(err,"createTRAN");
return(0);
}
}
else{
current->error = INPerrCat(current->error,INPmkTemp(
"transient analysis unsupported\n"));
}
parm=INPgetValue(ckt,&line,IF_REAL,tab);/* Tstep */
error = INPapName(ckt,which,tranJob,"tstep",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
parm = INPgetValue(ckt,&line,IF_REAL,tab); /* Tstop*/
error = INPapName(ckt,which,tranJob,"tstop",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
if(*line){
if(*line == 'd') goto next;
if(*line == 'u') goto uic;
parm=INPgetValue(ckt,&line,IF_REAL,tab);/* Tstart */
error = INPapName(ckt,which,tranJob,"tstart",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
if(*line == 'u') goto uic;
parm=INPgetValue(ckt,&line,IF_REAL,tab);/* Tmax */
error = INPapName(ckt,which,tranJob,"tmax",parm);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
uic:
if(*line == 'u') {
INPgetTok(&line,&name,1);
if(strcmp(name,"uic")==0) {
ptemp.iValue = 1;
error = INPapName(ckt,which,tranJob,"tstart",&ptemp);
if(error) current->error = INPerrCat(current->error,
INPerror(error));
}
}
}
}
next:
while(*line) { /* read the entire line */
if(flag){
INPgetTok(&line,&token,1);
}
else{
flag = 1;
}
for(i=0;i<ft_sim->analyses[save]->numParms;i++) {
/* find the parameter */
if(0==strcmp(token ,
ft_sim->analyses[save]->analysisParms[i].
keyword) ){
/* found it, analysis which, parameter i */
if(ft_sim->analyses[save]->analysisParms[i].
dataType & IF_FLAG) {
/* one of the keywords! */
ptemp.iValue = 1;
error = ft_sim->setAnalysisParm (ckt,
senseJob, ft_sim->analyses[save]->
analysisParms[i].id, &ptemp, NULL);
if(error) current->error = INPerrCat(
current->error, INPerror(error));
}
else {
parm = INPgetValue(ckt,&line,ft_sim->
analyses[save]->analysisParms[i].
dataType,tab);
error = ft_sim->setAnalysisParm (ckt,
senseJob, ft_sim->analyses[save]->
analysisParms[i].id, parm, NULL);
if(error) current->error = INPerrCat(
current->error, INPerror(error));
}
break;
}
}
if(i==ft_sim->analyses[save]->numParms) {
/* didn't find it! */
current->error = INPerrCat(current->error,INPmkTemp(
" Error: unknown parameter on .sens - ignored \n"));
}
}
if((err = ft_sim->doAnalyses (ckt, 1, ft_curckt->ci_curTask)) != OK) {
ft_sperror(err, "doAnalyses");
return(0);/* temporary */
}
return(0);
}