add ideal balun device
This commit is contained in:
parent
c49cb51492
commit
41c4098227
|
|
@ -1261,6 +1261,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/spicelib/devices/numd/Makefile
|
||||
src/spicelib/devices/numd2/Makefile
|
||||
src/spicelib/devices/numos/Makefile
|
||||
src/spicelib/devices/balun/Makefile
|
||||
src/spicelib/parser/Makefile
|
||||
src/ciderlib/Makefile
|
||||
src/ciderlib/input/Makefile
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
* simple differential pair with simple common-mode feedback
|
||||
|
||||
.model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.6
|
||||
.model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.7
|
||||
|
||||
.subckt diffpair inp inn outp outn setcm vdd vss
|
||||
Mp1 outp cmfb vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
|
||||
Mp2 outn cmfb vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
|
||||
Mpcm cmfb cmfb vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=2
|
||||
|
||||
Mncm cmfb setcm tail vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
|
||||
Mn1 outn inp tail vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=8
|
||||
Mn2 outp inn tail vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=8
|
||||
|
||||
*bias
|
||||
Mn0 tail bn vss vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
|
||||
Mnn bn bn vss vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
|
||||
Ib vss bn 1u
|
||||
.ends
|
||||
|
||||
Xdiff inp inn outp outn setcm vdd vss diffpair
|
||||
Cload outp outn 100f
|
||||
|
||||
Balun1#balun outp outn outcm outdiff
|
||||
Balun1#balun inn inp incm indiff
|
||||
Vprobediff outdiff indiff DC 0
|
||||
Vprobecm outcm incm DC 0
|
||||
|
||||
Vset setcm vss DC 1.1
|
||||
Vvdd vdd vss DC 3.3
|
||||
Vvss vss 0 DC 0
|
||||
|
||||
|
|
@ -134,6 +134,10 @@ if NDEV_WANTED
|
|||
ngspice_LDADD += spicelib/devices/ndev/libndev.la
|
||||
endif
|
||||
|
||||
if LOOPANA_WANTED
|
||||
ngspice_LDADD += spicelib/devices/balun/libbalun.la
|
||||
endif
|
||||
|
||||
if NUMDEV_WANTED
|
||||
ngspice_LDADD += \
|
||||
spicelib/devices/nbjt/libnbjt.la \
|
||||
|
|
@ -413,6 +417,10 @@ libspice_la_LIBADD += \
|
|||
spicelib/devices/ndev/libndev.la
|
||||
endif
|
||||
|
||||
if LOOPANA_WANTED
|
||||
libspice_la_LIBADD += spicelib/devices/balun/libbalun.la
|
||||
endif
|
||||
|
||||
if NUMDEV_WANTED
|
||||
libspice_la_LIBADD += \
|
||||
spicelib/devices/nbjt/libnbjt.la \
|
||||
|
|
@ -528,6 +536,10 @@ libngspice_la_LIBADD += \
|
|||
spicelib/devices/ndev/libndev.la
|
||||
endif
|
||||
|
||||
if LOOPANA_WANTED
|
||||
libngspice_la_LIBADD += spicelib/devices/balun/libbalun.la
|
||||
endif
|
||||
|
||||
if NUMDEV_WANTED
|
||||
libngspice_la_LIBADD += \
|
||||
spicelib/devices/nbjt/libnbjt.la \
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@ Author: 1985 Wayne A. Christopher
|
|||
/* gtri - end - 12/12/90 */
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
int INP2gentype(char* line);
|
||||
#endif
|
||||
|
||||
/* SJB - Uncomment this line for debug tracing */
|
||||
/*#define TRACE*/
|
||||
|
||||
|
|
@ -4701,6 +4705,11 @@ static void inp_compat(struct card *card)
|
|||
|
||||
if (*curr_line == '*')
|
||||
continue;
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
if (INP2gentype(curr_line))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (*curr_line == 'e') {
|
||||
/* Exxx n1 n2 VCVS n3 n4 gain --> Exxx n1 n2 n3 n4 gain
|
||||
|
|
@ -5771,6 +5780,10 @@ static void inp_bsource_compat(struct card *card)
|
|||
else if (skip_control > 0) {
|
||||
continue;
|
||||
}
|
||||
#ifdef WITH_LOOPANA
|
||||
else if (INP2gentype(curr_line))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if (*curr_line == 'b') {
|
||||
/* remove white spaces of everything inside {}*/
|
||||
|
|
@ -8297,7 +8310,7 @@ static void inp_check_syntax(struct card *deck)
|
|||
}
|
||||
else {
|
||||
if (!check_ch) {
|
||||
fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %$§\"!:,'\n", *cut_line);
|
||||
fprintf(stderr, "Warning: Unusal leading characters like '%c' or others out of '= [] ? () & %%$§\"!:,'\n", *cut_line);
|
||||
fprintf(stderr, " in netlist or included files, will be replaced with '*'\n");
|
||||
check_ch = 1; /* just one warning */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ if NUMDEV_WANTED
|
|||
SUBDIRS += nbjt nbjt2 numd numd2 numos
|
||||
endif
|
||||
|
||||
if LOOPANA_WANTED
|
||||
SUBDIRS += balun
|
||||
endif
|
||||
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
asrc \
|
||||
bjt \
|
||||
|
|
@ -117,7 +122,8 @@ DIST_SUBDIRS = \
|
|||
nbjt2 \
|
||||
numd \
|
||||
numd2 \
|
||||
numos
|
||||
numos \
|
||||
balun
|
||||
|
||||
|
||||
noinst_LTLIBRARIES = libdev.la
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_LTLIBRARIES = libbalun.la
|
||||
|
||||
libbalun_la_SOURCES = \
|
||||
balun.c \
|
||||
balunask.c \
|
||||
balundefs.h \
|
||||
balunext.h \
|
||||
baluninit.c \
|
||||
baluninit.h \
|
||||
balunitf.h \
|
||||
balunload.c \
|
||||
balunpar.c \
|
||||
balunpzld.c \
|
||||
balunset.c
|
||||
|
||||
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/**********
|
||||
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 "balundefs.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
IFparm BALUNpTable[] = { /* parameters */
|
||||
OPU("pos_node", BALUN_POS_NODE, IF_INTEGER, "Positive node"),
|
||||
OPU("neg_node", BALUN_NEG_NODE, IF_INTEGER, "Negative node"),
|
||||
OPU("cm_node", BALUN_CM_NODE, IF_INTEGER, "Common-mode node"),
|
||||
OPU("diff_node", BALUN_DIFF_NODE, IF_INTEGER, "Differential node"),
|
||||
OP("p", BALUN_POWER, IF_REAL, "Power"),
|
||||
};
|
||||
|
||||
char *BALUNnames[] = {
|
||||
"Pos",
|
||||
"Neg",
|
||||
"CM",
|
||||
"Diff"
|
||||
};
|
||||
|
||||
int BALUNnSize = NUMELEMS(BALUNnames);
|
||||
int BALUNpTSize = NUMELEMS(BALUNpTable);
|
||||
int BALUNmPTSize = 0;
|
||||
int BALUNiSize = sizeof(BALUNinstance);
|
||||
int BALUNmSize = sizeof(BALUNmodel);
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/**********
|
||||
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 "balundefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
BALUNask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select)
|
||||
{
|
||||
BALUNinstance *here = (BALUNinstance *)inst;
|
||||
static char *msg = "Power not available for ac analysis";
|
||||
switch(which) {
|
||||
case BALUN_POS_NODE:
|
||||
value->iValue = here->BALUNposNode;
|
||||
return (OK);
|
||||
case BALUN_NEG_NODE:
|
||||
value->iValue = here->BALUNnegNode;
|
||||
return (OK);
|
||||
case BALUN_DIFF_NODE:
|
||||
value->iValue = here->BALUNdiffNode;
|
||||
return (OK);
|
||||
case BALUN_CM_NODE:
|
||||
value->iValue = here->BALUNcmNode;
|
||||
return (OK);
|
||||
case BALUN_BRPOS:
|
||||
value->iValue = here->BALUNbranchpos;
|
||||
return (OK);
|
||||
case BALUN_BRNEG:
|
||||
value->iValue = here->BALUNbranchneg;
|
||||
return (OK);
|
||||
|
||||
case BALUN_POWER :
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "BALUNask";
|
||||
strcpy(errMsg,msg);
|
||||
return(E_ASKPOWER);
|
||||
} else {
|
||||
value->rValue =
|
||||
*(ckt->CKTrhsOld + here->BALUNbranchpos) *
|
||||
(*(ckt->CKTrhsOld + here->BALUNposNode)) +
|
||||
*(ckt->CKTrhsOld + here->BALUNbranchneg) *
|
||||
(*(ckt->CKTrhsOld + here->BALUNnegNode));
|
||||
}
|
||||
return(OK);
|
||||
default:
|
||||
return (E_BADPARM);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
**********/
|
||||
|
||||
#ifndef BALUN
|
||||
#define BALUN
|
||||
|
||||
|
||||
#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 sBALUNinstance {
|
||||
|
||||
struct GENinstance gen;
|
||||
|
||||
#define BALUNmodPtr(inst) ((struct sBALUNmodel *)((inst)->gen.GENmodPtr))
|
||||
#define BALUNnextInstance(inst) ((struct sBALUNinstance *)((inst)->gen.GENnextInstance))
|
||||
#define BALUNname gen.GENname
|
||||
#define BALUNstates gen.GENstate
|
||||
|
||||
const int BALUNposNode; /* number of positive node of source */
|
||||
const int BALUNnegNode; /* number of negative node of source */
|
||||
const int BALUNcmNode; /* cm node */
|
||||
const int BALUNdiffNode; /* diff node */
|
||||
|
||||
int BALUNbranchpos; /* branch for ipos */
|
||||
int BALUNbranchneg; /* branch for ineg */
|
||||
|
||||
double *BALUNposIbrposPtr;
|
||||
double *BALUNnegIbrnegPtr;
|
||||
double *BALUNcmIbrposPtr;
|
||||
double *BALUNcmIbrnegPtr;
|
||||
double *BALUNdiffIbrposPtr;
|
||||
double *BALUNdiffIbrnegPtr;
|
||||
|
||||
double *BALUNibrposDiffPtr;
|
||||
double *BALUNibrposPosPtr;
|
||||
double *BALUNibrposNegPtr;
|
||||
|
||||
double *BALUNibrnegCmPtr;
|
||||
double *BALUNibrnegPosPtr;
|
||||
double *BALUNibrnegNegPtr;
|
||||
|
||||
|
||||
int BALUNsenParmNo; /* parameter # for sensitivity use;
|
||||
set equal to 0 if not a design parameter*/
|
||||
|
||||
} BALUNinstance ;
|
||||
|
||||
/* per model data */
|
||||
|
||||
typedef struct sBALUNmodel { /* model structure for a source */
|
||||
|
||||
struct GENmodel gen;
|
||||
|
||||
#define BALUNmodType gen.GENmodType
|
||||
#define BALUNnextModel(inst) ((struct sBALUNmodel *)((inst)->gen.GENnextModel))
|
||||
#define BALUNinstances(inst) ((BALUNinstance *)((inst)->gen.GENinstances))
|
||||
#define BALUNmodName gen.GENmodName
|
||||
|
||||
} BALUNmodel;
|
||||
|
||||
/* device parameters */
|
||||
enum {
|
||||
BALUN_POS_NODE = 1,
|
||||
BALUN_NEG_NODE,
|
||||
BALUN_DIFF_NODE,
|
||||
BALUN_CM_NODE,
|
||||
BALUN_BRPOS,
|
||||
BALUN_BRNEG,
|
||||
BALUN_POWER,
|
||||
};
|
||||
|
||||
/* model parameters */
|
||||
|
||||
/* device questions */
|
||||
enum {
|
||||
BALUN_QUEST_NONE = 201,
|
||||
};
|
||||
|
||||
/* model questions */
|
||||
|
||||
#include "balunext.h"
|
||||
|
||||
#endif /*BALUN*/
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
**********/
|
||||
|
||||
extern int BALUNask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int BALUNload(GENmodel*,CKTcircuit*);
|
||||
extern int BALUNparam(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int BALUNpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
||||
extern int BALUNsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int BALUNunsetup(GENmodel*,CKTcircuit*);
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#include "ngspice/config.h"
|
||||
|
||||
#include "ngspice/devdefs.h"
|
||||
|
||||
#include "balunitf.h"
|
||||
#include "balunext.h"
|
||||
#include "baluninit.h"
|
||||
|
||||
|
||||
SPICEdev BALUNinfo = {
|
||||
.DEVpublic = {
|
||||
.name = "BALUN",
|
||||
.description = "Ideal balun",
|
||||
.terms = &BALUNnSize,
|
||||
.numNames = &BALUNnSize,
|
||||
.termNames = BALUNnames,
|
||||
.numInstanceParms = &BALUNpTSize,
|
||||
.instanceParms = BALUNpTable,
|
||||
.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 = BALUNparam,
|
||||
.DEVmodParam = NULL,
|
||||
.DEVload = BALUNload,
|
||||
.DEVsetup = BALUNsetup,
|
||||
.DEVunsetup = BALUNunsetup,
|
||||
.DEVpzSetup = BALUNsetup,
|
||||
.DEVtemperature = NULL,
|
||||
.DEVtrunc = NULL,
|
||||
.DEVfindBranch = NULL,
|
||||
.DEVacLoad = BALUNload,
|
||||
.DEVaccept = NULL,
|
||||
.DEVdestroy = NULL,
|
||||
.DEVmodDelete = NULL,
|
||||
.DEVdelete = NULL,
|
||||
.DEVsetic = NULL,
|
||||
.DEVask = BALUNask,
|
||||
.DEVmodAsk = NULL,
|
||||
.DEVpzLoad = BALUNpzLoad,
|
||||
.DEVconvTest = NULL,
|
||||
.DEVsenSetup = NULL,
|
||||
.DEVsenLoad = NULL,
|
||||
.DEVsenUpdate = NULL,
|
||||
.DEVsenAcLoad = NULL,
|
||||
.DEVsenPrint = NULL,
|
||||
.DEVsenTrunc = NULL,
|
||||
.DEVdisto = NULL,
|
||||
.DEVnoise = NULL,
|
||||
.DEVsoaCheck = NULL,
|
||||
.DEVinstSize = &BALUNiSize,
|
||||
.DEVmodSize = &BALUNmSize,
|
||||
|
||||
#ifdef CIDER
|
||||
.DEVdump = NULL,
|
||||
.DEVacct = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
SPICEdev *
|
||||
get_balun_info(void)
|
||||
{
|
||||
return &BALUNinfo;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef _VCVSINIT_H
|
||||
#define _VCVSINIT_H
|
||||
|
||||
extern IFparm BALUNpTable[ ];
|
||||
extern char *BALUNnames[ ];
|
||||
extern int BALUNpTSize;
|
||||
extern int BALUNnSize;
|
||||
extern int BALUNiSize;
|
||||
extern int BALUNmSize;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
**********/
|
||||
#ifndef DEV_BALUN
|
||||
#define DEV_BALUN
|
||||
|
||||
SPICEdev *get_balun_info(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/**********
|
||||
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 "balundefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
BALUNload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* actually load the current voltage value into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
{
|
||||
BALUNmodel *model = (BALUNmodel *)inModel;
|
||||
BALUNinstance *here;
|
||||
|
||||
NG_IGNORE(ckt);
|
||||
|
||||
/* loop through all the voltage source models */
|
||||
for( ; model != NULL; model = BALUNnextModel(model)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = BALUNinstances(model); here != NULL ;
|
||||
here=BALUNnextInstance(here)) {
|
||||
|
||||
/* currents to and from nodes */
|
||||
*(here->BALUNposIbrposPtr) -= 1.0;
|
||||
*(here->BALUNnegIbrnegPtr) -= 1.0;
|
||||
/* icm = ipos + ineg */
|
||||
*(here->BALUNcmIbrposPtr) += 1.0;
|
||||
*(here->BALUNcmIbrnegPtr) += 1.0;
|
||||
/* idiff = (ipos - ineg)/2 */
|
||||
*(here->BALUNdiffIbrposPtr) += 0.5;
|
||||
*(here->BALUNdiffIbrnegPtr) -= 0.5;
|
||||
|
||||
/* vd = vp - vn */
|
||||
*(here->BALUNibrposDiffPtr) += 1.0 ;
|
||||
*(here->BALUNibrposPosPtr) -= 1.0 ;
|
||||
*(here->BALUNibrposNegPtr) += 1.0 ;
|
||||
|
||||
/* vc = (vp + vn)/2 */
|
||||
*(here->BALUNibrnegCmPtr) += 1.0 ;
|
||||
*(here->BALUNibrnegPosPtr) -= 0.5 ;
|
||||
*(here->BALUNibrnegNegPtr) -= 0.5 ;
|
||||
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/**********
|
||||
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 "balundefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
BALUNparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
||||
{
|
||||
BALUNinstance *here = (BALUNinstance *)inst;
|
||||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(param) {
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**********
|
||||
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 "balundefs.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
BALUNpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
||||
/* actually load the current voltage value into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
{
|
||||
BALUNmodel *model = (BALUNmodel *)inModel;
|
||||
BALUNinstance *here;
|
||||
|
||||
NG_IGNORE(s);
|
||||
NG_IGNORE(ckt);
|
||||
|
||||
/* loop through all the voltage source models */
|
||||
for( ; model != NULL; model = BALUNnextModel(model)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = BALUNinstances(model); here != NULL ;
|
||||
here=BALUNnextInstance(here)) {
|
||||
|
||||
/* currents to and from nodes */
|
||||
*(here->BALUNposIbrposPtr) -= 1.0;
|
||||
*(here->BALUNnegIbrnegPtr) -= 1.0;
|
||||
/* icm = ipos + ineg */
|
||||
*(here->BALUNcmIbrposPtr) += 1.0;
|
||||
*(here->BALUNcmIbrnegPtr) += 1.0;
|
||||
/* idiff = (ipos - ineg)/2 */
|
||||
*(here->BALUNdiffIbrposPtr) += 0.5;
|
||||
*(here->BALUNdiffIbrnegPtr) -= 0.5;
|
||||
|
||||
/* vd = vp - vn */
|
||||
*(here->BALUNibrposDiffPtr) += 1.0 ;
|
||||
*(here->BALUNibrposPosPtr) -= 1.0 ;
|
||||
*(here->BALUNibrposNegPtr) += 1.0 ;
|
||||
|
||||
/* vc = (vp + vn)/2 */
|
||||
*(here->BALUNibrnegCmPtr) += 1.0 ;
|
||||
*(here->BALUNibrnegPosPtr) -= 0.5 ;
|
||||
*(here->BALUNibrnegNegPtr) -= 0.5 ;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
**********/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/smpdefs.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
#include "balundefs.h"
|
||||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
BALUNsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||
{
|
||||
BALUNmodel *model = (BALUNmodel *)inModel;
|
||||
BALUNinstance *here;
|
||||
int error;
|
||||
CKTnode *tmp;
|
||||
|
||||
NG_IGNORE(states);
|
||||
|
||||
/* loop through all the voltage source models */
|
||||
for( ; model != NULL; model = BALUNnextModel(model)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = BALUNinstances(model); here != NULL ;
|
||||
here=BALUNnextInstance(here)) {
|
||||
|
||||
if(here->BALUNposNode == here->BALUNnegNode) {
|
||||
SPfrontEnd->IFerrorf (ERR_FATAL,
|
||||
"instance %s is a shorted BALUN", here->BALUNname);
|
||||
return(E_UNSUPP);
|
||||
}
|
||||
|
||||
if(here->BALUNcmNode == here->BALUNdiffNode) {
|
||||
SPfrontEnd->IFerrorf (ERR_FATAL,
|
||||
"instance %s is a shorted BALUN", here->BALUNname);
|
||||
return(E_UNSUPP);
|
||||
}
|
||||
|
||||
if(here->BALUNbranchpos == 0) {
|
||||
error = CKTmkCur(ckt,&tmp,here->BALUNname,"branchpos");
|
||||
if(error) return(error);
|
||||
here->BALUNbranchpos = tmp->number;
|
||||
}
|
||||
if(here->BALUNbranchneg == 0) {
|
||||
error = CKTmkCur(ckt,&tmp,here->BALUNname,"branchneg");
|
||||
if(error) return(error);
|
||||
here->BALUNbranchneg = 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(BALUNposIbrposPtr, BALUNposNode, BALUNbranchpos);
|
||||
TSTALLOC(BALUNnegIbrnegPtr, BALUNnegNode, BALUNbranchneg);
|
||||
TSTALLOC(BALUNcmIbrposPtr, BALUNcmNode, BALUNbranchpos);
|
||||
TSTALLOC(BALUNcmIbrnegPtr, BALUNcmNode, BALUNbranchneg);
|
||||
TSTALLOC(BALUNdiffIbrposPtr, BALUNdiffNode, BALUNbranchpos);
|
||||
TSTALLOC(BALUNdiffIbrnegPtr, BALUNdiffNode, BALUNbranchneg);
|
||||
|
||||
TSTALLOC(BALUNibrposDiffPtr, BALUNbranchpos, BALUNdiffNode);
|
||||
TSTALLOC(BALUNibrposPosPtr, BALUNbranchpos, BALUNposNode);
|
||||
TSTALLOC(BALUNibrposNegPtr, BALUNbranchpos, BALUNnegNode);
|
||||
|
||||
TSTALLOC(BALUNibrnegCmPtr, BALUNbranchneg, BALUNcmNode);
|
||||
TSTALLOC(BALUNibrnegPosPtr, BALUNbranchneg, BALUNposNode);
|
||||
TSTALLOC(BALUNibrnegNegPtr, BALUNbranchneg, BALUNnegNode);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
||||
int
|
||||
BALUNunsetup(GENmodel *inModel, CKTcircuit *ckt)
|
||||
{
|
||||
BALUNmodel *model;
|
||||
BALUNinstance *here;
|
||||
|
||||
for (model = (BALUNmodel *)inModel; model != NULL;
|
||||
model = BALUNnextModel(model))
|
||||
{
|
||||
for (here = BALUNinstances(model); here != NULL;
|
||||
here=BALUNnextInstance(here))
|
||||
{
|
||||
if (here->BALUNbranchpos > 0)
|
||||
CKTdltNNum(ckt, here->BALUNbranchpos);
|
||||
here->BALUNbranchpos = 0;
|
||||
if (here->BALUNbranchneg > 0)
|
||||
CKTdltNNum(ckt, here->BALUNbranchneg);
|
||||
here->BALUNbranchneg = 0;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -142,6 +142,9 @@ extern struct coreInfo_t coreInfo; /* cmexport.c */
|
|||
#ifdef NDEV
|
||||
#include "ndev/ndevitf.h"
|
||||
#endif
|
||||
#ifdef WITH_LOOPANA
|
||||
#include "balun/balunitf.h"
|
||||
#endif
|
||||
|
||||
static SPICEdev *(*static_devices[])(void) = {
|
||||
/* URC device MUST precede both resistors and capacitors */
|
||||
|
|
@ -217,6 +220,10 @@ static SPICEdev *(*static_devices[])(void) = {
|
|||
get_ndev_info,
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
get_balun_info,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
static int DEVNUM = NUMELEMS(static_devices);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ libinp_la_SOURCES = \
|
|||
sperror.c \
|
||||
inpxx.h
|
||||
|
||||
if LOOPANA_WANTED
|
||||
libinp_la_SOURCES += inp2gen.c
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend
|
||||
AM_CFLAGS = $(STATIC)
|
||||
AM_YFLAGS = -d
|
||||
|
|
|
|||
|
|
@ -0,0 +1,155 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2020 Florian Ballenegger, Anamosic Ballenegger Design
|
||||
*******************************************************************************
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ngspice/ifsim.h"
|
||||
#include "ngspice/inpdefs.h"
|
||||
#include "ngspice/inpmacs.h"
|
||||
#include "ngspice/fteext.h"
|
||||
#include "inpxx.h"
|
||||
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
||||
|
||||
int INP2gentype(char* line)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
for(i=0;c=line[i];i++)
|
||||
if(!isblank(c))
|
||||
break;
|
||||
if(line[i]=='.') return 0;
|
||||
if(line[i]=='*') return 0;
|
||||
if(line[i]=='$') return 0;
|
||||
|
||||
for(;c=line[i];i++)
|
||||
{
|
||||
if(isblank(c))
|
||||
return 0;
|
||||
if(c=='#')
|
||||
return i+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int INP2GEN(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
||||
{
|
||||
|
||||
/* <inst>#<devtype> node1 node2 ... noden param=val */
|
||||
|
||||
int type; /* the type the model says it is */
|
||||
int idx, len;
|
||||
char *line; /* the part of the current line left to parse */
|
||||
char *name; /* a name */
|
||||
CKTnode *node; /* a node pointer */
|
||||
int error; /* error code temporary */
|
||||
GENinstance *fast; /* pointer to the actual instance */
|
||||
IFvalue ptemp; /* a value structure to package resistance into */
|
||||
IFuid uid; /* uid of default model to be created */
|
||||
GENmodel* genmod;
|
||||
|
||||
line = current->line;
|
||||
idx=INP2gentype(line);
|
||||
if(!idx)
|
||||
return 0; /* not a new generic instance format */
|
||||
|
||||
/* calc length of device type string */
|
||||
for(len=0;line[idx+len];len++)
|
||||
if(isblank(line[idx+len]))
|
||||
break;
|
||||
if(len==0) return 0;
|
||||
|
||||
/* look if find this device */
|
||||
for (type = 0; type < ft_sim->numDevices; type++) {
|
||||
if(ft_sim->devices[type])
|
||||
if(strlen(ft_sim->devices[type]->name)==len)
|
||||
if(strncasecmp(&line[idx], ft_sim->devices[type]->name, len)==0)
|
||||
break;
|
||||
}
|
||||
if(type==ft_sim->numDevices) { /* not found */
|
||||
LITERR("Device type not supported by this binary\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (1) {
|
||||
/* create default model */
|
||||
name = dup_string(ft_sim->devices[type]->name,len);
|
||||
IFnewUid(ckt, &uid, NULL, name, UID_MODEL, NULL);
|
||||
genmod = ft_sim->findModel(ckt, uid);
|
||||
if(!genmod)
|
||||
IFC(newModel, (ckt, type, &genmod, uid));
|
||||
}
|
||||
name = dup_string(line, idx-1);
|
||||
IFC(newInstance, (ckt, genmod, &fast, name));
|
||||
if(0) printf("Instance name: %s\n", name);
|
||||
|
||||
line = &line[idx+len];
|
||||
|
||||
/* parse node connections and bind nodes */
|
||||
for(idx=0;idx<*(ft_sim->devices[type]->terms);idx++)
|
||||
{
|
||||
INPgetNetTok(&line, &name, 1);
|
||||
INPtermInsert(ckt, &name, tab, &node);
|
||||
IFC(bindNode, (ckt, fast, idx+1, node));
|
||||
if(0) printf("bind term %d to %s\n", idx, node->name);
|
||||
}
|
||||
|
||||
/* parse parameters and assign parameters */
|
||||
while(*line)
|
||||
{
|
||||
INPgetTok(&line, &name, 0);
|
||||
if(*line!='=') {
|
||||
printf("Expect param=val format for %s, got %c\n", name, *line);
|
||||
LITERR("Expect param=val format\n");
|
||||
return(0);
|
||||
}
|
||||
line++; /* skip '=' */
|
||||
for(idx=0;idx<*(ft_sim->devices[type]->numInstanceParms);idx++)
|
||||
if(strcmp(name, ft_sim->devices[type]->instanceParms[idx].keyword)==0)
|
||||
break;
|
||||
tfree(name); /* don't need it anymore, we still know the keyword */
|
||||
if(idx<*(ft_sim->devices[type]->numInstanceParms))
|
||||
{ /* found */
|
||||
int dataType;
|
||||
IFvalue *parm;
|
||||
dataType = ft_sim->devices[type]->instanceParms[idx].dataType;
|
||||
parm = INPgetValue(ckt, &line, dataType, tab);
|
||||
GCA(INPpName, (ft_sim->devices[type]->instanceParms[idx].keyword, parm, ckt, type, fast));
|
||||
if(0) printf("Assign %s\n", ft_sim->devices[type]->instanceParms[idx].keyword);
|
||||
}
|
||||
else
|
||||
{
|
||||
LITERR("Unrecognized parameter\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,22 @@ Author: 1985 Thomas L. Quarles
|
|||
/* gtri - end - wbk - 11/9/90 */
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
/* detect A<instname>#<devtype> */
|
||||
int INPlookahead(char* line)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
for(i=1;c=line[i];i++)
|
||||
{
|
||||
if(isblank(c))
|
||||
return 0;
|
||||
if(c=='#')
|
||||
return i+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* uncomment to trace in this file */
|
||||
/*#define TRACE*/
|
||||
|
|
@ -90,7 +106,11 @@ void INPpas2(CKTcircuit *ckt, struct card *data, INPtables * tab, TSKtask *task)
|
|||
c = *(current->line);
|
||||
if(islower_c(c))
|
||||
c = toupper_c(c);
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
if(INP2GEN(ckt, tab, current))
|
||||
; /* well done */
|
||||
else
|
||||
#endif
|
||||
switch (c) {
|
||||
|
||||
case ' ':
|
||||
|
|
@ -98,11 +118,8 @@ void INPpas2(CKTcircuit *ckt, struct card *data, INPtables * tab, TSKtask *task)
|
|||
case '\t':
|
||||
/* blank line (tab leading) */
|
||||
break;
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - add - wbk - 10/23/90 - add case for 'A' devices */
|
||||
|
||||
case 'A': /* Aname <cm connections> <mname> */
|
||||
case 'A':
|
||||
MIF_INP2A(ckt, tab, current);
|
||||
ckt->CKTadevFlag = 1; /* an 'A' device is requested */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ void INP2W(CKTcircuit *ckt, INPtables *tab, struct card *current);
|
|||
void INP2Y(CKTcircuit *ckt, INPtables *tab, struct card *current);
|
||||
void INP2Z(CKTcircuit *ckt, INPtables *tab, struct card *current);
|
||||
|
||||
#ifdef WITH_LOOPANA
|
||||
int INP2GEN(CKTcircuit *ckt, INPtables * tab, struct card *current);
|
||||
#endif
|
||||
|
||||
/* ptfuncs.c */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue