CIDER integration. Code updated for cider support.
This commit is contained in:
parent
ae57bef3b4
commit
8d893d890a
|
|
@ -1,10 +1,11 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
## PN: remember to add CIDERSCRIPTS
|
||||
|
||||
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@
|
||||
SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@ @CIDERDIR@
|
||||
|
||||
bin_PROGRAMS = ngspice ngnutmeg nghelp ngsconvert ngproc2mod ngmultidec makeidx
|
||||
|
||||
EXTRA_DIST = ngspice.txt ngspice.idx spinit setplot spectrum
|
||||
EXTRA_DIST = ngspice.txt ngspice.idx spinit setplot spectrum @CIDERSCRIPTS@
|
||||
|
||||
helpdatadir = $(pkgdatadir)/helpdir
|
||||
|
||||
|
|
@ -12,19 +13,23 @@ helpdata_DATA = ngspice.idx ngspice.txt
|
|||
|
||||
initdatadir = $(pkgdatadir)/scripts
|
||||
|
||||
initdata_DATA = spinit setplot spectrum
|
||||
initdata_DATA = spinit setplot spectrum @CIDERSCRIPTS@
|
||||
|
||||
|
||||
DYNAMIC_DEVICELIBS = \
|
||||
spicelib/devices/asrc/libasrc.a \
|
||||
spicelib/devices/bjt/libbjt.a \
|
||||
spicelib/devices/bjt2/libbjt2.a \
|
||||
spicelib/devices/bsim1/libbsim1.a \
|
||||
spicelib/devices/bsim2/libbsim2.a \
|
||||
spicelib/devices/bsim3/libbsim3.a \
|
||||
spicelib/devices/bsim3v0/libbsim3v0.a \
|
||||
spicelib/devices/bsim3v1/libbsim3v1.a \
|
||||
spicelib/devices/bsim3v2/libbsim3v2.a \
|
||||
spicelib/devices/bsim3v1s/libbsim3v1s.a \
|
||||
spicelib/devices/bsim3v1a/libbsim3v1a.a \
|
||||
spicelib/devices/bsim4/libbsim4.a \
|
||||
spicelib/devices/cap/libcap.a \
|
||||
spicelib/devices/libbsim3soi.a \
|
||||
spicelib/devices/bsim3soi_pd/libbsim3soipd.a \
|
||||
spicelib/devices/bsim3soi_fd/libbsim3soifd.a \
|
||||
spicelib/devices/bsim3soi_dd/libbsim3soidd.a \
|
||||
|
|
@ -39,6 +44,7 @@ DYNAMIC_DEVICELIBS = \
|
|||
spicelib/devices/isrc/libisrc.a \
|
||||
spicelib/devices/hfet1/libhfet.a \
|
||||
spicelib/devices/hfet2/libhfet2.a \
|
||||
spicelib/devices/hisim/libhisim.a \
|
||||
spicelib/devices/jfet/libjfet.a \
|
||||
spicelib/devices/jfet2/libjfet2.a \
|
||||
spicelib/devices/ltra/libltra.a \
|
||||
|
|
@ -57,17 +63,10 @@ DYNAMIC_DEVICELIBS = \
|
|||
spicelib/devices/urc/liburc.a \
|
||||
spicelib/devices/vccs/libvccs.a \
|
||||
spicelib/devices/vcvs/libvcvs.a \
|
||||
spicelib/devices/vsrc/libvsrc.a
|
||||
|
||||
|
||||
|
||||
## ----- Note that I moved this stuff to here because it was causing automake
|
||||
## to choke when it was in the DYNAMIC_DEVICELIBS list above -----
|
||||
## This lib deleted from DYNAMIC_DEVICELIBS by sdb 'cause there's no source for it.
|
||||
## spicelib/devices/bjt2/libbjt2.a \
|
||||
## poly added to dynamic libs by SDB on 6.1.2003
|
||||
## xspice/icm/poly/libpoly.a
|
||||
|
||||
spicelib/devices/vsrc/libvsrc.a \
|
||||
@NUMDEV@
|
||||
|
||||
|
||||
## Build ngspice first:
|
||||
|
||||
ngspice_SOURCES = \
|
||||
|
|
@ -88,10 +87,12 @@ ngspice_LDADD = \
|
|||
spicelib/devices/libdev.a \
|
||||
@XSPICELIB2@ \
|
||||
frontend/parser/libparser.a \
|
||||
@CIDERSIM@
|
||||
frontend/help/libhlp.a \
|
||||
spicelib/parser/libinp.a \
|
||||
maths/deriv/libderiv.a \
|
||||
maths/cmaths/libcmaths.a \
|
||||
maths/misc/libmathsmisc.a \
|
||||
maths/poly/libpoly.a \
|
||||
maths/ni/libni.a \
|
||||
maths/sparse/libsparse.a \
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ ft_ckspace(void)
|
|||
static void
|
||||
printres(char *name)
|
||||
{
|
||||
#ifdef CIDER
|
||||
char *paramname = NULL;
|
||||
#endif
|
||||
bool yy = FALSE;
|
||||
static long lastsec = 0, lastusec = 0;
|
||||
struct variable *v;
|
||||
|
|
@ -314,11 +317,24 @@ printres(char *name)
|
|||
|
||||
/* Now get all the spice resource stuff. */
|
||||
if (ft_curckt && ft_curckt->ci_ckt) {
|
||||
|
||||
#ifdef CIDER
|
||||
/* begin cider integration */
|
||||
if (!name || eq(name, "circuit") || eq(name, "task")) {
|
||||
paramname = NULL;
|
||||
} else {
|
||||
paramname = name;
|
||||
}
|
||||
v = if_getstat(ft_curckt->ci_ckt, paramname);
|
||||
if (paramname && v) {
|
||||
/* end cider integration */
|
||||
#else /* ~CIDER */
|
||||
if (name && eq(name, "task"))
|
||||
v = if_getstat(ft_curckt->ci_ckt, NULL);
|
||||
else
|
||||
v = if_getstat(ft_curckt->ci_ckt, name);
|
||||
if (name && v) {
|
||||
#endif
|
||||
fprintf(cp_out, "%s = ", v->va_name);
|
||||
wl_print(cp_varwl(v), cp_out);
|
||||
(void) putc('\n', cp_out);
|
||||
|
|
@ -333,6 +349,17 @@ printres(char *name)
|
|||
}
|
||||
yy = TRUE;
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
/* begin cider integration */
|
||||
/* Now print out interesting stuff about numerical devices. */
|
||||
if (!name || eq(name, "devices")) {
|
||||
(void) NDEVacct(ft_curckt->ci_ckt, cp_out);
|
||||
yy = TRUE;
|
||||
}
|
||||
/* end cider integration */
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (!yy) {
|
||||
|
|
|
|||
|
|
@ -1,60 +1,110 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_HEADERS = \
|
||||
acdefs.h \
|
||||
bool.h \
|
||||
cktdefs.h \
|
||||
complex.h \
|
||||
const.h \
|
||||
cpdefs.h \
|
||||
cpextern.h \
|
||||
cpstd.h \
|
||||
defines.h \
|
||||
devdefs.h \
|
||||
dgen.h \
|
||||
distodef.h \
|
||||
dvec.h \
|
||||
ftedbgra.h \
|
||||
ftedebug.h \
|
||||
ftedefs.h \
|
||||
ftedev.h \
|
||||
fteext.h \
|
||||
fteinp.h \
|
||||
fteinput.h \
|
||||
fteparse.h \
|
||||
gendefs.h \
|
||||
graph.h \
|
||||
grid.h \
|
||||
hlpdefs.h \
|
||||
iferrmsg.h \
|
||||
ifsim.h \
|
||||
inpdefs.h \
|
||||
inpmacs.h \
|
||||
inpptree.h \
|
||||
jobdefs.h \
|
||||
macros.h \
|
||||
memory.h \
|
||||
missing_math.h \
|
||||
ngspice.h \
|
||||
noisedef.h \
|
||||
opdefs.h \
|
||||
optdefs.h \
|
||||
plot.h \
|
||||
pnode.h \
|
||||
pzdefs.h \
|
||||
sen2defs.h \
|
||||
sensdefs.h \
|
||||
sensgen.h \
|
||||
sim.h \
|
||||
smpdefs.h \
|
||||
sperror.h \
|
||||
spmatrix.h \
|
||||
suffix.h \
|
||||
terminal.h \
|
||||
tfdefs.h \
|
||||
trandefs.h \
|
||||
trcvdefs.h \
|
||||
tskdefs.h \
|
||||
wordlist.h
|
||||
noinst_HEADERS = \
|
||||
acdefs.h \
|
||||
bdrydefs.h \
|
||||
bool.h \
|
||||
carddefs.h \
|
||||
ciderinp.h \
|
||||
cidersupt.h \
|
||||
cktdefs.h \
|
||||
cluster.h \
|
||||
cmconstants.h \
|
||||
cm.h \
|
||||
cmproto.h \
|
||||
cmtypes.h \
|
||||
complex.h \
|
||||
const.h \
|
||||
contdefs.h \
|
||||
cpdefs.h \
|
||||
cpextern.h \
|
||||
cpstd.h \
|
||||
defines.h \
|
||||
devdefs.h \
|
||||
dgen.h \
|
||||
distodef.h \
|
||||
dllitf.h \
|
||||
domndefs.h \
|
||||
dvec.h \
|
||||
elctdefs.h \
|
||||
enh.h \
|
||||
evt.h \
|
||||
evtproto.h \
|
||||
evtudn.h \
|
||||
ftedbgra.h \
|
||||
ftedebug.h \
|
||||
ftedefs.h \
|
||||
ftedev.h \
|
||||
fteext.h \
|
||||
fteinp.h \
|
||||
fteinput.h \
|
||||
fteparse.h \
|
||||
gendefs.h \
|
||||
gendev.h \
|
||||
graph.h \
|
||||
grid.h \
|
||||
hlpdefs.h \
|
||||
iferrmsg.h \
|
||||
ifsim.h \
|
||||
inpdefs.h \
|
||||
inpmacs.h \
|
||||
inpptree.h \
|
||||
ipc.h \
|
||||
ipcproto.h \
|
||||
ipctiein.h \
|
||||
jobdefs.h \
|
||||
lsort.h \
|
||||
macros.h \
|
||||
material.h \
|
||||
matldefs.h \
|
||||
memory.h \
|
||||
meshdefs.h \
|
||||
meshext.h \
|
||||
methdefs.h \
|
||||
mifcmdat.h \
|
||||
mifdefs.h \
|
||||
mif.h \
|
||||
mifparse.h \
|
||||
mifproto.h \
|
||||
miftypes.h \
|
||||
missing_math.h \
|
||||
mobdefs.h \
|
||||
modldefs.h \
|
||||
multi_line.h \
|
||||
ngspice.h \
|
||||
noisedef.h \
|
||||
numcards.h \
|
||||
numconst.h \
|
||||
numenum.h \
|
||||
numgen.h \
|
||||
numglobs.h \
|
||||
onedev.h \
|
||||
onemesh.h \
|
||||
opdefs.h \
|
||||
optdefs.h \
|
||||
optndefs.h \
|
||||
outpdefs.h \
|
||||
plot.h \
|
||||
pnode.h \
|
||||
profile.h \
|
||||
pzdefs.h \
|
||||
sen2defs.h \
|
||||
sensdefs.h \
|
||||
sensgen.h \
|
||||
sim.h \
|
||||
smpdefs.h \
|
||||
sperror.h \
|
||||
spmatrix.h \
|
||||
suffix.h \
|
||||
swec.h \
|
||||
terminal.h \
|
||||
tfdefs.h \
|
||||
trandefs.h \
|
||||
trcvdefs.h \
|
||||
tskdefs.h \
|
||||
twodev.h \
|
||||
twomesh.h \
|
||||
wordlist.h \
|
||||
wstdio.h
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
#define _BOOL_H
|
||||
|
||||
typedef unsigned char bool;
|
||||
|
||||
#define BOOLEAN int
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define NO 0
|
||||
#define YES 1
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
|
||||
|
||||
|
||||
#define MAXNUMDEVS 40 /* Max number of possible devices PN:XXX may cause toubles*/
|
||||
#define MAXNUMDEVS 64 /* Max number of possible devices PN:XXX may cause toubles*/
|
||||
extern int DEVmaxnum; /* Not sure if still used */
|
||||
#define MAXNUMDEVNODES 4 /* Max No. of nodes per device */
|
||||
/* Need to change for SOI devs ? */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,22 @@ typedef struct _complex1 complex;
|
|||
#define realpart(cval) ((struct _complex1 *) (cval))->cx_real
|
||||
#define imagpart(cval) ((struct _complex1 *) (cval))->cx_imag
|
||||
|
||||
#ifdef CIDER
|
||||
/* From Cider numcomplex.h
|
||||
pn:leave it here until I decide what to do about
|
||||
struct mosAdmittances {
|
||||
complex yIdVdb;
|
||||
complex yIdVsb;
|
||||
complex yIdVgb;
|
||||
complex yIsVdb;
|
||||
complex yIsVsb;
|
||||
complex yIsVgb;
|
||||
complex yIgVdb;
|
||||
complex yIgVsb;
|
||||
complex yIgVgb;
|
||||
};
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Each expects two arguments for each complex number - a real and an
|
||||
|
|
@ -270,6 +286,11 @@ typedef struct
|
|||
/* Macro function that returns the approx absolute value of a complex
|
||||
number. */
|
||||
#define ELEMENT_MAG(ptr) (ABS((ptr)->Real) + ABS((ptr)->Imag))
|
||||
|
||||
#define CMPLX_ASSIGN_VALUE(cnum, vReal, vImag) \
|
||||
{ (cnum).Real = vReal; \
|
||||
(cnum).Imag = vImag; \
|
||||
}
|
||||
|
||||
/* Complex assignment statements. */
|
||||
#define CMPLX_ASSIGN(to,from) \
|
||||
|
|
@ -288,12 +309,21 @@ typedef struct
|
|||
{ (to).Real = -(from).Real; \
|
||||
(to).Imag = (from).Imag; \
|
||||
}
|
||||
|
||||
#define CMPLX_CONJ(a) (a).Imag = -(a).Imag
|
||||
|
||||
#define CONJUGATE(a) (a).Imag = -(a).Imag
|
||||
|
||||
#define CMPLX_NEGATE(a) \
|
||||
{ (a).Real = -(a).Real; \
|
||||
(a).Imag = -(a).Imag; \
|
||||
}
|
||||
|
||||
#define CMPLX_NEGATE_SELF(cnum) \
|
||||
{ (cnum).real = -(cnum).Real; \
|
||||
(cnum).imag = -(cnum).Imag; \
|
||||
}
|
||||
|
||||
/* Macro that returns the approx magnitude (L-1 norm) of a complex number. */
|
||||
#define CMPLX_1_NORM(a) (ABS((a).Real) + ABS((a).Imag))
|
||||
|
||||
|
|
@ -309,6 +339,11 @@ typedef struct
|
|||
(to).Imag = (from_a).Imag + (from_b).Imag; \
|
||||
}
|
||||
|
||||
/* Macro function that performs addition of a complex and a scalar. */
|
||||
#define CMPLX_ADD_SELF_SCALAR(cnum, scalar) \
|
||||
{ (cnum).Real += scalar; \
|
||||
}
|
||||
|
||||
/* Macro function that performs complex subtraction. */
|
||||
#define CMPLX_SUBT(to,from_a,from_b) \
|
||||
{ (to).Real = (from_a).Real - (from_b).Real; \
|
||||
|
|
@ -326,7 +361,7 @@ typedef struct
|
|||
{ (to).Real -= (from).Real; \
|
||||
(to).Imag -= (from).Imag; \
|
||||
}
|
||||
|
||||
|
||||
/* Macro function that multiplies a complex number by a scalar. */
|
||||
#define SCLR_MULT(to,sclr,cmplx) \
|
||||
{ (to).Real = (sclr) * (cmplx).Real; \
|
||||
|
|
@ -339,6 +374,33 @@ typedef struct
|
|||
(to).Imag *= (sclr); \
|
||||
}
|
||||
|
||||
/* Macro function that multiplies two complex numbers. */
|
||||
#define CMPLX_MULT(to,from_a,from_b) \
|
||||
{ (to).real = (from_a).Real * (from_b).Real - \
|
||||
(from_a).Imag * (from_b).Imag; \
|
||||
(to).imag = (from_a).Real * (from_b).Imag + \
|
||||
(from_a).Imag * (from_b).Real; \
|
||||
}
|
||||
|
||||
/* Macro function that multiplies a complex number and a scalar. */
|
||||
#define CMPLX_MULT_SCALAR(to,from, scalar) \
|
||||
{ (to).Real = (from).Real * scalar; \
|
||||
(to).Imag = (from).Imag * scalar; \
|
||||
}
|
||||
|
||||
/* Macro function that implements *= for a complex and a scalar number. */
|
||||
|
||||
#define CMPLX_MULT_SELF_SCALAR(cnum, scalar) \
|
||||
{ (cnum).Real *= scalar; \
|
||||
(cnum).Imag *= scalar; \
|
||||
}
|
||||
|
||||
/* Macro function that multiply-assigns a complex number by a scalar. */
|
||||
#define SCLR_MULT_ASSIGN(to,sclr) \
|
||||
{ (to).Real *= (sclr); \
|
||||
(to).Imag *= (sclr); \
|
||||
}
|
||||
|
||||
/* Macro function that multiplies two complex numbers. */
|
||||
#define CMPLX_MULT(to,from_a,from_b) \
|
||||
{ (to).Real = (from_a).Real * (from_b).Real - \
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
|
||||
#define HAS_ASCII
|
||||
#define HAS_TTY_
|
||||
#define HAS_TIME_
|
||||
#define HAS_TIME_H
|
||||
#define HAS_RLIMIT_
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,19 @@ void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
|
|||
double,double);
|
||||
double DEVpred(CKTcircuit*,int);
|
||||
|
||||
#ifdef CIDER
|
||||
/* Cider integration */
|
||||
double limitResistorVoltage( double, double, int * );
|
||||
double limitJunctionVoltage( double, double, int * );
|
||||
double limitVbe( double, double, int * );
|
||||
double limitVce( double, double, int * );
|
||||
double limitVgb( double, double, int * );
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct SPICEdev {
|
||||
IFdevice DEVpublic;
|
||||
|
||||
|
|
@ -80,6 +93,13 @@ typedef struct SPICEdev {
|
|||
/* procedure to do distortion operations */
|
||||
int (*DEVnoise)(int, int, GENmodel*,CKTcircuit*, Ndata *, double *);
|
||||
/* noise routine */
|
||||
#ifdef CIDER
|
||||
void (*DEVdump)(GENmodel *, CKTcircuit *);
|
||||
void (*DEVacct)(GENmodel *, CKTcircuit *, FILE *);
|
||||
/* routines to report device internals
|
||||
* now used only by cider numerical devices
|
||||
*/
|
||||
#endif
|
||||
int *DEVinstSize; /* size of an instance */
|
||||
int *DEVmodSize; /* size of a model */
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#define NUMELEMS(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
|
||||
|
||||
/* String macros */
|
||||
|
||||
#define eq(a,b) (!strcmp((a), (b)))
|
||||
#define eqc(a,b) (cieq((a), (b)))
|
||||
#define isalphanum(c) (isalpha(c) || isdigit(c))
|
||||
|
|
@ -22,10 +24,17 @@
|
|||
((c) <= 'F')) ? ((c) - 'A' + 10) : 0)))
|
||||
|
||||
|
||||
/* Mathematical macros */
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define ABS(a) ((a) < 0.0 ? -(a) : (a))
|
||||
#define SGN(a) ((a) < 0.0 ? -(1.0) : (1.0))
|
||||
#define SIGN(a,b) ( b >= 0 ? (a >= 0 ? a : - a) : (a >= 0 ? - a : a))
|
||||
|
||||
#define SWAP(type, a, b) {type swapx; swapx = a; a = b; b = swapx;}
|
||||
|
||||
|
||||
#define NIL(type) ((type *)0)
|
||||
#define ABORT() fflush(stderr);fflush(stdout);abort();
|
||||
|
||||
#define ERROR(CODE,MESSAGE) { \
|
||||
|
|
@ -60,4 +69,15 @@
|
|||
#define DEBUGMSG(testargs)
|
||||
#endif
|
||||
|
||||
/* Macro that queries the system to find the process time. */
|
||||
|
||||
#define ELAPSED_TIME( time ) \
|
||||
{ struct tms {int user, sys, cuser, csys;} buffer; \
|
||||
\
|
||||
times(&buffer); \
|
||||
time = buffer.user / 60.0; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* _MACROS_H_ */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "memory.h"
|
||||
#include "defines.h"
|
||||
#include "macros.h"
|
||||
#include "bool.h"
|
||||
#include "complex.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -110,7 +112,7 @@ struct timeb timebegin;
|
|||
#endif /* va: no index, but strchr */
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TIME_
|
||||
#ifdef HAS_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -167,4 +169,17 @@ extern char *Lib_Path;
|
|||
extern int ARCHme; /* My logical process number */
|
||||
extern int ARCHsize; /* Total number of processes */
|
||||
|
||||
#ifdef CIDER
|
||||
/* Definitions of globals for Machine Accuracy Limits
|
||||
* Imported from cider
|
||||
*/
|
||||
|
||||
extern double BMin; /* lower limit for B(x) */
|
||||
extern double BMax; /* upper limit for B(x) */
|
||||
extern double ExpLim; /* limit for exponential */
|
||||
extern double Accuracy; /* accuracy of the machine */
|
||||
extern double Acc, MuLim, MutLim;
|
||||
#endif /* CIDER */
|
||||
|
||||
|
||||
#endif /* NGSPICE_H_INCLUDED */
|
||||
|
|
|
|||
57
src/main.c
57
src/main.c
|
|
@ -49,6 +49,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CIDER
|
||||
#include "numenum.h"
|
||||
#endif
|
||||
|
||||
extern void DevInit(void);
|
||||
|
||||
/* Main options */
|
||||
|
|
@ -72,10 +76,57 @@ IFsimulator *ft_sim = NULL;
|
|||
int ARCHme;
|
||||
int ARCHsize;
|
||||
|
||||
#ifdef CIDER
|
||||
/* Globals definitions for Machine Accuracy Limits
|
||||
* (needed by CIDER)
|
||||
*/
|
||||
double BMin; /* lower limit for B(x) */
|
||||
double BMax; /* upper limit for B(x) */
|
||||
double ExpLim; /* limit for exponential */
|
||||
double Accuracy; /* accuracy of the machine */
|
||||
double Acc, MuLim, MutLim;
|
||||
#endif
|
||||
|
||||
char *errRtn;
|
||||
char *errMsg;
|
||||
char *cp_program;
|
||||
|
||||
#ifdef CIDER
|
||||
/* Global debug flags from CIDER, soon they will become
|
||||
* spice variables :)
|
||||
*/
|
||||
BOOLEAN ONEacDebug = FALSE;
|
||||
BOOLEAN ONEdcDebug = TRUE;
|
||||
BOOLEAN ONEtranDebug = TRUE;
|
||||
BOOLEAN ONEjacDebug = FALSE;
|
||||
|
||||
BOOLEAN TWOacDebug = FALSE;
|
||||
BOOLEAN TWOdcDebug = TRUE;
|
||||
BOOLEAN TWOtranDebug = TRUE;
|
||||
BOOLEAN TWOjacDebug = FALSE;
|
||||
|
||||
/* CIDER Global Variable Declarations */
|
||||
|
||||
char *LogFileName = "cider.log"; /* This will go somewhere else */
|
||||
|
||||
int BandGapNarrowing;
|
||||
int TempDepMobility, ConcDepMobility, FieldDepMobility, TransDepMobility;
|
||||
int SurfaceMobility, MatchingMobility, MobDeriv;
|
||||
int CCScattering;
|
||||
int Srh, Auger, ConcDepLifetime, AvalancheGen;
|
||||
int FreezeOut = FALSE;
|
||||
int OneCarrier;
|
||||
|
||||
int MaxIterations = 100;
|
||||
int AcAnalysisMethod = DIRECT;
|
||||
|
||||
double Temp, RelTemp, Vt;
|
||||
double RefPsi;/* potential at Infinity */
|
||||
double EpsNorm, VNorm, NNorm, LNorm, TNorm, JNorm, GNorm, ENorm;
|
||||
|
||||
/* end cider globals */
|
||||
#endif /* CIDER */
|
||||
|
||||
struct variable *(*if_getparam)( );
|
||||
|
||||
|
||||
|
|
@ -225,6 +276,12 @@ int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
|
|||
SIMinfo.analyses = (IFanalysis **)spice_analysis_ptr(); /* va: we recast, because we use
|
||||
* only the public part
|
||||
*/
|
||||
|
||||
#ifdef CIDER
|
||||
/* Evaluates limits of machine accuracy for CIDER */
|
||||
evalAccLimits();
|
||||
#endif /* CIDER */
|
||||
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
SPfrontEnd = frontEnd;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Process this file with automake
|
||||
|
||||
SUBDIRS = cmaths ni sparse poly deriv
|
||||
SUBDIRS = cmaths ni sparse poly deriv misc
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -315,8 +315,8 @@ cx_exp(void *data, short int type, int length, int *newlength, short int *newtyp
|
|||
void *
|
||||
cx_sqrt(void *data, short int type, int length, int *newlength, short int *newtype)
|
||||
{
|
||||
double *d;
|
||||
complex *c;
|
||||
double *d = NULL;
|
||||
complex *c = NULL;
|
||||
double *dd = (double *) data;
|
||||
complex *cc = (complex *) data;
|
||||
int i, cres = (type == VF_REAL) ? 0 : 1;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <memory.h>
|
||||
#include <dvec.h>
|
||||
#include <complex.h>
|
||||
#include <defines.h>
|
||||
|
||||
#include "cmath.h"
|
||||
#include "cmath1.h"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Author: 1985 Thomas L. Quarles
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "nidest.h"
|
||||
|
||||
|
|
@ -20,7 +19,7 @@ NIdestroy(register CKTcircuit *ckt)
|
|||
{
|
||||
if (ckt->CKTmatrix)
|
||||
SMPdestroy(ckt->CKTmatrix);
|
||||
ckt->CKTmatrix = 0;
|
||||
ckt->CKTmatrix = NULL;
|
||||
if(ckt->CKTrhs) FREE(ckt->CKTrhs);
|
||||
if(ckt->CKTrhsOld) FREE(ckt->CKTrhsOld);
|
||||
if(ckt->CKTrhsSpare) FREE(ckt->CKTrhsSpare);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#ifdef PREDICTOR
|
||||
|
||||
intNIpred(register CKTcircuit * ckt);
|
||||
int NIpred(register CKTcircuit * ckt);
|
||||
|
||||
#endif /* PREDICTOR */
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ Author: 1985 Thomas L. Quarles
|
|||
|
||||
#include "ngspice.h"
|
||||
#include "cktdefs.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "sperror.h"
|
||||
#include "nireinit.h"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
|
||||
#include <config.h>
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "misc_time.h"
|
||||
|
||||
|
|
@ -90,7 +89,10 @@ void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* How many seconds have elapsed in running time. */
|
||||
/*
|
||||
* How many seconds have elapsed in running time.
|
||||
* This is the routine called in IFseconds
|
||||
*/
|
||||
|
||||
double
|
||||
seconds(void)
|
||||
|
|
|
|||
|
|
@ -131,6 +131,69 @@ strtolower(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
/*
|
||||
* Imported from cider file support/strmatch.c
|
||||
* Original copyright notice:
|
||||
* Author: 1991 David A. Gates, U. C. Berkeley CAD Group
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Case-insensitive test of whether p is a prefix of s and at least the
|
||||
* first n characters are the same
|
||||
*/
|
||||
|
||||
int
|
||||
cinprefix(p, s, n)
|
||||
register char *p, *s;
|
||||
register int n;
|
||||
{
|
||||
if (!p || !s) return( 0 );
|
||||
|
||||
while (*p) {
|
||||
if ((isupper(*p) ? tolower(*p) : *p) != (isupper(*s) ? tolower(*s) : *s))
|
||||
return( 0 );
|
||||
p++;
|
||||
s++;
|
||||
n--;
|
||||
}
|
||||
if (n > 0)
|
||||
return( 0 );
|
||||
else
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Case-insensitive match of prefix string p against string s
|
||||
* returns the number of matching characters
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
cimatch(p, s)
|
||||
register char *p, *s;
|
||||
{
|
||||
register int n = 0;
|
||||
|
||||
if (!p || !s) return( 0 );
|
||||
|
||||
while (*p) {
|
||||
if ((isupper(*p) ? tolower(*p) : *p) != (isupper(*s) ? tolower(*s) : *s))
|
||||
return( n );
|
||||
p++;
|
||||
s++;
|
||||
n++;
|
||||
}
|
||||
return( n );
|
||||
}
|
||||
|
||||
#endif /* CIDER */
|
||||
|
||||
|
||||
|
||||
|
||||
char *
|
||||
gettok(char **s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,13 @@ int ciprefix(register char *p, register char *s);
|
|||
void strtolower(char *str);
|
||||
char * gettok(char **s);
|
||||
|
||||
#ifdef CIDER
|
||||
/* cider integration */
|
||||
|
||||
int cinprefix(register char *p, register char *s, register int n);
|
||||
int cimatch(register char *p, register char *s);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_INDEX) && !defined(HAVE_STRCHR)
|
||||
|
||||
char * index(register char *s, register char c);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
#include "suffix.h"
|
||||
|
||||
IFsimulator SIMinfo = {
|
||||
"nutmeg", /* my name */
|
||||
"ngnutmeg", /* my name */
|
||||
"data analysis and manipulation program", /* more about me */
|
||||
Spice_Version, /* my version */
|
||||
NULL, /* newCircuit function */
|
||||
|
|
@ -62,3 +62,12 @@ IFsimulator SIMinfo = {
|
|||
0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#ifdef CIDER
|
||||
/* An ugly hack */
|
||||
void
|
||||
NDEVacct(void *ckt, FILE *file)
|
||||
{
|
||||
fprintf(file, "Ouch, you have called NDEV from ngnutmeg\n");
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
#define CONFIG
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "devdefs.h"
|
||||
#include "noisedef.h"
|
||||
#include "suffix.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ Copyright 1992 Regents of the University of California. All rights reserved.
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "cktdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "sperror.h"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ Modified: 2000 AlansFixes
|
|||
|
||||
#include "ngspice.h"
|
||||
#include "cktdefs.h"
|
||||
#include <stdio.h>
|
||||
#include "sperror.h"
|
||||
#include "trandefs.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Author: 1985 Thomas L. Quarles, 1991 David A. Gates
|
||||
**********/
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Ngspice and cider integration note:
|
||||
This file must be changed to be consistent with the ngspice interface.
|
||||
The SPICEdev structure must be changed by adding a pointer to DEVdump
|
||||
and DEVacct routines (as suggested below).
|
||||
Paolo Nenzi Dec 2001
|
||||
No more sure about this notice (2003)
|
||||
*/
|
||||
|
||||
/* CKTdump(ckt)
|
||||
|
|
@ -10,20 +18,85 @@ Author: 1985 Thomas L. Quarles
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
|
||||
#ifdef CIDER
|
||||
/* Begin cider integration */
|
||||
#include "gendefs.h"
|
||||
#include "devdefs.h"
|
||||
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* End cider integration */
|
||||
#endif
|
||||
|
||||
void
|
||||
CKTdump(CKTcircuit *ckt, double ref, void *plot)
|
||||
{
|
||||
IFvalue refData;
|
||||
IFvalue valData;
|
||||
#ifdef CIDER
|
||||
int i;
|
||||
#endif
|
||||
|
||||
refData.rValue = ref;
|
||||
valData.v.numValue = ckt->CKTmaxEqNum-1;
|
||||
valData.v.vec.rVec = ckt->CKTrhsOld+1;
|
||||
(*(SPfrontEnd->OUTpData))(plot,&refData,&valData);
|
||||
|
||||
#ifdef CIDER
|
||||
/*
|
||||
* Begin cider integration:
|
||||
* This code has been hacked changing the SPICEdev structure.
|
||||
* SPICEdev now has DEVdump and DEVacct as members. The
|
||||
* following code works for any devices but as of this
|
||||
* comment is written, only numerical devices have DEVdump
|
||||
* and DEVacct routine (NUMD, NBJT, NUMD2, NBJT2, NUMOS).
|
||||
*/
|
||||
|
||||
for (i=0; i<DEVmaxnum; i++) {
|
||||
if ( ((*DEVices[i]).DEVdump != NULL) &&
|
||||
(ckt->CKThead[i] != NULL) ){
|
||||
(*((*DEVices[i]).DEVdump))(ckt->CKThead[i],ckt);
|
||||
}
|
||||
}
|
||||
/* End cider integration */
|
||||
#endif /* CIDER */
|
||||
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
/*
|
||||
* Routine to dump statistics about numerical devices
|
||||
*
|
||||
* The following lines are historical:
|
||||
* This is inefficient, because we have to look up the indices
|
||||
* of the devices in the device table. Would be simpler if
|
||||
* DEVices had an entry for an accounting function, so that indirection
|
||||
* could be used.
|
||||
* ------------------
|
||||
* The SPICEdev structure has been hacked and now has a DEVacct entry.
|
||||
*/
|
||||
|
||||
void
|
||||
NDEVacct(CKTcircuit *ckt, FILE *file)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !ckt->CKTisSetup ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<DEVmaxnum; i++) {
|
||||
if ( ((*DEVices[i]).DEVacct != NULL) &&
|
||||
(ckt->CKThead[i] != NULL) ){
|
||||
(*((*DEVices[i]).DEVacct))(ckt->CKThead[i],ckt, file);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* End cider integration */
|
||||
#endif /* CIDER */
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ Modified: 2000 AlansFixes
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ Author: 1985 Thomas L. Quarles
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "ifsim.h"
|
||||
#include "iferrmsg.h"
|
||||
#include "smpdefs.h"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ Modified: 2000 AlansFixes
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "tskdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "cktdefs.h"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "pzdefs.h"
|
||||
#include "complex.h"
|
||||
#include "cktdefs.h"
|
||||
|
|
|
|||
|
|
@ -221,8 +221,18 @@ int sens_sens(CKTcircuit *ckt, int restart)
|
|||
/* The unknown vector of node voltages overwrites rhs */
|
||||
E = ckt->CKTrhs;
|
||||
iE = ckt->CKTirhs;
|
||||
ckt->CKTrhsOld = E;
|
||||
ckt->CKTirhsOld = iE;
|
||||
|
||||
/* The following two lines assigned a pointer to another shadowing
|
||||
* the previous definition and creating trouble when xfree() in
|
||||
* NIdestroy tried to deallocate a non malloc'ed pointer
|
||||
*
|
||||
* Original code:
|
||||
* ckt->CKTrhsOld = E;
|
||||
* ckt->CKTirhsOld = iE;
|
||||
*/
|
||||
|
||||
*ckt->CKTrhsOld = *E;
|
||||
*ckt->CKTirhsOld = *iE;
|
||||
Y = ckt->CKTmatrix;
|
||||
#ifdef ASDEBUG
|
||||
DEBUG(1) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ Author: 1985 Thomas L. Quarles
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "smpdefs.h"
|
||||
#include "cktdefs.h"
|
||||
#include "devdefs.h"
|
||||
|
|
|
|||
|
|
@ -8,13 +8,18 @@ Copyright 1991 Regents of the University of California. All rights reserved.
|
|||
#include "cktdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "sensgen.h"
|
||||
#include <stdio.h>
|
||||
|
||||
extern SPICEdev **DEVices;
|
||||
|
||||
/* XXX */
|
||||
extern char *Sfilter;
|
||||
|
||||
int set_model(sgen *);
|
||||
int set_param(sgen *);
|
||||
int set_inst(sgen *);
|
||||
int set_dev(sgen *);
|
||||
extern int sens_getp(sgen *, CKTcircuit *, IFvalue *);
|
||||
|
||||
sgen *
|
||||
sgen_init(CKTcircuit *ckt, int is_dc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ Modified: 2000 AlansFixes
|
|||
*/
|
||||
|
||||
#include "ngspice.h"
|
||||
#include <stdio.h>
|
||||
#include "const.h"
|
||||
#include "optdefs.h"
|
||||
#include "tskdefs.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Thomas L. Quarles
|
||||
Modified: 2001 Paolo Nenzi (Cider Integration)
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -50,7 +51,13 @@ void INP2D(void *ckt, INPtables * tab, card * current)
|
|||
INPinsert(&model, tab);
|
||||
current->error = INPgetMod(ckt, model, &thismodel, tab);
|
||||
if (thismodel != NULL) {
|
||||
if (mytype != thismodel->INPmodType) {
|
||||
if ((mytype != thismodel->INPmodType)
|
||||
|
||||
#ifdef CIDER
|
||||
&& (thismodel->INPmodType != INPtypelook("NUMD"))
|
||||
&& (thismodel->INPmodType != INPtypelook("NUMD2"))
|
||||
#endif
|
||||
){
|
||||
LITERR("incorrect model type");
|
||||
return;
|
||||
}
|
||||
|
|
@ -71,7 +78,16 @@ void INP2D(void *ckt, INPtables * tab, card * current)
|
|||
IFC(bindNode, (ckt, fast, 2, node2));
|
||||
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
|
||||
if (waslead) {
|
||||
|
||||
#ifdef CIDER
|
||||
if( type == INPtypelook("NUMD2") ) {
|
||||
LITERR(" error: no unlabelled parameter permitted on NUMD2\n")
|
||||
} else {
|
||||
#endif
|
||||
ptemp.rValue = leadval;
|
||||
GCA(INPpName, ("area", &ptemp, ckt, type, fast));
|
||||
}
|
||||
#ifdef CIDER
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Thomas L. Quarles
|
||||
Modified: 2001 Paolo Nenzi (Cider Integration)
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -89,13 +90,14 @@ INP2M (void *ckt, INPtables * tab, card * current)
|
|||
INPgetMod (ckt, model, &thismodel, tab); /* get pointer to the model */
|
||||
if (thismodel != NULL)
|
||||
{
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIDD"))
|
||||
)
|
||||
{
|
||||
/* if model is not variable node B3SOIPD/FD/DD model, error! */
|
||||
LITERR ("only level 9-10 B3SOI(PD | FD | DD) can have 7 nodes") return;
|
||||
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) can have 7 nodes") return;
|
||||
}
|
||||
else
|
||||
{ /* if looking at B3SOIPD/FD/DD model, allocate the 7th node */
|
||||
|
|
@ -113,14 +115,15 @@ INP2M (void *ckt, INPtables * tab, card * current)
|
|||
}
|
||||
else
|
||||
{ /* 7th token is a model - only have 6 terminal device */
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("SOI3"))
|
||||
)
|
||||
{
|
||||
/* if model is not variable node B3SOIPD/FD/DD or STAG model, error! */
|
||||
LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 6 nodes") return;
|
||||
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) and STAG (SOI3) can have 6 nodes") return;
|
||||
}
|
||||
else
|
||||
{ /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 6th node */
|
||||
|
|
@ -132,14 +135,15 @@ INP2M (void *ckt, INPtables * tab, card * current)
|
|||
}
|
||||
else
|
||||
{ /* 6th token is a model - only have 5 terminal device */
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
if ((thismodel->INPmodType != INPtypelook ("B3SOI")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIPD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIFD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("B3SOIDD")) &&
|
||||
(thismodel->INPmodType != INPtypelook ("SOI3"))
|
||||
)
|
||||
{
|
||||
/* if model is not variable node B3SOIPD/FD/DD model, error! */
|
||||
LITERR ("only level 9-10 B3SOI(PD | FD | DD) and STAG (SOI3) can have 5 nodes") return;
|
||||
LITERR ("only level 9, 29-31 B3SOI(PD | FD | DD) and STAG (SOI3) can have 5 nodes") return;
|
||||
}
|
||||
else
|
||||
{ /* if looking at B3SOIPD/FD/DD or STAG (SOI3) model, allocate the 5th node */
|
||||
|
|
@ -171,16 +175,23 @@ INP2M (void *ckt, INPtables * tab, card * current)
|
|||
&& thismodel->INPmodType != INPtypelook ("BSIM1")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM2")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3")
|
||||
&& thismodel->INPmodType != INPtypelook ("B3SOI")
|
||||
&& thismodel->INPmodType != INPtypelook ("B3SOIPD")
|
||||
&& thismodel->INPmodType != INPtypelook ("B3SOIFD")
|
||||
&& thismodel->INPmodType != INPtypelook ("B3SOIDD")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM4")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3V1")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3V2")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3v0")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3v1")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3v1S")
|
||||
&& thismodel->INPmodType != INPtypelook ("BSIM3v1A")
|
||||
&& thismodel->INPmodType != INPtypelook ("SOI3")
|
||||
#ifdef CIDER
|
||||
&& thismodel->INPmodType != INPtypelook ("NUMOS")
|
||||
#endif
|
||||
#ifdef HAVE_EKV
|
||||
&& thismodel->INPmodType != INPtypelook ("EKV")
|
||||
#endif
|
||||
&& thismodel->INPmodType != INPtypelook ("HiSIM1")
|
||||
)
|
||||
{
|
||||
LITERR ("incorrect model type");
|
||||
|
|
@ -211,7 +222,8 @@ INP2M (void *ckt, INPtables * tab, card * current)
|
|||
IFC (bindNode, (ckt, fast, 3, node3));
|
||||
IFC (bindNode, (ckt, fast, 4, node4));
|
||||
/*use type not thismodel->INPmodType as it might not exist!*/
|
||||
if ((type == INPtypelook ("B3SOIPD")) ||
|
||||
if ((type == INPtypelook ("B3SOI")) ||
|
||||
(type == INPtypelook ("B3SOIPD")) ||
|
||||
(type == INPtypelook ("B3SOIFD")) ||
|
||||
(type == INPtypelook ("B3SOIDD")) ||
|
||||
(type == INPtypelook ("SOI3")))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1988 Thomas L. Quarles
|
||||
Modified: 2001 Paolo Nenzi (Cider Integration)
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -66,8 +67,13 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode)
|
|||
INPinsert(&model, tab);
|
||||
current->error = INPgetMod(ckt, model, &thismodel, tab);
|
||||
if (thismodel != NULL) {
|
||||
if(thismodel->INPmodType != INPtypelook("BJT") &&
|
||||
thismodel->INPmodType != INPtypelook("BJT2")) {
|
||||
if((thismodel->INPmodType != INPtypelook("BJT"))
|
||||
&& (thismodel->INPmodType != INPtypelook("BJT2"))
|
||||
#ifdef CIDER
|
||||
&& (thismodel->INPmodType != INPtypelook("NBJT"))
|
||||
&& (thismodel->INPmodType != INPtypelook("NBJT2"))
|
||||
#endif
|
||||
) {
|
||||
LITERR("incorrect model type")
|
||||
return;
|
||||
}
|
||||
|
|
@ -96,7 +102,15 @@ void INP2Q(void *ckt, INPtables * tab, card * current, void *gnode)
|
|||
IFC(bindNode, (ckt, fast, 4, node4));
|
||||
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
|
||||
if (waslead) {
|
||||
#ifdef CIDER
|
||||
if( type == INPtypelook("NBJT2") ) {
|
||||
LITERR(" error: no unlabelled parameter permitted on NBJT2\n")
|
||||
} else {
|
||||
#endif
|
||||
ptemp.rValue = leadval;
|
||||
GCA(INPpName, ("area", &ptemp, ckt, type, fast));
|
||||
}
|
||||
#ifdef CIDER
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,55 +255,71 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
|
|||
case 9:
|
||||
type = INPtypelook("Mos9");
|
||||
if(type < 0) {
|
||||
err = INPmkTemp(
|
||||
"Device type MOS9 not available in this binary\n");
|
||||
err = INPmkTemp
|
||||
("Device type MOS9 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
type = INPtypelook("B3SOIPD");
|
||||
type = INPtypelook("B3SOI");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type B3SOIPD not available in this binary\n");
|
||||
("Device type B3SOI V3.0 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
type = INPtypelook("B3SOIFD");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type B3SOIFD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
type = INPtypelook("B3SOIDD");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type B3SOIDD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
type = INPtypelook("BSIM4");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type BSIM4 not available in this binary\n");}
|
||||
("Device type BSIM4 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
type = INPtypelook("BSIM5");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type BSIM5 not available in this binary\n");
|
||||
("Device type BSIM5 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 16:
|
||||
type = INPtypelook("BSIM6");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type BSIM6 not available in this binary\n");
|
||||
("Device type BSIM6 not available in this binary\n");}
|
||||
break;
|
||||
case 17:
|
||||
type = INPtypelook("HiSIM1");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type HiSIM1 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 29:
|
||||
type = INPtypelook("B3SOIPD");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type B3SOIPD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
type = INPtypelook("B3SOIFD");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type B3SOIFD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 31:
|
||||
type = INPtypelook("B3SOIDD");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Placeholder: Device type B3SOIDD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 44:
|
||||
|
|
@ -315,21 +331,37 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
|
|||
}
|
||||
break;
|
||||
case 49:
|
||||
type = INPtypelook("BSIM3V1");
|
||||
type = INPtypelook("BSIM3v1S");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type BSIM3V1 not available in this binary\n");
|
||||
("Device type BSIM3v1S not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 50:
|
||||
type = INPtypelook("BSIM3V2");
|
||||
type = INPtypelook("BSIM3v1");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type BSIM3V2 not available in this binary\n");
|
||||
("Device type BSIM3v1 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 51:
|
||||
type = INPtypelook("BSIM3v1A");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type BSIM3v1A not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 52:
|
||||
type = INPtypelook("BSIM3v0");
|
||||
if (type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type BSIM3v0 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 60:
|
||||
type = INPtypelook("SOI");
|
||||
if (type < 0) {
|
||||
|
|
@ -468,6 +500,62 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
|
|||
INPmakeMod(modname, type, image);
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
else if(strcmp(typename,"numd") == 0) {
|
||||
err = INPfindLev(line,&lev);
|
||||
switch( lev ) {
|
||||
case 1:
|
||||
default:
|
||||
type = INPtypelook("NUMD");
|
||||
if(type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type NUMD not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
type = INPtypelook("NUMD2");
|
||||
if(type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type NUMD2 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
INPmakeMod(modname,type,image);
|
||||
} else if(strcmp(typename,"nbjt") == 0) {
|
||||
err = INPfindLev(line,&lev);
|
||||
switch( lev ) {
|
||||
case 1:
|
||||
default:
|
||||
type = INPtypelook("NBJT");
|
||||
if(type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type NBJT not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
type = INPtypelook("NBJT2");
|
||||
if(type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type NBJT2 not available in this binary\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
INPmakeMod(modname,type,image);
|
||||
} else if(strcmp(typename,"numos") == 0) {
|
||||
type = INPtypelook("NUMOS");
|
||||
if(type < 0) {
|
||||
err =
|
||||
INPmkTemp
|
||||
("Device type NUMOS not available in this binary\n");
|
||||
}
|
||||
INPmakeMod(modname,type,image);
|
||||
}
|
||||
#endif /* CIDER */
|
||||
|
||||
/* type poly added by SDB . . . */
|
||||
#ifdef XSPICE
|
||||
/* -------- Check if model is a poly (specific to xspice) --------- */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Thomas L. Quarles
|
||||
Author: 1985 Thomas L. Quarles, 1991 David A. Gates
|
||||
Modified: 2001 Paolo Nenzi (Cider Integration)
|
||||
**********/
|
||||
|
||||
#include "ngspice.h"
|
||||
|
|
@ -11,6 +12,21 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "fteext.h"
|
||||
#include "inp.h"
|
||||
|
||||
#ifdef CIDER
|
||||
/* begin Cider Integration */
|
||||
#include "numcards.h"
|
||||
#include "carddefs.h"
|
||||
#include "numgen.h"
|
||||
#include "suffix.h"
|
||||
|
||||
extern IFcardInfo *INPcardTab[];
|
||||
extern int INPnumCards;
|
||||
#define E_MISSING -1
|
||||
#define E_AMBIGUOUS -2
|
||||
|
||||
/* end Cider Integration */
|
||||
#endif /* CIDER */
|
||||
|
||||
extern INPmodel *modtab;
|
||||
|
||||
char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
|
||||
|
|
@ -65,6 +81,21 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
|
|||
if (error)
|
||||
return (INPerror(error));
|
||||
/* parameter isolation, identification, binding */
|
||||
|
||||
#ifdef CIDER
|
||||
/* begin cider integration */
|
||||
/* Handle Numerical Models Differently */
|
||||
if ( ((modtmp)->INPmodType == INPtypelook("NUMD")) ||
|
||||
((modtmp)->INPmodType == INPtypelook("NBJT")) ||
|
||||
((modtmp)->INPmodType == INPtypelook("NUMD2")) ||
|
||||
((modtmp)->INPmodType == INPtypelook("NBJT2")) ||
|
||||
((modtmp)->INPmodType == INPtypelook("NUMOS")) ) {
|
||||
error = INPparseNumMod( ckt, modtmp, tab, &err );
|
||||
if (error) return(INPerror(error));
|
||||
} else {
|
||||
/* It's an analytical model */
|
||||
#endif /* CIDER */
|
||||
|
||||
line = ((modtmp)->INPmodLine)->line;
|
||||
|
||||
#ifdef TRACE
|
||||
|
|
@ -121,6 +152,9 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
|
|||
}
|
||||
FREE(parm);
|
||||
}
|
||||
#ifdef CIDER
|
||||
} /* analytical vs. numerical model parsing */
|
||||
#endif
|
||||
(modtmp)->INPmodUsed = 1;
|
||||
(modtmp)->INPmodLine->error = err;
|
||||
}
|
||||
|
|
@ -142,3 +176,240 @@ char *INPgetMod(void *ckt, char *name, INPmodel ** model, INPtables * tab)
|
|||
|
||||
return (err);
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
/*
|
||||
* Parse a numerical model by running through the list of original
|
||||
* input cards which make up the model
|
||||
* Given:
|
||||
* 1. First card looks like: .model modname modtype <level=val>
|
||||
* 2. Other cards look like: +<whitespace>? where ? tells us what
|
||||
* to do with the next card:
|
||||
* '#$*' = comment card
|
||||
* '+' = continue previous card
|
||||
* other = new card
|
||||
*/
|
||||
int
|
||||
INPparseNumMod( ckt, model, tab, errMessage )
|
||||
void* ckt;
|
||||
INPmodel *model;
|
||||
INPtables *tab;
|
||||
char **errMessage;
|
||||
{
|
||||
card *txtCard; /* Text description of a card */
|
||||
GENcard *tmpCard; /* Processed description of a card */
|
||||
IFcardInfo *info; /* Info about the type of card located */
|
||||
char *line;
|
||||
char *cardName = NULL; /* name of a card */
|
||||
char *parm; /* name of a parameter */
|
||||
int cardType; /* type/index for the current card */
|
||||
int cardNum = 0; /* number of this card in the overall line */
|
||||
int lastType = E_MISSING; /* type of previous card */
|
||||
char *err = NULL, *tmp; /* Strings for error messages */
|
||||
IFvalue *value;
|
||||
int error, idx, invert;
|
||||
|
||||
/* Chase down to the top of the list of actual cards */
|
||||
txtCard = model->INPmodLine->actualLine;
|
||||
|
||||
/* Skip the first card if it exists since there's nothing interesting */
|
||||
/* txtCard will be empty if the numerical model is empty */
|
||||
if (txtCard) txtCard = txtCard->nextcard;
|
||||
|
||||
/* Now parse each remaining card */
|
||||
while (txtCard) {
|
||||
line = txtCard->line;
|
||||
cardType = E_MISSING;
|
||||
cardNum++;
|
||||
|
||||
/* Skip the initial '+' and any whitespace. */
|
||||
line++;
|
||||
while (*line == ' ' || *line == '\t')
|
||||
line++;
|
||||
|
||||
switch (*line) {
|
||||
case '*':
|
||||
case '$':
|
||||
case '#':
|
||||
case '\0':
|
||||
case '\n':
|
||||
/* comment or empty cards */
|
||||
lastType = E_MISSING;
|
||||
break;
|
||||
case '+':
|
||||
/* continuation card */
|
||||
if (lastType >= 0) {
|
||||
cardType = lastType;
|
||||
while (*line == '+') line++; /* Skip leading '+'s */
|
||||
} else {
|
||||
tmp = (char *)xmalloc((55)*sizeof(char));
|
||||
(void) sprintf(tmp,
|
||||
"Error on card %d : illegal continuation \'+\' - ignored",
|
||||
cardNum);
|
||||
err = INPerrCat(err,tmp);
|
||||
lastType = E_MISSING;
|
||||
break;
|
||||
}
|
||||
/* FALL THRU when continuing a card */
|
||||
default:
|
||||
if (cardType == E_MISSING) {
|
||||
/* new command card */
|
||||
if (cardName) FREE(cardName); /* get rid of old card name */
|
||||
INPgetTok(&line,&cardName,1); /* get new card name */
|
||||
if (*cardName) { /* Found a name? */
|
||||
cardType = INPfindCard(cardName,INPcardTab,INPnumCards);
|
||||
if (cardType >= 0) {
|
||||
/* Add card structure to model */
|
||||
info = INPcardTab[cardType];
|
||||
error = (*(info->newCard))( (void *)&tmpCard,
|
||||
model->INPmodfast );
|
||||
if (error) return(error);
|
||||
/* Handle parameter-less cards */
|
||||
} else if (cinprefix( cardName, "title", 3 ) ) {
|
||||
/* Do nothing */
|
||||
} else if (cinprefix( cardName, "comment", 3 ) ) {
|
||||
/* Do nothing */
|
||||
} else if (cinprefix( cardName, "end", 3 ) ) {
|
||||
/* Terminate parsing */
|
||||
txtCard = ((card *) 0);
|
||||
cardType = E_MISSING;
|
||||
} else {
|
||||
/* Error */
|
||||
tmp =(char *)xmalloc((55+strlen(cardName))*sizeof(char));
|
||||
(void) sprintf(tmp,
|
||||
"Error on card %d : unrecognized name (%s) - ignored",
|
||||
cardNum, cardName );
|
||||
err = INPerrCat(err,tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cardType >= 0) { /* parse the rest of this line */
|
||||
while (*line) {
|
||||
/* Strip leading carat from booleans */
|
||||
if (*line == '^') {
|
||||
invert = TRUE;
|
||||
*line++; /* Skip the '^' */
|
||||
} else {
|
||||
invert = FALSE;
|
||||
}
|
||||
INPgetTok(&line,&parm,1);
|
||||
if (!*parm)
|
||||
break;
|
||||
idx = INPfindParm(parm, info->cardParms, info->numParms);
|
||||
if (idx == E_MISSING) {
|
||||
/* parm not found */
|
||||
tmp = (char *)xmalloc((60+strlen(parm)) * sizeof(char));
|
||||
(void)sprintf(tmp,
|
||||
"Error on card %d : unrecognized parameter (%s) - ignored",
|
||||
cardNum, parm);
|
||||
err = INPerrCat(err, tmp);
|
||||
} else if (idx == E_AMBIGUOUS) {
|
||||
/* parm ambiguous */
|
||||
tmp = (char *)xmalloc((58+strlen(parm)) * sizeof(char));
|
||||
(void)sprintf(tmp,
|
||||
"Error on card %d : ambiguous parameter (%s) - ignored",
|
||||
cardNum, parm);
|
||||
err = INPerrCat(err, tmp);
|
||||
} else {
|
||||
value = INPgetValue( ckt, &line,
|
||||
((info->cardParms)[idx]).dataType, tab );
|
||||
if (invert) { /* invert if it's a boolean entry */
|
||||
if (((((info->cardParms)[idx]).dataType)&IF_VARTYPES)
|
||||
== IF_FLAG) {
|
||||
value->iValue = 0;
|
||||
} else {
|
||||
tmp =(char *)xmalloc((63+strlen(parm))*sizeof(char));
|
||||
(void)sprintf(tmp,
|
||||
"Error on card %d : non-boolean parameter (%s) - \'^\' ignored",
|
||||
cardNum, parm);
|
||||
err = INPerrCat(err, tmp);
|
||||
}
|
||||
}
|
||||
error = (*(info->setCardParm))(
|
||||
((info->cardParms)[idx]).id, value, tmpCard );
|
||||
if (error) return(error);
|
||||
}
|
||||
FREE(parm);
|
||||
}
|
||||
}
|
||||
lastType = cardType;
|
||||
break;
|
||||
}
|
||||
if (txtCard) txtCard = txtCard->nextcard;
|
||||
}
|
||||
*errMessage = err;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the best match to a card name in an IFcardInfo table
|
||||
*/
|
||||
int
|
||||
INPfindCard( name, table, numCards )
|
||||
char *name;
|
||||
IFcardInfo *table[];
|
||||
int numCards;
|
||||
{
|
||||
int test;
|
||||
int match, bestMatch;
|
||||
int best;
|
||||
int length;
|
||||
|
||||
length = strlen(name);
|
||||
|
||||
/* compare all the names in the card table to this name */
|
||||
best = E_MISSING;
|
||||
bestMatch = 0;
|
||||
for ( test = 0; test < numCards; test++ ) {
|
||||
match = cimatch( name, table[test]->name );
|
||||
if ((match == bestMatch ) && (match > 0)){
|
||||
best = E_AMBIGUOUS;
|
||||
} else if ((match > bestMatch) && (match == length)) {
|
||||
best = test;
|
||||
bestMatch = match;
|
||||
}
|
||||
}
|
||||
return(best);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate the best match to a parameter name in an IFparm table
|
||||
*/
|
||||
int
|
||||
INPfindParm( name, table, numParms )
|
||||
char *name;
|
||||
IFparm *table;
|
||||
int numParms;
|
||||
{
|
||||
int test, best;
|
||||
int match, bestMatch;
|
||||
int id, bestId;
|
||||
int length;
|
||||
|
||||
length = strlen(name);
|
||||
|
||||
/* compare all the names in the parameter table to this name */
|
||||
best = E_MISSING;
|
||||
bestId = -1;
|
||||
bestMatch = 0;
|
||||
for ( test = 0; test < numParms; test++ ) {
|
||||
match = cimatch( name, table[test].keyword );
|
||||
if ( (match == length) && (match == strlen(table[test].keyword)) ) {
|
||||
/* exact match */
|
||||
best = test;
|
||||
/* all done */
|
||||
break;
|
||||
}
|
||||
id = table[test].id;
|
||||
if ((match == bestMatch) && (match > 0) && (id != bestId)) {
|
||||
best = E_AMBIGUOUS;
|
||||
} else if ((match > bestMatch) && (match == length)) {
|
||||
bestMatch = match;
|
||||
bestId = id;
|
||||
best = test;
|
||||
}
|
||||
}
|
||||
return(best);
|
||||
}
|
||||
|
||||
#endif /* CIDER */
|
||||
|
|
|
|||
Loading…
Reference in New Issue