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.
 
 
 
 
 
 

236 lines
4.7 KiB

/**********
Copyright 1991 Regents of the University of California. All rights reserved.
**********/
#include "ngspice/ngspice.h"
#include "ngspice/gendefs.h"
#include "ngspice/devdefs.h"
#include "ngspice/cktdefs.h"
#include "ngspice/ifsim.h"
#include "ngspice/sensgen.h"
static int set_model(sgen *);
static int set_param(sgen *);
static int set_inst(sgen *);
static int set_dev(sgen *);
sgen *
sgen_init(CKTcircuit *ckt, int is_dc)
{
sgen *sg;
sg = TMALLOC(sgen, 1);
sg->param = 99999;
sg->is_instparam = 0;
sg->dev = -1;
sg->istate = 0;
sg->ckt = ckt;
sg->devlist = ckt->CKThead;
sg->instance = sg->first_instance = sg->next_instance = NULL;
sg->model = sg->next_model = NULL;
sg->ptable = NULL;
sg->is_dc = is_dc;
sg->is_principle = 0;
sg->value = 0.0;
sgen_next(&sg); /* get the ball rolling XXX check return val? */
return sg;
}
int
sgen_next(sgen **xsg)
{
sgen *sg = *xsg;
int good, done;
int i;
done = 0;
i = sg->dev;
do {
if (sg->instance) {
if (sg->ptable) {
do {
sg->param += 1;
} while (sg->param < sg->max_param
&& !set_param(sg));
} else {
sg->max_param = -1;
}
if (sg->param < sg->max_param) {
done = 1;
} else if (!sg->is_instparam) {
/* Try instance parameters now */
sg->is_instparam = 1;
sg->param = -1;
sg->max_param =
*DEVices[i]->DEVpublic.numInstanceParms;
sg->ptable =
DEVices[i]->DEVpublic.instanceParms;
} else {
sg->is_principle = 0;
sg->instance->GENnextInstance =
sg->next_instance;
sg->instance->GENstate = sg->istate;
sg->instance = NULL;
}
} else if (sg->model) {
/* Find the first/next good instance for this model */
for (good = 0; !good && sg->next_instance;
good = set_inst(sg))
{
sg->instance = sg->next_instance;
sg->next_instance =
sg->instance->GENnextInstance;
}
if (good) {
sg->is_principle = 0;
sg->istate = sg->instance->GENstate;
sg->instance->GENnextInstance = NULL;
sg->model->GENinstances = sg->instance;
if (DEVices[i]->DEVpublic.modelParms) {
sg->max_param =
*DEVices[i]->DEVpublic.
numModelParms;
sg->ptable =
DEVices[i]->DEVpublic.
modelParms;
} else {
sg->ptable = NULL;
}
sg->param = -1;
sg->is_instparam = 0;
} else {
/* No good instances of this model */
sg->model->GENinstances = sg->first_instance;
sg->model->GENnextModel = sg->next_model;
sg->model = NULL;
}
} else if (i >= 0) {
/* Find the first/next good model for this device */
for (good = 0; !good && sg->next_model;
good = set_model(sg))
{
sg->model = sg->next_model;
sg->next_model = sg->model->GENnextModel;
}
if (good) {
sg->model->GENnextModel = NULL;
sg->devlist[i] = sg->model;
if (DEVices[i]->DEVpublic.modelParms) {
sg->max_param =
*DEVices[i]->DEVpublic.
numModelParms;
sg->ptable =
DEVices[i]->DEVpublic.
modelParms;
} else {
sg->ptable = NULL;
}
sg->next_instance = sg->first_instance
= sg->model->GENinstances;
} else {
/* No more good models for this device */
sg->devlist[i] = sg->first_model;
i = -1; /* Try the next good device */
}
} else if (i < DEVmaxnum && sg->dev < DEVmaxnum) {
/* Find the next good device in this circuit */
do
sg->dev++;
while (sg->dev < DEVmaxnum && sg->devlist[sg->dev]
&& !set_dev(sg));
i = sg->dev;
if (i >= DEVmaxnum) /* PN: Segafult if not = */
done = 1;
sg->first_model = sg->next_model = (i<DEVmaxnum) ? sg->devlist[i] : NULL;
} else {
done = 1;
}
} while (!done);
if (sg->dev >= DEVmaxnum) {
FREE(sg);
*xsg = NULL;
}
return 1;
}
static int set_inst(sgen *sg)
{
NG_IGNORE(sg);
return 1;
}
static int set_model(sgen *sg)
{
NG_IGNORE(sg);
return 1;
}
static int set_dev(sgen *sg)
{
NG_IGNORE(sg);
return 1;
}
static int set_param(sgen *sg)
{
IFvalue ifval;
if (!sg->ptable[sg->param].keyword)
return 0;
if ((sg->ptable[sg->param].dataType &
(IF_SET|IF_ASK|IF_REAL|IF_VECTOR|IF_REDUNDANT|IF_NONSENSE))
!= (IF_SET|IF_ASK|IF_REAL))
return 0;
if (sg->is_dc &&
(sg->ptable[sg->param].dataType & (IF_AC | IF_AC_ONLY)))
return 0;
if (sens_getp(sg, sg->ckt, &ifval))
return 0;
if (sg->ptable[sg->param].dataType & IF_PRINCIPAL)
sg->is_principle += 1;
sg->value = ifval.rValue;
return 1;
}
#ifdef notdef
void
sgen_suspend(sgen *sg)
{
sg->devlist[sg->dev] = sg->first_model;
sg->model->GENnextModel = sg->next_model;
sg->instance->GENnextInstance = sg->next_instance;
sg->model->GENinstances = sg->first_instance;
}
void
sgen_restore(sgen *sg)
{
sg->devlist[sg->dev] = sg->model;
sg->model->GENnextModel = NULL;
sg->instance->GENnextInstance = NULL;
sg->model->GENinstances = sg->instance;
}
#endif