diff --git a/configure.ac b/configure.ac index f4f5ece32..e67cb2c7d 100644 --- a/configure.ac +++ b/configure.ac @@ -1262,6 +1262,8 @@ AC_CONFIG_FILES([Makefile src/spicelib/devices/numd2/Makefile src/spicelib/devices/numos/Makefile src/spicelib/devices/balun/Makefile + src/spicelib/devices/nullator/Makefile + src/spicelib/devices/norator/Makefile src/spicelib/parser/Makefile src/ciderlib/Makefile src/ciderlib/input/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 7b9eb1bcf..af43903e9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,7 +135,9 @@ ngspice_LDADD += spicelib/devices/ndev/libndev.la endif if LOOPANA_WANTED -ngspice_LDADD += spicelib/devices/balun/libbalun.la +ngspice_LDADD += spicelib/devices/balun/libbalun.la \ + spicelib/devices/nullator/libnula.la \ + spicelib/devices/norator/libnora.la endif if NUMDEV_WANTED @@ -418,7 +420,9 @@ libspice_la_LIBADD += \ endif if LOOPANA_WANTED -libspice_la_LIBADD += spicelib/devices/balun/libbalun.la +libspice_la_LIBADD += spicelib/devices/balun/libbalun.la \ + spicelib/devices/nullator/libnula.la \ + spicelib/devices/norator/libnora.la endif if NUMDEV_WANTED @@ -537,7 +541,9 @@ libngspice_la_LIBADD += \ endif if LOOPANA_WANTED -libngspice_la_LIBADD += spicelib/devices/balun/libbalun.la +libngspice_la_LIBADD += spicelib/devices/balun/libbalun.la \ + spicelib/devices/nullator/libnula.la \ + spicelib/devices/norator/libnora.la endif if NUMDEV_WANTED diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 29e2cd469..968643e55 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -62,7 +62,7 @@ SUBDIRS += nbjt nbjt2 numd numd2 numos endif if LOOPANA_WANTED -SUBDIRS += balun +SUBDIRS += balun nullator norator endif @@ -123,7 +123,9 @@ DIST_SUBDIRS = \ numd \ numd2 \ numos \ - balun + balun \ + nullator \ + norator noinst_LTLIBRARIES = libdev.la diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index 81080ef47..2e44cf968 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -144,6 +144,8 @@ extern struct coreInfo_t coreInfo; /* cmexport.c */ #endif #ifdef WITH_LOOPANA #include "balun/balunitf.h" +#include "nullator/nulaitf.h" +#include "norator/noraitf.h" #endif static SPICEdev *(*static_devices[])(void) = { @@ -222,6 +224,8 @@ static SPICEdev *(*static_devices[])(void) = { #ifdef WITH_LOOPANA get_balun_info, + get_nula_info, + get_nora_info, #endif }; diff --git a/src/spicelib/devices/norator/Makefile.am b/src/spicelib/devices/norator/Makefile.am new file mode 100644 index 000000000..242bc53ef --- /dev/null +++ b/src/spicelib/devices/norator/Makefile.am @@ -0,0 +1,28 @@ +## Process this file with automake to produce Makefile.in + +noinst_LTLIBRARIES = libnora.la + +libnora_la_SOURCES = \ + nora.c \ + noraask.c \ + noradefs.h \ + noraext.h \ + norafbr.c \ + norainit.c \ + norainit.h \ + noraitf.h \ + noraload.c \ + norapar.c \ + norapzld.c \ + noraset.c + +# norasacl.c \ +# norasld.c \ +# norasprt.c \ +# norasset.c + + + +AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include +AM_CFLAGS = $(STATIC) +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/norator/nora.c b/src/spicelib/devices/norator/nora.c new file mode 100644 index 000000000..ed7001686 --- /dev/null +++ b/src/spicelib/devices/norator/nora.c @@ -0,0 +1,34 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "ngspice/devdefs.h" +#include "noradefs.h" +#include "ngspice/suffix.h" + +IFparm NORApTable[] = { /* parameters */ + OPU("pos_node", NORA_POS_NODE, IF_INTEGER, "Positive node of source"), + OPU("neg_node", NORA_NEG_NODE, IF_INTEGER, "Negative node of source"), + IP("ic", NORA_IC, IF_REAL, "Initial condition of branch current"), + OP("i", NORA_CURRENT, IF_REAL, "Output current"), + OP("v", NORA_VOLTS, IF_REAL, "Output voltage"), + OP("p", NORA_POWER, IF_REAL, "Power"), +}; + +char *NORAnames[] = { + "V+", + "V-", +}; + +int NORAnSize = NUMELEMS(NORAnames); +int NORApTSize = NUMELEMS(NORApTable); +int NORAmPTSize = 0; +int NORAiSize = sizeof(NORAinstance); +int NORAmSize = sizeof(NORAmodel); diff --git a/src/spicelib/devices/norator/noraask.c b/src/spicelib/devices/norator/noraask.c new file mode 100644 index 000000000..819b13588 --- /dev/null +++ b/src/spicelib/devices/norator/noraask.c @@ -0,0 +1,77 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ + +/* + * This routine gives access to the internal device parameters + * of Voltage Controlled Voltage Source + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/devdefs.h" +#include "ngspice/ifsim.h" +#include "noradefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/* ARGSUSED */ +int +NORAask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select) +{ + NORAinstance *here = (NORAinstance *)inst; + double vr; + double vi; + double sr; + double si; + double vm; + static char *msg = "Current and power not available for ac analysis"; + switch(which) { + case NORA_POS_NODE: + value->iValue = here->NORAposNode; + return (OK); + case NORA_NEG_NODE: + value->iValue = here->NORAnegNode; + return (OK); + case NORA_IC: + value->rValue = here->NORAinitCond; + return (OK); + case NORA_BR: + value->iValue = here->NORAbranch; + return (OK); + case NORA_CURRENT : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = TMALLOC(char, strlen(msg) + 1); + errRtn = "NORAask"; + strcpy(errMsg,msg); + return(E_ASKCURRENT); + } else { + value->rValue = *(ckt->CKTrhsOld + here->NORAbranch); + } + return(OK); + case NORA_VOLTS : + value->rValue = (*(ckt->CKTrhsOld + here->NORAposNode) - + *(ckt->CKTrhsOld + here->NORAnegNode)); + return(OK); + case NORA_POWER : + if (ckt->CKTcurrentAnalysis & DOING_AC) { + errMsg = TMALLOC(char, strlen(msg) + 1); + errRtn = "NORAask"; + strcpy(errMsg,msg); + return(E_ASKPOWER); + } else { + value->rValue = *(ckt->CKTrhsOld + here->NORAbranch) * + (*(ckt->CKTrhsOld + here->NORAposNode) - + *(ckt->CKTrhsOld + here->NORAnegNode)); + } + return(OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/norator/noradefs.h b/src/spicelib/devices/norator/noradefs.h new file mode 100644 index 000000000..040c425b0 --- /dev/null +++ b/src/spicelib/devices/norator/noradefs.h @@ -0,0 +1,81 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#ifndef NORA +#define NORA + + +#include "ngspice/ifsim.h" +#include "ngspice/cktdefs.h" +#include "ngspice/gendefs.h" +#include "ngspice/complex.h" + + /* + * structures to describe Voltage Controlled Voltage Sources + */ + +/* information to describe a single instance */ + +typedef struct sNORAinstance { + + struct GENinstance gen; + +#define NORAmodPtr(inst) ((struct sNORAmodel *)((inst)->gen.GENmodPtr)) +#define NORAnextInstance(inst) ((struct sNORAinstance *)((inst)->gen.GENnextInstance)) +#define NORAname gen.GENname +#define NORAstates gen.GENstate + + const int NORAposNode; /* number of positive node of source */ + const int NORAnegNode; /* number of negative node of source */ + int NORAbranch; /* equation number of branch equation added for v source */ + + double NORAinitCond; /* initial condition (of branch current) */ + + double *NORAposIbrPtr; /* pointer to sparse matrix element at + * (positive node, branch equation) */ + double *NORAnegIbrPtr; /* pointer to sparse matrix element at + * (negative node, branch equation) */ + +} NORAinstance ; + +#define NORAvOld NORAstates +#define NORAcontVOld NORAstates + 1 + +/* per model data */ + +typedef struct sNORAmodel { /* model structure for a source */ + + struct GENmodel gen; + +#define NORAmodType gen.GENmodType +#define NORAnextModel(inst) ((struct sNORAmodel *)((inst)->gen.GENnextModel)) +#define NORAinstances(inst) ((NORAinstance *)((inst)->gen.GENinstances)) +#define NORAmodName gen.GENmodName + +} NORAmodel; + +/* device parameters */ +enum { + NORA_POS_NODE = 1, + NORA_NEG_NODE, + NORA_BR, + NORA_IC, + NORA_CURRENT, + NORA_POWER, + NORA_VOLTS, +}; + +/* model parameters */ + + +/* model questions */ + +#include "noraext.h" + +#endif /*NORA*/ diff --git a/src/spicelib/devices/norator/noraext.h b/src/spicelib/devices/norator/noraext.h new file mode 100644 index 000000000..4bd1bcdb2 --- /dev/null +++ b/src/spicelib/devices/norator/noraext.h @@ -0,0 +1,23 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +extern int NORAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int NORAfindBr(CKTcircuit*,GENmodel*,IFuid); +extern int NORAload(GENmodel*,CKTcircuit*); +extern int NORAparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int NORAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int NORAunsetup(GENmodel*,CKTcircuit*); +extern int NORApzLoad(GENmodel*,CKTcircuit*,SPcomplex*); + +/* +extern int NORAsAcLoad(GENmodel*,CKTcircuit*); +extern int NORAsLoad(GENmodel*,CKTcircuit*); +extern int NORAsSetup(SENstruct*,GENmodel*); +extern void NORAsPrint(GENmodel*,CKTcircuit*); +*/ diff --git a/src/spicelib/devices/norator/norafbr.c b/src/spicelib/devices/norator/norafbr.c new file mode 100644 index 000000000..c811598ff --- /dev/null +++ b/src/spicelib/devices/norator/norafbr.c @@ -0,0 +1,42 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "noradefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +NORAfindBr(CKTcircuit *ckt, GENmodel *inModel, IFuid name) +{ + NORAmodel *model = (NORAmodel *)inModel; + NORAinstance *here; + int error; + CKTnode *tmp; + + for( ; model != NULL; model = NORAnextModel(model)) { + for (here = NORAinstances(model); here != NULL; + here = NORAnextInstance(here)) { + if(here->NORAname == name) { + if(here->NORAbranch == 0) { + error = CKTmkCur(ckt,&tmp,here->NORAname,"branch"); + if(error) return(error); + here->NORAbranch = tmp->number; + } + return(here->NORAbranch); + } + } + } + return(0); +} diff --git a/src/spicelib/devices/norator/norainit.c b/src/spicelib/devices/norator/norainit.c new file mode 100644 index 000000000..4e0c5a8e4 --- /dev/null +++ b/src/spicelib/devices/norator/norainit.c @@ -0,0 +1,80 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +#include "ngspice/config.h" + +#include "ngspice/devdefs.h" + +#include "noraitf.h" +#include "noraext.h" +#include "norainit.h" + + +SPICEdev NORAinfo = { + .DEVpublic = { + .name = "Norator", + .description = "Norator - arbitrary current source", + .terms = &NORAnSize, + .numNames = &NORAnSize, + .termNames = NORAnames, + .numInstanceParms = &NORApTSize, + .instanceParms = NORApTable, + .numModelParms = NULL, + .modelParms = NULL, + .flags = DEV_DEFAULT, + +#ifdef XSPICE + .cm_func = NULL, + .num_conn = 0, + .conn = NULL, + .num_param = 0, + .param = NULL, + .num_inst_var = 0, + .inst_var = NULL, +#endif + }, + + .DEVparam = NORAparam, + .DEVmodParam = NULL, + .DEVload = NORAload, + .DEVsetup = NORAsetup, + .DEVunsetup = NORAunsetup, + .DEVpzSetup = NORAsetup, + .DEVtemperature = NULL, + .DEVtrunc = NULL, + .DEVfindBranch = NORAfindBr, + .DEVacLoad = NORAload, + .DEVaccept = NULL, + .DEVdestroy = NULL, + .DEVmodDelete = NULL, + .DEVdelete = NULL, + .DEVsetic = NULL, + .DEVask = NORAask, + .DEVmodAsk = NULL, + .DEVpzLoad = NORApzLoad, + .DEVconvTest = NULL, + .DEVsenSetup = NULL, + .DEVsenLoad = NULL, + .DEVsenUpdate = NULL, + .DEVsenAcLoad = NULL, + .DEVsenPrint = NULL, + .DEVsenTrunc = NULL, + .DEVdisto = NULL, + .DEVnoise = NULL, + .DEVsoaCheck = NULL, + .DEVinstSize = &NORAiSize, + .DEVmodSize = &NORAmSize, + +#ifdef CIDER + .DEVdump = NULL, + .DEVacct = NULL, +#endif +}; + + +SPICEdev * +get_nora_info(void) +{ + return &NORAinfo; +} diff --git a/src/spicelib/devices/norator/norainit.h b/src/spicelib/devices/norator/norainit.h new file mode 100644 index 000000000..456f7fb25 --- /dev/null +++ b/src/spicelib/devices/norator/norainit.h @@ -0,0 +1,15 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +#ifndef _NORAINIT_H +#define _NORAINIT_H + +extern IFparm NORApTable[ ]; +extern char *NORAnames[ ]; +extern int NORApTSize; +extern int NORAnSize; +extern int NORAiSize; +extern int NORAmSize; + +#endif diff --git a/src/spicelib/devices/norator/noraitf.h b/src/spicelib/devices/norator/noraitf.h new file mode 100644 index 000000000..07e3fa660 --- /dev/null +++ b/src/spicelib/devices/norator/noraitf.h @@ -0,0 +1,13 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ +#ifndef DEV_NORA +#define DEV_NORA + +SPICEdev *get_nora_info(void); + +#endif diff --git a/src/spicelib/devices/norator/noraload.c b/src/spicelib/devices/norator/noraload.c new file mode 100644 index 000000000..ab10e7fd0 --- /dev/null +++ b/src/spicelib/devices/norator/noraload.c @@ -0,0 +1,48 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "noradefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +/*ARGSUSED*/ +int +NORAload(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current voltage value into the + * sparse matrix previously provided + */ +{ + NORAmodel *model = (NORAmodel *)inModel; + NORAinstance *here; + + NG_IGNORE(ckt); + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NORAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NORAinstances(model); here != NULL ; + here=NORAnextInstance(here)) { + + *(here->NORAposIbrPtr) += 1.0 ; + *(here->NORAnegIbrPtr) -= 1.0 ; + /* equations to be loaded by a nullator : + *(here->NORAibrContPosPtr) += 1.0 ; + *(here->NORAibrContNegPtr) -= 1.0 ; + *(ckt->CKTrhs + (here->NORAbranch)) += here->NORAoffset; + */ + } + } + return(OK); +} diff --git a/src/spicelib/devices/norator/norapar.c b/src/spicelib/devices/norator/norapar.c new file mode 100644 index 000000000..4dc83d1fc --- /dev/null +++ b/src/spicelib/devices/norator/norapar.c @@ -0,0 +1,32 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "noradefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +/* ARGSUSED */ +int +NORAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) +{ + NORAinstance *here = (NORAinstance *)inst; + + NG_IGNORE(select); + + switch(param) { + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/norator/norapzld.c b/src/spicelib/devices/norator/norapzld.c new file mode 100644 index 000000000..e35901dca --- /dev/null +++ b/src/spicelib/devices/norator/norapzld.c @@ -0,0 +1,46 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/complex.h" +#include "ngspice/sperror.h" +#include "noradefs.h" +#include "ngspice/suffix.h" + +/* file not used - use regular load function */ + +/*ARGSUSED*/ +int +NORApzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) + /* actually load the current voltage value into the + * sparse matrix previously provided + */ +{ + NORAmodel *model = (NORAmodel *)inModel; + NORAinstance *here; + + NG_IGNORE(s); + NG_IGNORE(ckt); + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NORAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NORAinstances(model); here != NULL ; + here=NORAnextInstance(here)) { + + *(here->NORAposIbrPtr) += 1.0 ; + *(here->NORAnegIbrPtr) -= 1.0 ; + } + } + return(OK); +} diff --git a/src/spicelib/devices/norator/norasacl.c b/src/spicelib/devices/norator/norasacl.c new file mode 100644 index 000000000..af8fe25e6 --- /dev/null +++ b/src/spicelib/devices/norator/norasacl.c @@ -0,0 +1,54 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* actually load the current ac sensitivity information into the + * array previously provided + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "noradefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +NORAsAcLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + NORAmodel *model = (NORAmodel *)inModel; + NORAinstance *here; + double vc; + double ivc; + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NORAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NORAinstances(model); here != NULL ; + here=NORAnextInstance(here)) { + + if(here->NORAsenParmNo){ + + vc = *(ckt->CKTrhsOld + here->NORAcontPosNode) + - *(ckt->CKTrhsOld + here->NORAcontNegNode); + ivc = *(ckt->CKTirhsOld + here->NORAcontPosNode) + - *(ckt->CKTirhsOld + here->NORAcontNegNode); + + *(ckt->CKTsenInfo->SEN_RHS[here->NORAbranch] + + here->NORAsenParmNo) += vc; + *(ckt->CKTsenInfo->SEN_iRHS[here->NORAbranch] + + here->NORAsenParmNo) += ivc; + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/norator/noraset.c b/src/spicelib/devices/norator/noraset.c new file mode 100644 index 000000000..0ac84668d --- /dev/null +++ b/src/spicelib/devices/norator/noraset.c @@ -0,0 +1,87 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Created 2020 Florian Ballenegger - based on VCVS code. +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* load the voltage source structure with those pointers needed later + * for fast matrix loading + */ + +#include "ngspice/ngspice.h" +#include "ngspice/smpdefs.h" +#include "ngspice/cktdefs.h" +#include "noradefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/*ARGSUSED*/ +int +NORAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) +{ + NORAmodel *model = (NORAmodel *)inModel; + NORAinstance *here; + int error; + CKTnode *tmp; + + NG_IGNORE(states); + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NORAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NORAinstances(model); here != NULL ; + here=NORAnextInstance(here)) { + + if(here->NORAposNode == here->NORAnegNode) { + SPfrontEnd->IFerrorf (ERR_FATAL, + "instance %s is a shorted NORATOR", here->NORAname); + return(E_UNSUPP); + } + + if(here->NORAbranch == 0) { + error = CKTmkCur(ckt,&tmp,here->NORAname,"branch"); + if(error) return(error); + here->NORAbranch = tmp->number; + } + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ + return(E_NOMEM);\ +} } while(0) + + TSTALLOC(NORAposIbrPtr, NORAposNode, NORAbranch); + TSTALLOC(NORAnegIbrPtr, NORAnegNode, NORAbranch); + /* + TSTALLOC(NORAibrContPosPtr, NORAbranch, NORAcontPosNode); + TSTALLOC(NORAibrContNegPtr, NORAbranch, NORAcontNegNode); + */ + } + } + return(OK); +} + +int +NORAunsetup(GENmodel *inModel, CKTcircuit *ckt) +{ + NORAmodel *model; + NORAinstance *here; + + for (model = (NORAmodel *)inModel; model != NULL; + model = NORAnextModel(model)) + { + for (here = NORAinstances(model); here != NULL; + here=NORAnextInstance(here)) + { + if (here->NORAbranch > 0) + CKTdltNNum(ckt, here->NORAbranch); + here->NORAbranch = 0; + } + } + return OK; +} diff --git a/src/spicelib/devices/nullator/Makefile.am b/src/spicelib/devices/nullator/Makefile.am new file mode 100644 index 000000000..f89066208 --- /dev/null +++ b/src/spicelib/devices/nullator/Makefile.am @@ -0,0 +1,30 @@ +## Process this file with automake to produce Makefile.in + +noinst_LTLIBRARIES = libnula.la + +libnula_la_SOURCES = \ + nula.c \ + nulaask.c \ + nuladefs.h \ + nulaext.h \ + nulainit.c \ + nulainit.h \ + nulaitf.h \ + nulaload.c \ + nulapar.c \ + nulaset.c \ + nulapzld.c + +# nulafbr.c +# nulapzld.c \ +# nulasacl.c \ +# nulaset.c \ +# nulasld.c \ +# nulasprt.c \ +# nulasset.c + + + +AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include +AM_CFLAGS = $(STATIC) +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/nullator/nula.c b/src/spicelib/devices/nullator/nula.c new file mode 100644 index 000000000..bbd48929f --- /dev/null +++ b/src/spicelib/devices/nullator/nula.c @@ -0,0 +1,33 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "ngspice/devdefs.h" +#include "nuladefs.h" +#include "ngspice/suffix.h" + +IFparm NULApTable[] = { /* parameters */ + IOP("offset", NULA_OFFSET, IF_REAL,"Control offset"), + OPU("cont_p_node",NULA_CONT_P_NODE,IF_INTEGER, + "Positive node of nullator"), + OPU("cont_n_node",NULA_CONT_N_NODE,IF_INTEGER, + "Negative node of nullator"), +}; + +char *NULAnames[] = { + "VC+", + "VC-" +}; + +int NULAnSize = NUMELEMS(NULAnames); +int NULApTSize = NUMELEMS(NULApTable); +int NULAmPTSize = 0; +int NULAiSize = sizeof(NULAinstance); +int NULAmSize = sizeof(NULAmodel); diff --git a/src/spicelib/devices/nullator/nulaask.c b/src/spicelib/devices/nullator/nulaask.c new file mode 100644 index 000000000..e3c1baf07 --- /dev/null +++ b/src/spicelib/devices/nullator/nulaask.c @@ -0,0 +1,39 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Thomas L. Quarles +**********/ + +/* + * This routine gives access to the internal device parameters + * of Voltage Controlled Voltage Source + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/devdefs.h" +#include "ngspice/ifsim.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/* ARGSUSED */ +int +NULAask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select) +{ + NULAinstance *here = (NULAinstance *)inst; + switch(which) { + case NULA_CONT_P_NODE: + value->iValue = here->NULAcontPosNode; + return (OK); + case NULA_CONT_N_NODE: + value->iValue = here->NULAcontNegNode; + return (OK); + default: + return (E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/nullator/nuladefs.h b/src/spicelib/devices/nullator/nuladefs.h new file mode 100644 index 000000000..3426a8657 --- /dev/null +++ b/src/spicelib/devices/nullator/nuladefs.h @@ -0,0 +1,79 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +#ifndef NULA +#define NULA + + +#include "ngspice/ifsim.h" +#include "ngspice/cktdefs.h" +#include "ngspice/gendefs.h" +#include "ngspice/complex.h" + + /* + * structures to describe Voltage Controlled Voltage Sources + */ + +/* information to describe a single instance */ + +typedef struct sNULAinstance { + + struct GENinstance gen; + +#define NULAmodPtr(inst) ((struct sNULAmodel *)((inst)->gen.GENmodPtr)) +#define NULAnextInstance(inst) ((struct sNULAinstance *)((inst)->gen.GENnextInstance)) +#define NULAname gen.GENname +#define NULAstates gen.GENstate + + const int NULAcontPosNode; /* number of positive node of controlling source */ + const int NULAcontNegNode; /* number of negative node of controlling source */ + int NULAbranch; /* equation number of branch equation added for v source */ + + double NULAoffset; /* control offset */ + + double *NULAibrContPosPtr; /* pointer to sparse matrix element at + *(branch equation, control positive node)*/ + double *NULAibrContNegPtr; /* pointer to sparse matrix element at + *(branch equation, control negative node)*/ + unsigned NULAoffsetGiven :1 ;/* flag to indicate offset given */ + +} NULAinstance ; + +#define NULAvOld NULAstates +#define NULAcontVOld NULAstates + 1 + +/* per model data */ + +typedef struct sNULAmodel { /* model structure for a source */ + + struct GENmodel gen; + +#define NULAmodType gen.GENmodType +#define NULAnextModel(inst) ((struct sNULAmodel *)((inst)->gen.GENnextModel)) +#define NULAinstances(inst) ((NULAinstance *)((inst)->gen.GENinstances)) +#define NULAmodName gen.GENmodName + +} NULAmodel; + +/* device parameters */ +enum { + NULA_OFFSET = 1, + NULA_CONT_P_NODE, + NULA_CONT_N_NODE, +}; + +/* model parameters */ + +/* device questions */ + +/* model questions */ + +#include "nulaext.h" + +#endif /*NULA*/ diff --git a/src/spicelib/devices/nullator/nulaext.h b/src/spicelib/devices/nullator/nulaext.h new file mode 100644 index 000000000..72507b534 --- /dev/null +++ b/src/spicelib/devices/nullator/nulaext.h @@ -0,0 +1,23 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +extern int NULAask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); +extern int NULAfindBr(CKTcircuit*,GENmodel*,IFuid); +extern int NULAload(GENmodel*,CKTcircuit*); +extern int NULAparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int NULAsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int NULAunsetup(GENmodel*,CKTcircuit*); +extern int NULApzLoad(GENmodel*,CKTcircuit*,SPcomplex*); + +/* +extern int NULAsAcLoad(GENmodel*,CKTcircuit*); +extern int NULAsLoad(GENmodel*,CKTcircuit*); +extern int NULAsSetup(SENstruct*,GENmodel*); +extern void NULAsPrint(GENmodel*,CKTcircuit*); +*/ diff --git a/src/spicelib/devices/nullator/nulainit.c b/src/spicelib/devices/nullator/nulainit.c new file mode 100644 index 000000000..e6b8b9239 --- /dev/null +++ b/src/spicelib/devices/nullator/nulainit.c @@ -0,0 +1,80 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +#include "ngspice/config.h" + +#include "ngspice/devdefs.h" + +#include "nulaitf.h" +#include "nulaext.h" +#include "nulainit.h" + + +SPICEdev NULAinfo = { + .DEVpublic = { + .name = "Nullator", + .description = "Nullator", + .terms = &NULAnSize, + .numNames = &NULAnSize, + .termNames = NULAnames, + .numInstanceParms = &NULApTSize, + .instanceParms = NULApTable, + .numModelParms = NULL, + .modelParms = NULL, + .flags = DEV_DEFAULT, + +#ifdef XSPICE + .cm_func = NULL, + .num_conn = 0, + .conn = NULL, + .num_param = 0, + .param = NULL, + .num_inst_var = 0, + .inst_var = NULL, +#endif + }, + + .DEVparam = NULAparam, + .DEVmodParam = NULL, + .DEVload = NULAload, + .DEVsetup = NULAsetup, + .DEVunsetup = NULAunsetup, + .DEVpzSetup = NULAsetup, + .DEVtemperature = NULL, + .DEVtrunc = NULL, + .DEVfindBranch = NULL, + .DEVacLoad = NULAload, + .DEVaccept = NULL, + .DEVdestroy = NULL, + .DEVmodDelete = NULL, + .DEVdelete = NULL, + .DEVsetic = NULL, + .DEVask = NULAask, + .DEVmodAsk = NULL, + .DEVpzLoad = NULApzLoad, + .DEVconvTest = NULL, + .DEVsenSetup = NULL, + .DEVsenLoad = NULL, + .DEVsenUpdate = NULL, + .DEVsenAcLoad = NULL, + .DEVsenPrint = NULL, + .DEVsenTrunc = NULL, + .DEVdisto = NULL, + .DEVnoise = NULL, + .DEVsoaCheck = NULL, + .DEVinstSize = &NULAiSize, + .DEVmodSize = &NULAmSize, + +#ifdef CIDER + .DEVdump = NULL, + .DEVacct = NULL, +#endif +}; + + +SPICEdev * +get_nula_info(void) +{ + return &NULAinfo; +} diff --git a/src/spicelib/devices/nullator/nulainit.h b/src/spicelib/devices/nullator/nulainit.h new file mode 100644 index 000000000..ed4e097af --- /dev/null +++ b/src/spicelib/devices/nullator/nulainit.h @@ -0,0 +1,15 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +#ifndef _NULAINIT_H +#define _NULAINIT_H + +extern IFparm NULApTable[ ]; +extern char *NULAnames[ ]; +extern int NULApTSize; +extern int NULAnSize; +extern int NULAiSize; +extern int NULAmSize; + +#endif diff --git a/src/spicelib/devices/nullator/nulaitf.h b/src/spicelib/devices/nullator/nulaitf.h new file mode 100644 index 000000000..7ef2fd373 --- /dev/null +++ b/src/spicelib/devices/nullator/nulaitf.h @@ -0,0 +1,13 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +**********/ +#ifndef DEV_NULA +#define DEV_NULA + +SPICEdev *get_nula_info(void); + +#endif diff --git a/src/spicelib/devices/nullator/nulaload.c b/src/spicelib/devices/nullator/nulaload.c new file mode 100644 index 000000000..c6c5be5ba --- /dev/null +++ b/src/spicelib/devices/nullator/nulaload.c @@ -0,0 +1,44 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +/*ARGSUSED*/ +int +NULAload(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current voltage value into the + * sparse matrix previously provided + */ +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + + NG_IGNORE(ckt); + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + *(here->NULAibrContPosPtr) += 1.0 ; + *(here->NULAibrContNegPtr) -= 1.0 ; + *(ckt->CKTrhs + (here->NULAbranch)) += here->NULAoffset; + } + } + return(OK); +} diff --git a/src/spicelib/devices/nullator/nulapar.c b/src/spicelib/devices/nullator/nulapar.c new file mode 100644 index 000000000..98e0feeaf --- /dev/null +++ b/src/spicelib/devices/nullator/nulapar.c @@ -0,0 +1,36 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +/* ARGSUSED */ +int +NULAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) +{ + NULAinstance *here = (NULAinstance *)inst; + + NG_IGNORE(select); + + switch(param) { + case NULA_OFFSET: + here->NULAoffset = value->rValue; + here->NULAoffsetGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/nullator/nulapzld.c b/src/spicelib/devices/nullator/nulapzld.c new file mode 100644 index 000000000..76cc41433 --- /dev/null +++ b/src/spicelib/devices/nullator/nulapzld.c @@ -0,0 +1,45 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/complex.h" +#include "ngspice/sperror.h" +#include "nuladefs.h" +#include "ngspice/suffix.h" + + +/*ARGSUSED*/ +int +NULApzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) + /* actually load the current voltage value into the + * sparse matrix previously provided + */ +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + + NG_IGNORE(s); + NG_IGNORE(ckt); + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + *(here->NULAibrContPosPtr) += 1.0 ; + *(here->NULAibrContNegPtr) -= 1.0 ; + } + } + return(OK); +} diff --git a/src/spicelib/devices/nullator/nulasacl.c b/src/spicelib/devices/nullator/nulasacl.c new file mode 100644 index 000000000..767cd1982 --- /dev/null +++ b/src/spicelib/devices/nullator/nulasacl.c @@ -0,0 +1,54 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* actually load the current ac sensitivity information into the + * array previously provided + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +NULAsAcLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + double vc; + double ivc; + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + if(here->NULAsenParmNo){ + + vc = *(ckt->CKTrhsOld + here->NULAcontPosNode) + - *(ckt->CKTrhsOld + here->NULAcontNegNode); + ivc = *(ckt->CKTirhsOld + here->NULAcontPosNode) + - *(ckt->CKTirhsOld + here->NULAcontNegNode); + + *(ckt->CKTsenInfo->SEN_RHS[here->NULAbranch] + + here->NULAsenParmNo) += vc; + *(ckt->CKTsenInfo->SEN_iRHS[here->NULAbranch] + + here->NULAsenParmNo) += ivc; + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/nullator/nulaset.c b/src/spicelib/devices/nullator/nulaset.c new file mode 100644 index 000000000..c95aa3866 --- /dev/null +++ b/src/spicelib/devices/nullator/nulaset.c @@ -0,0 +1,121 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ + +/* load the voltage source structure with those pointers needed later + * for fast matrix loading + */ + +#include "ngspice/ngspice.h" +#include "ngspice/smpdefs.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +#include "ngspice/devdefs.h" + +/*ARGSUSED*/ +int +NULAsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + GENinstance *nora; + GENmodel *noramod; + + int i, error; + CKTnode *tmp; + + NG_IGNORE(states); + + noramod = NULL; + nora = NULL; + for (i=0;iDEVpublic.name,"Norator")==0) { + noramod = ckt->CKThead[i]; + break; + } + if(i==DEVmaxnum) + if(model && NULAinstances(model)) /* emit warning only if circuit actualy has a nullator */ + SPfrontEnd->IFerrorf (ERR_WARNING, + "Norator device needed for nullator, missing."); + if(noramod) + nora = noramod->GENinstances; + + /* loop through all the nullator models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + if(here->NULAcontPosNode == here->NULAcontNegNode) { + SPfrontEnd->IFerrorf (ERR_FATAL, + "instance %s is a shorted nullator", here->NULAname); + return(E_UNSUPP); + } + + if(!here->NULAoffsetGiven) + here->NULAoffset = 0.0; + + if(here->NULAbranch == 0) { + /* assign a branch from a norator device ... */ + if(nora) { + here->NULAbranch = DEVices[i]->DEVfindBranch(ckt, noramod, nora->GENname); + } else { + SPfrontEnd->IFerrorf (ERR_FATAL, + "excess nullators in respect to number of norator"); + return(E_UNSUPP); + } + + /* point to next norator instance */ + nora = nora->GENnextInstance; + if(!nora) { + noramod = noramod->GENnextModel; + if(noramod) + nora = noramod->GENinstances; + } + } + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ + return(E_NOMEM);\ +} } while(0) + if(here->NULAbranch>0) { + TSTALLOC(NULAibrContPosPtr, NULAbranch, NULAcontPosNode); + TSTALLOC(NULAibrContNegPtr, NULAbranch, NULAcontNegNode); + } else { + SPfrontEnd->IFerrorf (ERR_FATAL, + "failed to find a norator branch for nullator %s", here->NULAname); + return(E_UNSUPP); + } + } + } + return(OK); +} + +int +NULAunsetup(GENmodel *inModel, CKTcircuit *ckt) +{ + NULAmodel *model; + NULAinstance *here; + + for (model = (NULAmodel *)inModel; model != NULL; + model = NULAnextModel(model)) + { + for (here = NULAinstances(model); here != NULL; + here=NULAnextInstance(here)) + { + here->NULAbranch = 0; + } + } + return OK; +} diff --git a/src/spicelib/devices/nullator/nulasld.c b/src/spicelib/devices/nullator/nulasld.c new file mode 100644 index 000000000..546c9dab8 --- /dev/null +++ b/src/spicelib/devices/nullator/nulasld.c @@ -0,0 +1,48 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* actually load the current sensitivity information into the + * array previously provided + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +NULAsLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + double vc; + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + if(here->NULAsenParmNo){ + + vc = *(ckt->CKTrhsOld + here->NULAcontPosNode) + - *(ckt->CKTrhsOld + here->NULAcontNegNode); + + *(ckt->CKTsenInfo->SEN_RHS[here->NULAbranch] + + here->NULAsenParmNo) += vc; + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/nullator/nulasprt.c b/src/spicelib/devices/nullator/nulasprt.c new file mode 100644 index 000000000..0c190bb72 --- /dev/null +++ b/src/spicelib/devices/nullator/nulasprt.c @@ -0,0 +1,52 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* Pretty print the sensitivity info for + * all the NULA in the circuit. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +void +NULAsPrint(GENmodel *inModel, CKTcircuit *ckt) +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + + printf("VOLTAGE CONTROLLED VOLTAGE SOURCES-----------------\n"); + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + printf("Model name:%s\n",model->NULAmodName); + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + printf(" Instance name:%s\n",here->NULAname); + printf(" Positive, negative nodes: %s, %s\n", + CKTnodName(ckt,here->NULAposNode), + CKTnodName(ckt,here->NULAnegNode)); + printf(" Controlling Positive, negative nodes: %s, %s\n", + CKTnodName(ckt,here->NULAcontPosNode), + CKTnodName(ckt,here->NULAcontNegNode)); + printf(" Branch equation number: %s\n", + CKTnodName(ckt,here->NULAbranch)); + printf(" Coefficient: %f\n",here->NULAcoeff); + printf(" NULAsenParmNo:%d\n",here->NULAsenParmNo); + } + } +} diff --git a/src/spicelib/devices/nullator/nulasset.c b/src/spicelib/devices/nullator/nulasset.c new file mode 100644 index 000000000..3fd3dda69 --- /dev/null +++ b/src/spicelib/devices/nullator/nulasset.c @@ -0,0 +1,44 @@ +/********** +Author: Florian Ballenegger 2020 +Adapted from VCVS device code. +**********/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +**********/ +/* + */ + +/* loop through all the devices and + * allocate parameter #s to design parameters + */ + +#include "ngspice/ngspice.h" +#include "ngspice/smpdefs.h" +#include "ngspice/cktdefs.h" +#include "nuladefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +NULAsSetup(SENstruct *info, GENmodel *inModel) +{ + NULAmodel *model = (NULAmodel *)inModel; + NULAinstance *here; + + /* loop through all the voltage source models */ + for( ; model != NULL; model = NULAnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = NULAinstances(model); here != NULL ; + here=NULAnextInstance(here)) { + + if(here->NULAsenParmNo){ + here->NULAsenParmNo = ++(info->SENparms); + } + + } + } + return(OK); +}