Modified Files:
ChangeLog Makefile.am NOTES configure.in src/Makefile.am src/spinit src/include/inpdefs.h src/include/mif.h src/include/ngspice.h src/spicelib/devices/Makefile.am src/spicelib/devices/cktcrte.c src/spicelib/devices/dev.c src/spicelib/parser/inpdomod.c src/spicelib/parser/inptyplk.c src/xspice/Makefile.am src/xspice/README src/xspice/enh/enhtrans.c src/xspice/icm/Makefile.am src/xspice/mif/mif.c src/xspice/mif/mif_inp2.c src/xspice/mif/mifgetmod.c src/xspice/mif/mifutil.c tests/Makefile.am Added Files: src/xspice/icm/README src/xspice/icm/dlinfo.h src/xspice/icm/dlmain.c src/xspice/icm/modpath.lst src/xspice/icm/objects.inc src/xspice/icm/spice2poly.cm src/xspice/icm/icm_spice2poly/Makefile.am src/xspice/icm/icm_spice2poly/README src/xspice/icm/icm_spice2poly/cfunc.c src/xspice/icm/icm_spice2poly/cfunc.mod src/xspice/icm/icm_spice2poly/ifspec.c src/xspice/icm/icm_spice2poly/ifspec.ifs src/xspice/icm/icm_spice2poly/make.bat tests/TransImpedanceAmp/Makefile.am tests/TransImpedanceAmp/README tests/TransImpedanceAmp/output.net Merged Changes from http://www.brorson.com/gEDA/ngspice/ngspice.html Many thanks to Stuart Brorson.
This commit is contained in:
parent
84f79054a8
commit
da89dcc6c5
28
ChangeLog
28
ChangeLog
|
|
@ -1,3 +1,31 @@
|
|||
2003-06-22 Stuart Brorson <sdb@cloud9.net>
|
||||
|
||||
* Finally got SPICE2 POLY stuff working. This involved lots of changes
|
||||
in src/xspice/mif and src/xspice/enh. Particular changes were made in:
|
||||
-- MIF_INP2A: re-arranged logic to fix parsing problems.
|
||||
-- two2three_translate: fixed some stupid pointer problems.
|
||||
-- etc.
|
||||
|
||||
* Revamped src/xspice/icm/ and src/xspice/icm/icm_spice2poly
|
||||
directories to enable build of POLY codemodel. Makefiles were
|
||||
fixed, and some stuff was added to enable cmpp (from SPICE Opus)
|
||||
to build the codemodel precursors correctly. (Note that you need
|
||||
to download and install SPICE Opus to rebuild the codemodel
|
||||
stuff. See src/xspice/icm/README for more details.)
|
||||
|
||||
* Hacked Makefile.am's for much of the directory hierarchy, particularly
|
||||
for src/xspice/icm and src/xspice/icm/icm_spice2poly to build the POLY
|
||||
codemodel correctly. Note that top level make still doesn't detect
|
||||
changes in the xspice hierarchy; read the NOTES file for a workaround.
|
||||
|
||||
* Added a SPICE netlist incorporating vendor models with SPICE2
|
||||
POLYs in tests/TransImpedanceAmp/. Running this model
|
||||
successfully demonstrates that you have built the XSpice POLY
|
||||
codemodel correctly and that life is good . . . .
|
||||
|
||||
* Moved #define TRACE out of src/ngspice.h and made it a compiler
|
||||
option (-DTRACE) invoked in src/Makefile when making spice.o.
|
||||
|
||||
2003-06-19 Adrian Dawe <a.dawe@multigig.com>
|
||||
|
||||
* Much improved spice wish interface; graph includes zooming,
|
||||
|
|
|
|||
|
|
@ -18,3 +18,6 @@ tcl:
|
|||
cd src && $(MAKE) tcl
|
||||
install-tcl:
|
||||
cd src && $(MAKE) install-tcl
|
||||
|
||||
codemodels:
|
||||
cd src/xspice/icm && make
|
||||
28
NOTES
28
NOTES
|
|
@ -1,3 +1,31 @@
|
|||
SPICE 2 POLY CODEMODEL
|
||||
|
||||
SPICE2 POLY attributes are now available for controlled sources. To
|
||||
use POLY attributes, configure tclspice/ngspice with the
|
||||
--enable-xspice flag set as described above. After compilation of
|
||||
ngspice, cd into $(top_srcdir)/src/xspice/icm and read the README file
|
||||
there for instructions about how to get POLY support. (Hint: you have
|
||||
to download some stuff from http://www.fe.uni-lj.si/ and edit the
|
||||
Makefiles before you can do "make && make install" of the codemodel
|
||||
stuff.)
|
||||
|
||||
-- SDB 6.22.2003.
|
||||
|
||||
--------------------------------------------------------------------
|
||||
COMPILING XSPICE CHANGES
|
||||
|
||||
The dependencies in the Makefile don't seem to work when you are
|
||||
compiling changes in the xspice stuff. Obviously, the best thing to
|
||||
do is fix Makefile.am, but since I am not an expert at this, I have
|
||||
been using the following workaround when making:
|
||||
|
||||
touch src/main.c && make && make install
|
||||
|
||||
I recommend you also do this if you hack anything under src/xspice.
|
||||
|
||||
-- SDB 6.19.2003.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
DEBUGGING SPICE
|
||||
|
||||
To avoid a segmentation fault in the initial run, use the following
|
||||
|
|
|
|||
12
configure.in
12
configure.in
|
|
@ -207,6 +207,8 @@ dnl Checks for programs
|
|||
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AM_PROG_LIBTOOL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
|
||||
|
||||
dnl Checks for X11 header files and libraries - X11 support can be disabled
|
||||
|
|
@ -363,6 +365,7 @@ fi
|
|||
AC_SUBST(EKVDIR)
|
||||
AC_SUBST(EKVLIB)
|
||||
|
||||
dnl Add new code models to the build by pointing to them here.
|
||||
if test "$enable_xspice" = "yes"; then
|
||||
AC_MSG_RESULT(X-Spice features included)
|
||||
AC_DEFINE(XSPICE)
|
||||
|
|
@ -412,7 +415,7 @@ src/spicelib/analysis/Makefile \
|
|||
src/spicelib/devices/Makefile \
|
||||
src/spicelib/devices/asrc/Makefile \
|
||||
src/spicelib/devices/bjt/Makefile \
|
||||
src/spicelib/devices/bjt2/Makefile \
|
||||
dnl src/spicelib/devices/bjt2/Makefile \
|
||||
src/spicelib/devices/bsim1/Makefile \
|
||||
src/spicelib/devices/bsim2/Makefile \
|
||||
src/spicelib/devices/bsim3v1/Makefile \
|
||||
|
|
@ -428,7 +431,7 @@ src/spicelib/devices/ccvs/Makefile \
|
|||
src/spicelib/devices/csw/Makefile \
|
||||
src/spicelib/devices/cpl/Makefile \
|
||||
src/spicelib/devices/dio/Makefile \
|
||||
src/spicelib/devices/ekv/Makefile \
|
||||
dnl src/spicelib/devices/ekv/Makefile \
|
||||
src/spicelib/devices/ind/Makefile \
|
||||
src/spicelib/devices/isrc/Makefile \
|
||||
src/spicelib/devices/hfet1/Makefile \
|
||||
|
|
@ -467,6 +470,8 @@ src/maths/sparse/Makefile \
|
|||
src/misc/Makefile \
|
||||
src/xspice/Makefile \
|
||||
src/xspice/cm/Makefile \
|
||||
src/xspice/icm/Makefile \
|
||||
src/xspice/icm/icm_spice2poly/Makefile \
|
||||
src/xspice/mif/Makefile \
|
||||
src/xspice/evt/Makefile \
|
||||
src/xspice/enh/Makefile \
|
||||
|
|
@ -480,7 +485,8 @@ tests/bsim3soipd/Makefile \
|
|||
tests/bsim3soifd/Makefile \
|
||||
tests/bsim3soidd/Makefile \
|
||||
tests/bsim4/Makefile \
|
||||
tests/mesa/Makefile
|
||||
tests/mesa/Makefile \
|
||||
tests/TransImpedanceAmp/Makefile
|
||||
)
|
||||
|
||||
dnl Printout Tcl option
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ initdata_DATA = spinit setplot spectrum
|
|||
DYNAMIC_DEVICELIBS = \
|
||||
spicelib/devices/asrc/libasrc.la \
|
||||
spicelib/devices/bjt/libbjt.la \
|
||||
## spicelib/devices/bjt2/libbjt2.la \
|
||||
spicelib/devices/bsim1/libbsim1.la \
|
||||
spicelib/devices/bsim2/libbsim2.la \
|
||||
spicelib/devices/bsim3/libbsim3.la \
|
||||
|
|
@ -60,6 +59,15 @@ DYNAMIC_DEVICELIBS = \
|
|||
spicelib/devices/vcvs/libvcvs.la \
|
||||
spicelib/devices/vsrc/libvsrc.la
|
||||
|
||||
|
||||
|
||||
## ----- 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.la \
|
||||
## poly added to dynamic libs by SDB on 6.1.2003
|
||||
## xspice/icm/poly/libpoly.la
|
||||
|
||||
## Build ngspice first:
|
||||
|
||||
ngspice_SOURCES = \
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ typedef struct sINPmodel{
|
|||
void *INPmodfast; /* high speed pointer to model for access */
|
||||
} INPmodel;
|
||||
|
||||
|
||||
/* global input model table. */
|
||||
extern INPmodel *modtab;
|
||||
|
||||
|
||||
/* listing types - used for debug listings */
|
||||
#define LOGICAL 1
|
||||
#define PHYSICAL 2
|
||||
|
|
|
|||
|
|
@ -77,8 +77,11 @@ typedef struct {
|
|||
} Mif_Info_t;
|
||||
|
||||
|
||||
/* These are defined in mif.c */
|
||||
extern int MIFiSize;
|
||||
extern int MIFmSize;
|
||||
|
||||
|
||||
extern Mif_Info_t g_mif_info;
|
||||
|
||||
|
||||
#endif /* MIF */
|
||||
|
|
|
|||
|
|
@ -3,15 +3,6 @@
|
|||
* 1999 E. Rouat
|
||||
************/
|
||||
|
||||
/* Uncomment this to get trace of program operation for
|
||||
* debugging
|
||||
*/
|
||||
/* #define TRACE */
|
||||
|
||||
/* This was also added by SDB to aid in
|
||||
* debugging. Remove when finished.
|
||||
*/
|
||||
|
||||
/* #include "memwatch.h"
|
||||
#define MEMWATCH */
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
SUBDIRS = \
|
||||
asrc \
|
||||
bjt \
|
||||
## bjt2 \
|
||||
bsim1 \
|
||||
bsim2 \
|
||||
bsim3 \
|
||||
|
|
@ -44,6 +43,11 @@ SUBDIRS = \
|
|||
vcvs \
|
||||
vsrc
|
||||
|
||||
## This line move to here 'cause it was causing automake to choke
|
||||
## when it was in the list of subdirs
|
||||
## bjt2 \
|
||||
|
||||
|
||||
noinst_LIBRARIES = libdev.a
|
||||
|
||||
libdev_a_SOURCES = \
|
||||
|
|
@ -58,6 +62,6 @@ libdev_a_SOURCES = \
|
|||
cktfinddev.c \
|
||||
cktinit.c
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ CKTcrtElt(void *ckt, void *inModPtr, void **inInstPtr, IFuid name)
|
|||
|
||||
#ifdef TRACE
|
||||
/*------ SDB debug statement -------*/
|
||||
printf("about to tmalloc, type = %d. . . \n", type);
|
||||
printf("In CKTcrtElt, about to tmalloc new model, type = %d. . . \n", type);
|
||||
#endif
|
||||
|
||||
instPtr = (GENinstance *) tmalloc(*DEVices[type]->DEVinstSize);
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ void load_alldevs(void){
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------- XSPICE additions below ----------------------*/
|
||||
#ifdef XSPICE
|
||||
#include <mif.h>
|
||||
#include <cm.h>
|
||||
|
|
@ -298,8 +298,18 @@ void load_alldevs(void){
|
|||
#include <cktdefs.h> /*for DEVmaxnum*/
|
||||
|
||||
static void relink() {
|
||||
ft_sim->numDevices = num_devices();
|
||||
DEVmaxnum = num_devices();
|
||||
/* added by SDB; DEVmaxnum is an external int defined in cktdefs.h */
|
||||
extern int DEVmaxnum;
|
||||
|
||||
/*
|
||||
* This replacement done by SDB on 6.11.2003
|
||||
*
|
||||
* ft_sim->numDevices = num_devices();
|
||||
* DEVmaxnum = num_devices();
|
||||
*/
|
||||
ft_sim->numDevices = DEVNUM;
|
||||
DEVmaxnum = DEVNUM;
|
||||
|
||||
ft_sim->devices = devices_ptr();
|
||||
return;
|
||||
}
|
||||
|
|
@ -311,6 +321,10 @@ int add_device(int n, SPICEdev **devs, int flag){
|
|||
for(i = 0; i < n;i++){
|
||||
/*debug*/printf("Added device: %s\n",devs[i]->DEVpublic.name);
|
||||
DEVices[DEVNUM+i] = devs[i];
|
||||
|
||||
/* added by SDB on 6.20.2003 */
|
||||
DEVices[DEVNUM+i]->DEVinstSize = &MIFiSize;
|
||||
|
||||
DEVicesfl[DEVNUM+i] = flag;
|
||||
}
|
||||
DEVNUM += n;
|
||||
|
|
@ -407,4 +421,6 @@ int load_opus(char *name){
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*-------------------- end of XSPICE additions ----------------------*/
|
||||
|
|
|
|||
|
|
@ -476,7 +476,8 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
|
|||
/* type poly added by SDB . . . */
|
||||
#ifdef XSPICE
|
||||
/* -------- Check if model is a poly (specific to xspice) --------- */
|
||||
else if (strcmp(typename, "poly") == 0) {
|
||||
else if ( (strcmp(typename, "poly") == 0) ||
|
||||
(strcmp(typename, "POLY") == 0) ) {
|
||||
type = INPtypelook("POLY");
|
||||
if (type < 0) {
|
||||
err =
|
||||
|
|
@ -519,7 +520,7 @@ char *INPdomodel(void *ckt, card * image, INPtables * tab)
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In INPdomodel, adding model typename = %s to model list. . .\n", typename);
|
||||
printf("In INPdomodel, adding unknown model typename = %s to model list. . .\n", typename);
|
||||
#endif
|
||||
|
||||
INPmakeMod(modname,type,image);
|
||||
|
|
|
|||
|
|
@ -21,20 +21,32 @@ int INPtypelook(char *type)
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
/* printf("In INPtypelook, examining model type = %s . . .\n", type); */
|
||||
printf("In INPtypelook, examining model type = %s . . .\n", type);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ft_sim->numDevices; i++) {
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statemnet */
|
||||
/* printf("In INPtypelook, checking model against = %s . . .\n", (*(ft_sim->devices)[i]).name ); */
|
||||
/* SDB debug statement */
|
||||
printf("In INPtypelook, checking model type = %s against existing model = %s, . . .\n", type, (*(ft_sim->devices)[i]).name );
|
||||
#endif
|
||||
|
||||
if (strcmp(type, (*(ft_sim->devices)[i]).name) == 0) {
|
||||
/*found the device - return it */
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In INPtypelook, found the device -- returning it!!!\n");
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In INPtypelook, device not found!\n");
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,3 +2,6 @@
|
|||
alias exit quit
|
||||
alias acct rusage all
|
||||
set x11lineararcs
|
||||
* For SPICE2 POLYs, edit the below line to point to the location
|
||||
* of your codemode.
|
||||
* codemodel /usr/local/src/tclspice-0.2.10/src/xspice/icm/spice2poly.cm
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CF
|
|||
|
||||
EXTRA_DIST = README
|
||||
|
||||
## This is removed because icm relies upon the existance of all other
|
||||
## libs. It is currently compiled manually, last.
|
||||
##SUBDIRS = mif cm enh evt ipc idn icm
|
||||
|
||||
SUBDIRS = mif cm enh evt ipc idn
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)
|
||||
|
|
|
|||
|
|
@ -22,3 +22,20 @@ TODO:
|
|||
|
||||
Stefan Jones
|
||||
19/2/2002
|
||||
|
||||
-----------------------------------------
|
||||
SPICE2 POLY codemodel support.
|
||||
|
||||
SPICE2 POLY attributes are now available for controlled sources. To
|
||||
use POLY attributes, configure tclspice/ngspice with the
|
||||
--enable-xspice flag set as described above. After compilation of
|
||||
ngspice, cd into $(top_srcdir)/src/xspice/icm and read the README file
|
||||
there for instructions about how to get POLY support. (Hint: you have
|
||||
to download some stuff from http://www.fe.uni-lj.si/ and edit the
|
||||
Makefiles before you can do "make && make install" of the codemodel
|
||||
stuff.)
|
||||
|
||||
Please direct questions/comments/complaints to mailto:sdb@cloud9.net.
|
||||
|
||||
6.22.2003 -- SDB.
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ NON-STANDARD FEATURES
|
|||
|
||||
|
||||
/*=== FUNCTION PROTOTYPES ===*/
|
||||
|
||||
static int needs_translating(char *card);
|
||||
static int count_tokens(char *card);
|
||||
static char *two2three_translate(char *orig_card, char **inst_card,
|
||||
|
|
@ -92,8 +91,6 @@ struct line * ENHtranslate_poly(
|
|||
struct line *l2;
|
||||
|
||||
char *card;
|
||||
int poly_dimension;
|
||||
char *buff;
|
||||
|
||||
/* Iterate through each card in the deck and translate as needed */
|
||||
for(d = deck; d; d = d->li_next)
|
||||
|
|
@ -174,15 +171,15 @@ static int needs_translating(
|
|||
|
||||
switch(*card) {
|
||||
|
||||
case 'e':
|
||||
case 'g':
|
||||
case 'e': case 'E':
|
||||
case 'g': case 'G':
|
||||
if(count_tokens(card) <=6)
|
||||
return(0);
|
||||
else
|
||||
return(1);
|
||||
|
||||
case 'f':
|
||||
case 'h':
|
||||
case 'f': case 'F':
|
||||
case 'h': case 'H':
|
||||
if(count_tokens(card) <= 5)
|
||||
return(0);
|
||||
else
|
||||
|
|
@ -217,17 +214,57 @@ static int count_tokens(
|
|||
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
/*====================================================================
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*
|
||||
two2three_translate()
|
||||
|
||||
Do the syntax translation of the 2G6 source to the new code model syntax.
|
||||
Do the syntax translation of the 2G6 source to the new code model
|
||||
syntax. The translation proceeds according to the template below.
|
||||
|
||||
Renamed by SDB to eliminate clash with translate fcn defined in subckt.c
|
||||
4.17.2003 -- SDB
|
||||
--------------------------------------------
|
||||
VCVS:
|
||||
ename N+ N- POLY(dim) NC+ NC- P0 P1 P2 . . .
|
||||
N+ N- = outputs
|
||||
NC+ NC- = inputs
|
||||
|
||||
*/
|
||||
aname %vd[NC+ NC-] %vd[N+ N-] pname
|
||||
.model pname spice2poly(coef=P0 P1 P2 . . . )
|
||||
%vd[NC+ NC-] = inputs
|
||||
%vd[N+ N-] = outputs
|
||||
--------------------------------------------
|
||||
CCCS
|
||||
fname N+ N- POLY(dim) Vname P0 P1 P2 . . .
|
||||
N+ N- = outputs
|
||||
Vname = input voltage source (measures current)
|
||||
|
||||
aname %vnam[Vname] %id[N+ N-] pname
|
||||
.model pname spice2poly(coef=P0 P1 P2 . . . )
|
||||
%vnam[Vname] = input
|
||||
%id[N+ N-] = output
|
||||
--------------------------------------------
|
||||
VCCS
|
||||
gname N+ N- POLY(dim) NC+ NC- P0 P1 P2 , , ,
|
||||
N+ N- = outputs
|
||||
NC+ NC- = inputs
|
||||
|
||||
aname %vd[NC+ NC-] %id[N+ N-] pname
|
||||
.model pname spice2poly(coef=P0 P1 P2 . . . )
|
||||
%vd[NC+ NC-] = inputs
|
||||
%id[N+ N-] = outputs
|
||||
--------------------------------------------
|
||||
CCVS
|
||||
hname N+ N- POLY(dim) Vname P0 P1 P2 . . .
|
||||
N+ N- = outputs
|
||||
Vname = input voltage source (measures current)
|
||||
|
||||
aname %vnam[Vname] %vd[N+ N-] pname
|
||||
.model pname spice2poly(coef=P0 P1 P2 . . . )
|
||||
%vnam[Vname] = input
|
||||
%vd[N+ N-] = output
|
||||
|
||||
====================================================================*/
|
||||
/********************************************************************/
|
||||
|
||||
static char *two2three_translate(
|
||||
char *orig_card, /* the original untranslated card */
|
||||
|
|
@ -246,6 +283,7 @@ static char *two2three_translate(
|
|||
|
||||
char type;
|
||||
|
||||
char *tok;
|
||||
char *name;
|
||||
char **out_conn;
|
||||
char **in_conn;
|
||||
|
|
@ -259,20 +297,22 @@ static char *two2three_translate(
|
|||
printf("In two2three_translate, card to translate = %s . . .\n", orig_card);
|
||||
#endif
|
||||
|
||||
/* Get the first character into local storage for checking type */
|
||||
/* Put the first character into local storage for checking type */
|
||||
type = *orig_card;
|
||||
|
||||
/* Count the number of tokens for use in parsing */
|
||||
num_tokens = count_tokens(orig_card);
|
||||
|
||||
/* Determine the dimension of the poly source */
|
||||
/* Note that get_poly_dimension returns 0 for "no poly", -1 for
|
||||
invalid dimensiion, otherwise returns numeric value of POLY */
|
||||
dim = get_poly_dimension(orig_card);
|
||||
if(dim <= 0) {
|
||||
if(dim == -1) {
|
||||
printf("ERROR in two2three_translate -- Argument to poly() is not an integer\n");
|
||||
return("ERROR - Argument to poly() is not an integer\n");
|
||||
}
|
||||
|
||||
/* Compute number of input connections based on type and dimension */
|
||||
/* Compute number of output connections based on type and dimension */
|
||||
switch(type) {
|
||||
case 'E':
|
||||
case 'e':
|
||||
|
|
@ -286,10 +326,16 @@ static char *two2three_translate(
|
|||
}
|
||||
|
||||
/* Compute number of coefficients. Return error if less than one. */
|
||||
if(dim == 1)
|
||||
num_coefs = num_tokens - num_conns - 3;
|
||||
if(dim == 0)
|
||||
num_coefs = num_tokens - num_conns - 3; /* no POLY token */
|
||||
else
|
||||
num_coefs = num_tokens - num_conns - 5;
|
||||
num_coefs = num_tokens - num_conns - 5; /* POLY token present */
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In two2three_translate, num_tokens=%d, num_conns=%d, num_coefs=%d . . .\n", num_tokens, num_conns, num_coefs);
|
||||
#endif
|
||||
|
||||
|
||||
if(num_coefs < 1)
|
||||
return("ERROR - Number of connections differs from poly dimension\n");
|
||||
|
|
@ -300,18 +346,30 @@ static char *two2three_translate(
|
|||
card = orig_card;
|
||||
name = MIFgettok(&card);
|
||||
|
||||
/* Get output connections (2 netnames) */
|
||||
out_conn = (void *) MALLOC(2 * sizeof(char *));
|
||||
for(i = 0; i < 2; i++)
|
||||
out_conn[i] = MIFgettok(&card);
|
||||
|
||||
if(dim > 1)
|
||||
for(i = 0; i < 2; i++)
|
||||
txfree(MIFgettok(&card));
|
||||
/* check for POLY, and ignore it if present */
|
||||
if (dim > 0) {
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In two2three_translate, found poly!!! dim = %d \n", dim);
|
||||
#endif
|
||||
|
||||
tok = MIFgettok(&card); /* read and discard POLY */
|
||||
tok = MIFgettok(&card); /* read and discard dimension */
|
||||
}
|
||||
|
||||
|
||||
/* Get input connections (2 netnames per dimension) */
|
||||
in_conn = (void *) MALLOC(num_conns * sizeof(char *));
|
||||
for(i = 0; i < num_conns; i++)
|
||||
in_conn[i] = MIFgettok(&card);
|
||||
|
||||
/* The remainder of the line are the poly coeffs. */
|
||||
coef = (void *) MALLOC(num_coefs * sizeof(char *));
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
coef[i] = MIFgettok(&card);
|
||||
|
|
@ -320,14 +378,14 @@ static char *two2three_translate(
|
|||
/* Allow a fair amount of extra space for connection types, etc. */
|
||||
/* to be safe... */
|
||||
|
||||
inst_card_len = 50;
|
||||
inst_card_len = 70;
|
||||
inst_card_len += 2 * (strlen(name) + 1);
|
||||
for(i = 0; i < 2; i++)
|
||||
inst_card_len += strlen(out_conn[i]) + 1;
|
||||
for(i = 0; i < num_conns; i++)
|
||||
inst_card_len += strlen(in_conn[i]) + 1;
|
||||
|
||||
mod_card_len = 50;
|
||||
mod_card_len = 70;
|
||||
mod_card_len += strlen(name) + 1;
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
mod_card_len += strlen(coef[i]) + 1;
|
||||
|
|
@ -340,6 +398,7 @@ static char *two2three_translate(
|
|||
strcpy(*inst_card, "a$poly$");
|
||||
sprintf(*inst_card + strlen(*inst_card), "%s ", name);
|
||||
|
||||
/* Write input nets/sources */
|
||||
if((type == 'e') || (type == 'g') ||
|
||||
(type == 'E') || (type == 'G'))
|
||||
sprintf(*inst_card + strlen(*inst_card), "%%vd [ ");
|
||||
|
|
@ -351,19 +410,26 @@ static char *two2three_translate(
|
|||
|
||||
sprintf(*inst_card + strlen(*inst_card), "] ");
|
||||
|
||||
|
||||
/* Write output nets */
|
||||
if((type == 'e') || (type == 'h') ||
|
||||
(type == 'E') || (type == 'H'))
|
||||
sprintf(*inst_card + strlen(*inst_card), "%%vd ");
|
||||
sprintf(*inst_card + strlen(*inst_card), "%%vd [ ");
|
||||
else
|
||||
sprintf(*inst_card + strlen(*inst_card), "%%id ");
|
||||
sprintf(*inst_card + strlen(*inst_card), "%%id [ ");
|
||||
|
||||
for(i = 0; i < 2; i++)
|
||||
sprintf(*inst_card + strlen(*inst_card), "%s ", out_conn[i]);
|
||||
|
||||
sprintf(*inst_card + strlen(*inst_card), "] ");
|
||||
|
||||
|
||||
/* Write model name */
|
||||
sprintf(*inst_card + strlen(*inst_card), "a$poly$%s", name);
|
||||
|
||||
|
||||
sprintf(*mod_card, ".model a$poly$%s poly coef = [ ", name);
|
||||
/* Now create model card */
|
||||
sprintf(*mod_card, ".model a$poly$%s spice2poly coef = [ ", name);
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
sprintf(*mod_card + strlen(*mod_card), "%s ", coef[i]);
|
||||
sprintf(*mod_card + strlen(*mod_card), "]");
|
||||
|
|
@ -417,9 +483,11 @@ static char *two2three_translate(
|
|||
get_poly_dimension()
|
||||
|
||||
Get the poly source dimension from the token immediately following
|
||||
the 'poly' if any. If 'poly' is not present, return 1. If poly is
|
||||
present and token following is a valid integer, return it. Else
|
||||
return 0.
|
||||
the 'poly' if any. Return values changed by SDB on 5.23.2003 to be:
|
||||
If "poly" is not present, return 0.
|
||||
If the dimension token following "poly" is invalid, return -1.
|
||||
Otherwise, return the integer dimension.
|
||||
Note that the dimension may only be 1 or 2. Is this correct SPICE?
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -429,7 +497,7 @@ static int get_poly_dimension(
|
|||
|
||||
int i;
|
||||
int dim;
|
||||
char *tok;
|
||||
char *local_tok;
|
||||
|
||||
|
||||
/* Skip over name and output connections */
|
||||
|
|
@ -437,27 +505,32 @@ static int get_poly_dimension(
|
|||
txfree(MIFgettok(&card));
|
||||
|
||||
/* Check the next token to see if it is "poly" */
|
||||
/* If not, return a dimension of 1 */
|
||||
tok = MIFgettok(&card);
|
||||
if(strcmp(tok, "poly"))
|
||||
/* If not, return 0 */
|
||||
local_tok = MIFgettok(&card);
|
||||
if( strcmp(local_tok, "poly") &&
|
||||
strcmp(local_tok, "POLY") ) /* check that local_tok is *not* poly */
|
||||
{
|
||||
FREE(tok);
|
||||
|
||||
tok = NULL;
|
||||
|
||||
return(1);
|
||||
FREE(local_tok);
|
||||
local_tok = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
FREE(tok);
|
||||
FREE(local_tok);
|
||||
|
||||
/* Must have been "poly", so next line must be a number */
|
||||
/* Try to convert it. If successful, return the number */
|
||||
/* else, return 0 to indicate an error... */
|
||||
tok = MIFgettok(&card);
|
||||
dim = atoi(tok);
|
||||
FREE(tok);
|
||||
/* else, return -1 to indicate an error... */
|
||||
local_tok = MIFgettok(&card);
|
||||
dim = atoi(local_tok);
|
||||
FREE(local_tok);
|
||||
|
||||
/* This is stupid, but it works. . . . */
|
||||
if ( (dim == 0) || (dim == 1) || (dim == 2) ) {
|
||||
return(dim);
|
||||
}
|
||||
else {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
} /* get_poly_dimension */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,194 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
#
|
||||
# JW 3/9/01 - had a go and makeing an autoconf script.
|
||||
# Hacked on 5.23.2003 by SDB
|
||||
|
||||
noinst_LIBRARIES = libidnxsp.a
|
||||
|
||||
libidnxsp_a_SOURCES = \
|
||||
idndig.c
|
||||
SUBDIRS = icm_spice2poly
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = README modpath.lst udnpath.lst spice2poly.cm dlmain.c
|
||||
|
||||
|
||||
# Edit these to point to your Opus installation
|
||||
CMPPDIR = /usr/local/opus/bin
|
||||
OPUS_INCLUDE_DIR = /usr/local/opus/lib/spice/include
|
||||
|
||||
|
||||
##------ automake definitions below. ------
|
||||
##
|
||||
|
||||
## Yes, listing all this stuff is ugly, but I wasn't clever enough to
|
||||
## find a better way to make it work.
|
||||
|
||||
SYSTEM_LIBS = -lm -lncurses -L/usr/X11R6/lib -lX11 -lXt -lXext -lXmu -lXaw -lSM -lICE
|
||||
|
||||
LOCAL_LIBS = -lcmxsp,-levtxsp,-lidnxsp,-lipcxsp,-lenhxsp,-lmifxsp,-ldev,-lckt,-linp,-lparser,-lhlp,-linp,-lderiv,-lcmaths,-lpoly,-lni,-lsparse,-lmisc,-lfte,-lplotting
|
||||
|
||||
DEVICE_LIBS = -lasrc,-lbjt,-lbsim1,-lbsim2,-lbsim3,-lbsim3v1,-lbsim3v2,-lbsim4,-lcap,-lbsim3soipd,-lbsim3soifd,-lbsim3soidd,-lcccs,-lccvs,-lccvs,-lcpl,-lcsw,-ldio,-lind,-lisrc,-lhfet,-lhfet2,-ljfet,-ljfet2,-lltra,-lmes,-lmesa,-lmos1,-lmos2,-lmos3,-lmos6,-lmos9,-lres,-lsoi3,-lsw,-ltxl,-ltra,-lurc,-lvccs,-lvcvs,-lvsrc
|
||||
|
||||
|
||||
|
||||
LOCAL_LIB_DIRS = \
|
||||
-L$(top_srcdir)/src/xspice/cm/ \
|
||||
-L$(top_srcdir)/src/xspice/enh/ \
|
||||
-L$(top_srcdir)/src/xspice/evt/ \
|
||||
-L$(top_srcdir)/src/xspice/idn/ \
|
||||
-L$(top_srcdir)/src/xspice/ipc/ \
|
||||
-L$(top_srcdir)/src/xspice/mif/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ \
|
||||
-L$(top_srcdir)/src/spicelib/analysis/ \
|
||||
-L$(top_srcdir)/src/spicelib/parser/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/parser/ \
|
||||
-L$(top_srcdir)/src/frontend/help/ \
|
||||
-L$(top_srcdir)/src/maths/deriv/ \
|
||||
-L$(top_srcdir)/src/maths/cmaths/ \
|
||||
-L$(top_srcdir)/src/maths/poly/ \
|
||||
-L$(top_srcdir)/src/maths/ni/ \
|
||||
-L$(top_srcdir)/src/maths/sparse/ \
|
||||
-L$(top_srcdir)/src/misc/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/ \
|
||||
-L$(top_srcdir)/src/frontend/plotting/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/asrc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bjt/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim4/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cap/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_pd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_fd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_dd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cccs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cpl/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/csw/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/dio/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/ind/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/isrc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ltra/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mes/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mesa/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos6/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos9/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/res/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/soi3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/sw/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/txl/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/tra/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/urc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vccs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vcvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vsrc/
|
||||
|
||||
|
||||
EXTRA_LIB_DIRS = \
|
||||
-L$(top_srcdir)/src/xspice/cm/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/enh/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/evt/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/idn/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/ipc/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/mif/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/analysis/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/parser/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/parser/.libs/ \
|
||||
-L$(top_srcdir)/src/frontend/help/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/deriv/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/cmaths/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/poly/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/ni/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/sparse/.libs \
|
||||
-L$(top_srcdir)/src/misc/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/.libs/ \
|
||||
-L$(top_srcdir)/src/frontend/plotting/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/asrc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bjt/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim4/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cap/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_pd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_fd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_dd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cccs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cpl/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/csw/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/dio/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/ind/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/isrc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ltra/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mes/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mesa/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos6/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos9/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/res/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/soi3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/sw/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/txl/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/tra/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/urc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vccs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vcvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vsrc/.libs/
|
||||
|
||||
clean: clean-recursive
|
||||
rm -f cmextrn.h cminfo.h udnextrn.h udninfo.h *.o
|
||||
|
||||
|
||||
cmextrn.h: modpath.lst $(SUBDIRS)/cfunc.c $(SUBDIRS)/ifspec.c
|
||||
$(CMPPDIR)/cmpp -lst
|
||||
|
||||
cminfo.h: modpath.lst $(SUBDIRS)/cfunc.c $(SUBDIRS)/ifspec.c
|
||||
$(CMPPDIR)/cmpp -lst
|
||||
|
||||
udnextrn.h: udnpath.lst $(SUBDIRS)/cfunc.c $(SUBDIRS)/ifspec.c
|
||||
$(CMPPDIR)/cmpp -lst
|
||||
|
||||
udninfo.h: udnpath.lst $(SUBDIRS)/cfunc.c $(SUBDIRS)/ifspec.c
|
||||
$(CMPPDIR)/cmpp -lst
|
||||
|
||||
all: spice2poly.cm
|
||||
|
||||
spice2poly.cm: $(SUBDIRS)/cfunc.o $(SUBDIRS)/ifspec.o dlmain.o
|
||||
$(top_srcdir)/libtool --mode=link $(CC) -module -shared -fPIC -o spice2poly.cm \
|
||||
$(SUBDIRS)/cfunc.o $(SUBDIRS)/ifspec.o dlmain.o \
|
||||
$(SYSTEM_LIBS) $(LOCAL_LIB_DIRS) \
|
||||
-Wl,--start-group -Wl,$(LOCAL_LIBS) -Wl,--end-group -ldl \
|
||||
-Wl,--rpath,/usr/local/geda/lib/ng-spice-rework
|
||||
|
||||
dlmain.o: dlmain.c cmextrn.h udnextrn.h cminfo.h udninfo.h
|
||||
$(CC) -fPIC -I$(OPUS_INCLUDE_DIR) $(INCLUDES) $(CFLAGS) -DCM_LINUX -c dlmain.c
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
This directory holds a codemodel which enables ngspice to handle SPICE
|
||||
2 POLY attributes on controlled sources. In short, when a SPICE 2
|
||||
netlist is read in, any controlled sources with POLY attributes are
|
||||
translated into codemodel devices with an associated .model which
|
||||
invokes spice2poly to evaluate the polynomial.
|
||||
|
||||
To use this model, you need to do the following:
|
||||
|
||||
1. Compile the rest of ngspice/tclspice in the usual way from the
|
||||
base directory. Make sure you do configure --enable-xspice when
|
||||
configuring.
|
||||
|
||||
2. Download and install SPICE Opus (available from
|
||||
http://www.fe.uni-lj.si/). From this you need the program cmpp, as
|
||||
well as some of the include files.
|
||||
|
||||
3. Edit the Makefile in this directory and make the variable CMPPDIR
|
||||
point to the base location of your Opus installation. (Hint: I
|
||||
place it in /usr/local/opus.)
|
||||
|
||||
4. Edit the Makefile in the directory below (icm_spice2poly/) and
|
||||
make the variable CMPDIR point to the base location of your Opus
|
||||
installation.
|
||||
|
||||
5. Do "make" in this directory. The makefiles are set up
|
||||
to do all the necessary stuff to turn the spice2poly sources into a
|
||||
shared object named spice2poly.cm which you can load into ngspice.
|
||||
(Alternatively, you can do "make codemodels" from $(top_srcdir); I
|
||||
have included codemodels as a target which cd's into this directory
|
||||
and does "make".)
|
||||
|
||||
6. Read the codemodel into ngspice in the following way:
|
||||
|
||||
ngspice 1 -> codemodel /usr/local/src/tclspice-0.2.10/src/xspice/icm/spice2poly.cm
|
||||
|
||||
(Of course, you should point to the location where *you* built
|
||||
spice2poly.cm!) You might want to put this invocation into your
|
||||
spinit file (which usually lives in $(top_srcdir)/src/).
|
||||
|
||||
7. Then read in your SPICE netlist. SPICE 2 POLY attributes in
|
||||
controlled sources will be translated into .models invoking the
|
||||
spice2poly codemodel. You should be able to run ngspice and simulate
|
||||
in the usual way!
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Please send any comments/questions/bug reports to:
|
||||
|
||||
Stuart Brorson
|
||||
sdb@cloud9.net
|
||||
|
||||
-- SDB 6.19.2003
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Modify these to include general information about the library
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
char inf_Title[]="icm_poly.cm";
|
||||
char inf_Version[]="0.1";
|
||||
char inf_Description[]="Code model implementation of SPICE2 poly.";
|
||||
char inf_Author[]="Hacked together by SDB, June 2003.";
|
||||
char inf_Copyright[]="Released under GPL";
|
||||
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Build cmextrn.h, cminfo.h, udnextrn.h and udninfo.h from udnpath.lst and
|
||||
// modpath.lst using 'cmpp -lst'. Then compile this file and link it with
|
||||
// cm and udn object files to produce a dll that can be loaded by the
|
||||
// spice opus simulator at run-time.
|
||||
//
|
||||
// Author: Arpad Buermen
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#include "dlinfo.h"
|
||||
|
||||
#include <devdefs.h>
|
||||
#include <evtudn.h>
|
||||
#include "port.h"
|
||||
#include "misc.h"
|
||||
#include "cmextrn.h"
|
||||
#include "udnextrn.h"
|
||||
#include "dllitf.h"
|
||||
|
||||
// This one is automatically set by the compiler
|
||||
char inf_Date[]=__DATE__;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Do not modify anything below this line
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SPICEdev *cmDEVices[] = {
|
||||
#include "cminfo.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmDEVicesCNT = sizeof(cmDEVices)/sizeof(SPICEdev *)-1;
|
||||
|
||||
Evt_Udn_Info_t *cmEVTudns[] = {
|
||||
#include "udninfo.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmEVTudnCNT = sizeof(cmEVTudns)/sizeof(Evt_Udn_Info_t *)-1;
|
||||
|
||||
// Pointer to core info structure containing pointers to core functions.
|
||||
struct coreInfo_t *coreitf;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Functions that return pointers to structures.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef CM_WINDOWS
|
||||
#undef CM_EXPORT
|
||||
#define CM_EXPORT __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#ifdef CM_LINUX
|
||||
#undef CM_EXPORT
|
||||
#define CM_EXPORT extern
|
||||
#endif
|
||||
|
||||
int cmopusvers = 2;
|
||||
|
||||
// This one checks the opus dynamic link version.
|
||||
CM_EXPORT void *CMsysvers() {
|
||||
return (void *)&cmopusvers;
|
||||
}
|
||||
|
||||
// This one returns the title
|
||||
CM_EXPORT void *CMtitle() {
|
||||
return (void *)inf_Title;
|
||||
}
|
||||
|
||||
// This one returns the version
|
||||
CM_EXPORT void *CMversion() {
|
||||
return (void *)inf_Version;
|
||||
}
|
||||
|
||||
// This one returns the date
|
||||
CM_EXPORT void *CMdate() {
|
||||
return (void *)inf_Date;
|
||||
}
|
||||
|
||||
// This one returns the description
|
||||
CM_EXPORT void *CMdescription() {
|
||||
return (void *)inf_Description;
|
||||
}
|
||||
|
||||
// This one returns the author
|
||||
CM_EXPORT void *CMauthor() {
|
||||
return (void *)inf_Author;
|
||||
}
|
||||
|
||||
// This one returns the copyright
|
||||
CM_EXPORT void *CMcopyright() {
|
||||
return (void *)inf_Copyright;
|
||||
}
|
||||
|
||||
// This one returns the device table
|
||||
CM_EXPORT void *CMdevs() {
|
||||
return (void *)cmDEVices;
|
||||
}
|
||||
|
||||
// This one returns the device count
|
||||
CM_EXPORT void *CMdevNum() {
|
||||
return (void *)&cmDEVicesCNT;
|
||||
}
|
||||
|
||||
// This one returns the UDN table
|
||||
CM_EXPORT void *CMudns() {
|
||||
return (void *)cmEVTudns;
|
||||
}
|
||||
|
||||
// This one returns the UDN count
|
||||
CM_EXPORT void *CMudnNum() {
|
||||
return (void *)&cmEVTudnCNT;
|
||||
}
|
||||
|
||||
// This one returns the pointer to the pointer to the core interface structure
|
||||
CM_EXPORT void *CMgetCoreItfPtr() {
|
||||
return (void *)(&coreitf);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// These functions call the real core functions of SPICE OPUS using the
|
||||
// pointers in coreitf structure.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
void MIF_INP2A(
|
||||
GENERIC *ckt, /* circuit structure to put mod/inst structs in */
|
||||
INPtables *tab, /* symbol table for node names, etc. */
|
||||
card *current /* the card we are to parse */
|
||||
) {
|
||||
(coreitf->dllitf_MIF_INP2A)(ckt,tab,current);
|
||||
}
|
||||
|
||||
char * MIFgetMod(
|
||||
GENERIC *ckt,
|
||||
char **name,
|
||||
INPmodel **model,
|
||||
INPtables *tab
|
||||
) {
|
||||
return (coreitf->dllitf_MIFgetMod)(ckt,name,model,tab);
|
||||
}
|
||||
|
||||
IFvalue * MIFgetValue(
|
||||
GENERIC *ckt,
|
||||
char **line,
|
||||
int type,
|
||||
INPtables *tab,
|
||||
char **err
|
||||
) {
|
||||
return (coreitf->dllitf_MIFgetValue)(ckt,line,type,tab,err);
|
||||
}
|
||||
|
||||
|
||||
int MIFsetup(
|
||||
SMPmatrix *matrix,
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt,
|
||||
int *state
|
||||
) {
|
||||
return (coreitf->dllitf_MIFsetup)(matrix,inModel,ckt,state);
|
||||
}
|
||||
|
||||
int MIFunsetup(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
) {
|
||||
return (coreitf->dllitf_MIFunsetup)(inModel,ckt);
|
||||
}
|
||||
|
||||
int MIFload(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
) {
|
||||
return (coreitf->dllitf_MIFload)(inModel,ckt);
|
||||
}
|
||||
|
||||
|
||||
int MIFmParam(
|
||||
int param_index,
|
||||
IFvalue *value,
|
||||
GENmodel *inModel
|
||||
) {
|
||||
return (coreitf->dllitf_MIFmParam)(param_index,value,inModel);
|
||||
}
|
||||
|
||||
int MIFask(
|
||||
CKTcircuit *ckt,
|
||||
GENinstance *inst,
|
||||
int param_index,
|
||||
IFvalue *value,
|
||||
IFvalue *select
|
||||
) {
|
||||
return (coreitf->dllitf_MIFask)(ckt,inst,param_index,value,select);
|
||||
}
|
||||
|
||||
int MIFmAsk(
|
||||
CKTcircuit *ckt,
|
||||
GENmodel *inModel,
|
||||
int param_index,
|
||||
IFvalue *value
|
||||
) {
|
||||
return (coreitf->dllitf_MIFmAsk)(ckt,inModel,param_index,value);
|
||||
}
|
||||
|
||||
int MIFtrunc(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt,
|
||||
double *timeStep
|
||||
) {
|
||||
return (coreitf->dllitf_MIFtrunc)(inModel,ckt,timeStep);
|
||||
}
|
||||
|
||||
int MIFconvTest(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
) {
|
||||
return (coreitf->dllitf_MIFconvTest)(inModel,ckt);
|
||||
}
|
||||
|
||||
int MIFdelete(
|
||||
GENmodel *inModel,
|
||||
IFuid name,
|
||||
GENinstance **inst
|
||||
) {
|
||||
return (coreitf->dllitf_MIFdelete)(inModel,name,inst);
|
||||
}
|
||||
|
||||
int MIFmDelete(
|
||||
GENmodel **inModel,
|
||||
IFuid modname,
|
||||
GENmodel *model
|
||||
) {
|
||||
return (coreitf->dllitf_MIFmDelete)(inModel,modname,model);
|
||||
}
|
||||
|
||||
void MIFdestroy(
|
||||
GENmodel **inModel
|
||||
) {
|
||||
(coreitf->dllitf_MIFdestroy)(inModel);
|
||||
}
|
||||
|
||||
char *MIFgettok(
|
||||
char **s
|
||||
) {
|
||||
return (coreitf->dllitf_MIFgettok)(s);
|
||||
}
|
||||
|
||||
|
||||
char *MIFget_token(
|
||||
char **s,
|
||||
Mif_Token_Type_t *type
|
||||
) {
|
||||
return (coreitf->dllitf_MIFget_token)(s,type);
|
||||
}
|
||||
|
||||
|
||||
Mif_Cntl_Src_Type_t MIFget_cntl_src_type(
|
||||
Mif_Port_Type_t in_port_type,
|
||||
Mif_Port_Type_t out_port_type
|
||||
) {
|
||||
return (coreitf->dllitf_MIFget_cntl_src_type)(in_port_type,out_port_type);
|
||||
}
|
||||
|
||||
char *MIFcopy(char *c) {
|
||||
return (coreitf->dllitf_MIFcopy)(c);
|
||||
}
|
||||
|
||||
|
||||
void cm_climit_fcn(double in, double in_offset, double cntl_upper,
|
||||
double cntl_lower, double lower_delta,
|
||||
double upper_delta, double limit_range,
|
||||
double gain, int percent, double *out_final,
|
||||
double *pout_pin_final, double *pout_pcntl_lower_final,
|
||||
double *pout_pcntl_upper_final) {
|
||||
(coreitf->dllitf_cm_climit_fcn)(in,in_offset,cntl_upper,cntl_lower,lower_delta,
|
||||
upper_delta,limit_range,gain,percent,out_final,
|
||||
pout_pin_final,pout_pcntl_lower_final,
|
||||
pout_pcntl_upper_final);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cm_smooth_corner(double x_input, double x_center, double y_center,
|
||||
double domain, double lower_slope, double upper_slope,
|
||||
double *y_output, double *dy_dx) {
|
||||
(coreitf->dllitf_cm_smooth_corner)(x_input,x_center,y_center,domain,lower_slope,
|
||||
upper_slope,y_output,dy_dx);
|
||||
}
|
||||
|
||||
void cm_smooth_discontinuity(double x_input, double x_lower, double y_lower,
|
||||
double x_upper, double y_upper,
|
||||
double *y_output, double *dy_dx) {
|
||||
(coreitf->dllitf_cm_smooth_discontinuity)(x_input,x_lower,y_lower,x_upper,y_upper,
|
||||
y_output,dy_dx);
|
||||
}
|
||||
|
||||
double cm_smooth_pwl(double x_input, double *x, double *y, int size,
|
||||
double input_domain, double *dout_din) {
|
||||
return (coreitf->dllitf_cm_smooth_pwl)(x_input,x,y,size,input_domain,dout_din);
|
||||
}
|
||||
|
||||
double cm_analog_ramp_factor(void) {
|
||||
return (coreitf->dllitf_cm_analog_ramp_factor)();
|
||||
}
|
||||
|
||||
void *cm_analog_alloc(int tag, int bytes) {
|
||||
return (coreitf->dllitf_cm_analog_alloc)(tag,bytes);
|
||||
}
|
||||
|
||||
void *cm_analog_get_ptr(int tag, int timepoint) {
|
||||
return (coreitf->dllitf_cm_analog_get_ptr)(tag,timepoint);
|
||||
}
|
||||
|
||||
int cm_analog_integrate(double integrand, double *integral, double *partial) {
|
||||
return (coreitf->dllitf_cm_analog_integrate)(integrand,integral,partial);
|
||||
}
|
||||
|
||||
int cm_analog_converge(double *state) {
|
||||
return (coreitf->dllitf_cm_analog_converge)(state);
|
||||
}
|
||||
|
||||
int cm_analog_set_temp_bkpt(double time) {
|
||||
return (coreitf->dllitf_cm_analog_set_temp_bkpt)(time);
|
||||
}
|
||||
|
||||
int cm_analog_set_perm_bkpt(double time) {
|
||||
return (coreitf->dllitf_cm_analog_set_perm_bkpt)(time);
|
||||
}
|
||||
|
||||
void cm_analog_not_converged(void) {
|
||||
(coreitf->dllitf_cm_analog_not_converged)();
|
||||
}
|
||||
|
||||
void cm_analog_auto_partial(void) {
|
||||
(coreitf->dllitf_cm_analog_auto_partial)();
|
||||
}
|
||||
|
||||
void *cm_event_alloc(int tag, int bytes){
|
||||
return (coreitf->dllitf_cm_event_alloc)(tag,bytes);
|
||||
}
|
||||
|
||||
void *cm_event_get_ptr(int tag, int timepoint) {
|
||||
return (coreitf->dllitf_cm_event_get_ptr)(tag,timepoint);
|
||||
}
|
||||
|
||||
int cm_event_queue(double time) {
|
||||
return (coreitf->dllitf_cm_event_queue)(time);
|
||||
}
|
||||
|
||||
char *cm_message_get_errmsg(void) {
|
||||
return (coreitf->dllitf_cm_message_get_errmsg)();
|
||||
}
|
||||
|
||||
int cm_message_send(char *msg) {
|
||||
return (coreitf->dllitf_cm_message_send)(msg);
|
||||
}
|
||||
|
||||
double cm_netlist_get_c(void) {
|
||||
return (coreitf->dllitf_cm_netlist_get_c)();
|
||||
}
|
||||
|
||||
double cm_netlist_get_l(void) {
|
||||
return (coreitf->dllitf_cm_netlist_get_l)();
|
||||
}
|
||||
|
||||
Complex_t cm_complex_set(double real, double imag) {
|
||||
return (coreitf->dllitf_cm_complex_set)(real,imag);
|
||||
}
|
||||
|
||||
Complex_t cm_complex_add(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_add)(x,y);
|
||||
}
|
||||
|
||||
Complex_t cm_complex_subtract(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_subtract)(x,y);
|
||||
}
|
||||
|
||||
Complex_t cm_complex_multiply(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_multiply)(x,y);
|
||||
}
|
||||
|
||||
Complex_t cm_complex_divide(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_divide)(x,y);
|
||||
}
|
||||
|
||||
FILE * cm_stream_out(void) {
|
||||
return (coreitf->dllitf_cm_stream_out)();
|
||||
}
|
||||
|
||||
FILE * cm_stream_in(void) {
|
||||
return (coreitf->dllitf_cm_stream_in)();
|
||||
}
|
||||
|
||||
FILE * cm_stream_err(void) {
|
||||
return (coreitf->dllitf_cm_stream_err)();
|
||||
}
|
||||
|
||||
char * tmalloc_internal(size_t s, int clean, const char *f, int l, int sw) {
|
||||
return (coreitf->dllitf_tmalloc)(s,clean,f,l,sw);
|
||||
}
|
||||
|
||||
char * trealloc_internal(char *ptr, size_t s, const char *f, int l, int sw) {
|
||||
return (coreitf->dllitf_trealloc)(ptr,s,f,l,sw);
|
||||
}
|
||||
|
||||
void tfree_internal(char *ptr, const char *f, int l, int sw) {
|
||||
(coreitf->dllitf_tfree)(ptr,f,l,sw);
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
#
|
||||
# Makefile.am hand-crafted by SDB on 5.25.2003 to create POLY
|
||||
# codemodel shared object. To enable simulation of POLY controlled sources,
|
||||
# do the following:
|
||||
#
|
||||
|
||||
# Edit this to point to cmpp in your installation.
|
||||
CMPPDIR = /usr/local/opus/bin
|
||||
|
||||
##------ automake definitions below. ------
|
||||
##
|
||||
|
||||
## Yes, listing all this stuff is ugly, but I wasn't clever enough to
|
||||
## find a better way to make it work.
|
||||
|
||||
SYSTEM_LIBS = -lm -lncurses -L/usr/X11R6/lib -lX11 -lXt -lXext -lXmu -lXaw -lSM -lICE
|
||||
|
||||
LOCAL_LIBS = -lcmxsp,-levtxsp,-lidnxsp,-lipcxsp,-lenhxsp,-lmifxsp,-ldev,-lckt,-linp,-lparser,-lhlp,-linp,-lderiv,-lcmaths,-lpoly,-lni,-lsparse,-lmisc,-lfte,-lplotting
|
||||
|
||||
DEVICE_LIBS = -lasrc,-lbjt,-lbsim1,-lbsim2,-lbsim3,-lbsim3v1,-lbsim3v2,-lbsim4,-lcap,-lbsim3soipd,-lbsim3soifd,-lbsim3soidd,-lcccs,-lccvs,-lccvs,-lcpl,-lcsw,-ldio,-lind,-lisrc,-lhfet,-lhfet2,-ljfet,-ljfet2,-lltra,-lmes,-lmesa,-lmos1,-lmos2,-lmos3,-lmos6,-lmos9,-lres,-lsoi3,-lsw,-ltxl,-ltra,-lurc,-lvccs,-lvcvs,-lvsrc
|
||||
|
||||
|
||||
LOCAL_LIB_DIRS = \
|
||||
-L$(top_srcdir)/src/xspice/cm/ \
|
||||
-L$(top_srcdir)/src/xspice/enh/ \
|
||||
-L$(top_srcdir)/src/xspice/evt/ \
|
||||
-L$(top_srcdir)/src/xspice/idn/ \
|
||||
-L$(top_srcdir)/src/xspice/ipc/ \
|
||||
-L$(top_srcdir)/src/xspice/mif/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ \
|
||||
-L$(top_srcdir)/src/spicelib/analysis/ \
|
||||
-L$(top_srcdir)/src/spicelib/parser/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/parser/ \
|
||||
-L$(top_srcdir)/src/frontend/help/ \
|
||||
-L$(top_srcdir)/src/maths/deriv/ \
|
||||
-L$(top_srcdir)/src/maths/cmaths/ \
|
||||
-L$(top_srcdir)/src/maths/poly/ \
|
||||
-L$(top_srcdir)/src/maths/ni/ \
|
||||
-L$(top_srcdir)/src/maths/sparse/ \
|
||||
-L$(top_srcdir)/src/misc/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/ \
|
||||
-L$(top_srcdir)/src/frontend/plotting/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/asrc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bjt/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim4/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cap/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_pd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_fd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_dd/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cccs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cpl/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/csw/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/dio/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/ind/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/isrc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ltra/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mes/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mesa/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos1/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos2/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos6/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos9/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/res/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/soi3/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/sw/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/txl/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/tra/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/urc/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vccs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vcvs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vsrc/
|
||||
|
||||
|
||||
EXTRA_LIB_DIRS = \
|
||||
-L$(top_srcdir)/src/xspice/cm/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/enh/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/evt/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/idn/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/ipc/.libs/ \
|
||||
-L$(top_srcdir)/src/xspice/mif/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/analysis/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/parser/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/parser/.libs/ \
|
||||
-L$(top_srcdir)/src/frontend/help/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/deriv/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/cmaths/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/poly/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/ni/.libs/ \
|
||||
-L$(top_srcdir)/src/maths/sparse/.libs \
|
||||
-L$(top_srcdir)/src/misc/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/frontend/.libs/ \
|
||||
-L$(top_srcdir)/src/frontend/plotting/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/asrc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bjt/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3v2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim4/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cap/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_pd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_fd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/bsim3soi_dd/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cccs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ccvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/cpl/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/csw/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/dio/.libs/ \
|
||||
\
|
||||
-L$(top_srcdir)/src/spicelib/devices/ind/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/isrc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/hfet2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/jfet2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/ltra/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mes/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mesa/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos1/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos2/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos6/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/mos9/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/res/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/soi3/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/sw/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/txl/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/tra/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/urc/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vccs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vcvs/.libs/ \
|
||||
-L$(top_srcdir)/src/spicelib/devices/vsrc/.libs/
|
||||
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)
|
||||
|
||||
EXTRA_DIST = cfunc.mod ifspec.ifs README cfunc.c ifspec.c README
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
##------ Make targets listed below. ------
|
||||
|
||||
all: cfunc.o ifspec.o
|
||||
|
||||
clean:
|
||||
rm -f *.o *.cm *.la
|
||||
rm -fR .libs
|
||||
|
||||
cfunc.o: cfunc.c
|
||||
$(CC) -fPIC $(INCLUDES) $(CFLAGS) -c cfunc.c
|
||||
|
||||
ifspec.o: ifspec.c
|
||||
$(CC) -fPIC $(INCLUDES) $(CFLAGS) -c ifspec.c
|
||||
|
||||
# Don't use the below targets unless you know what you are doing!
|
||||
#
|
||||
# Hint: if you create ifspec.c using cmpp, you need to replace MIFunsetup
|
||||
# with NULL in ifspec.c before making ifspec.o (compiling with gcc) because
|
||||
# MIFunsetup is apparently unimplemented.
|
||||
#
|
||||
#cclean: clean
|
||||
# rm -f cfunc.c ifspec.c
|
||||
#
|
||||
#cfunc.c: cfunc.mod
|
||||
# $(CMPPDIR)/cmpp -mod cfunc.mod
|
||||
#
|
||||
#ifspec.c: ifspec.ifs
|
||||
# $(CMPPDIR)/cmpp -ifs
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
This directory holds a codemodel which enables ngspice to handle SPICE
|
||||
2 POLY attributes on controlled sources. In short, when a SPICE 2
|
||||
netlist is read in, any controlled sources with POLY attributes are
|
||||
translated into codemodel devices with an associated .model which
|
||||
invokes spice2poly to evaluate the polynomial.
|
||||
|
||||
To use this model, you need to do the following:
|
||||
|
||||
1. Compile the rest of ngspice/tclspice in the usual way from the
|
||||
base directory.
|
||||
|
||||
2. Download and install SPICE Opus (available from
|
||||
http://www.fe.uni-lj.si/ ). From this you need the program cmpp, as
|
||||
well as some of the include files.
|
||||
|
||||
3. Edit the Makefile in this directory and make the variable CMPPDIR
|
||||
point to the base location of your Opus installation.
|
||||
|
||||
4. Edit the Makefile in the directory above (..) and make the
|
||||
variable CMPDIR point to the base location of your Opus installation.
|
||||
|
||||
5. Do "make" in the directory above (..). The makefiles are set up
|
||||
to do all the necessary stuff to turn the spice2poly sources into a
|
||||
shared object named spice2poly.cm which you can load into ngspice.
|
||||
(Alternatively, you can do "make codemodels" from $(top_srcdir); I
|
||||
have included codemodels as a target which cd's into the directory
|
||||
below and does "make".)
|
||||
|
||||
6. Read the codemodel into ngspice in the following way:
|
||||
|
||||
ngspice 1 -> codemodel /usr/local/src/tclspice-0.2.10/src/xspice/icm/spice2poly.cm
|
||||
|
||||
(Of course, you should point to the location where *you* built
|
||||
spice2poly.cm!) You might want to put this invocation into your
|
||||
spinit file (which usually lives in $(top_srcdir)/src/).
|
||||
|
||||
7. Then read in your SPICE netlist. SPICE 2 POLY attributes in
|
||||
controlled sources will be translated into .models invoking the
|
||||
spice2poly codemodel. You should be able to run ngspice and simulate
|
||||
in the usual way!
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Please send any comments/questions/bug reports to:
|
||||
|
||||
Stuart Brorson
|
||||
sdb@cloud9.net
|
||||
|
||||
-- SDB 6.19.2003
|
||||
|
||||
|
|
@ -0,0 +1,305 @@
|
|||
#line 1 "cfunc.mod"
|
||||
#include "cm.h"
|
||||
#line 1 "cfunc.mod"
|
||||
/* ===========================================================================
|
||||
FILE cfunc.mod
|
||||
|
||||
MEMBER OF process XSPICE
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the definition of a code model polynomial controlled
|
||||
source compatible with SPICE 2G6 poly sources.
|
||||
|
||||
INTERFACES
|
||||
|
||||
spice2poly()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
=========================================================================== */
|
||||
|
||||
/*
|
||||
|
||||
This code model implements the non-linear polynomial controlled sources
|
||||
available in SPICE 2G6. An automatic translator added into the simulator
|
||||
front end is used to map 2G6 syntax into a call to this model in the
|
||||
required syntax.
|
||||
|
||||
This model may also be called directly as follows:
|
||||
|
||||
a1 [ <input(s)> ] <output> xxx
|
||||
.model xxx spice2poly ( coef = [ <list of 2G6 compatible coefficients> ] )
|
||||
|
||||
Refer to the 2G6 User Guide for an explanation of the coefficients.
|
||||
|
||||
|
||||
This model is patterned after the FORTRAN code used in the 2G6 simulator.
|
||||
Function cm_poly() below performs the functions of subroutines NLCSRC and
|
||||
EVPOLY. Function evterm() performs the function of subroutine EVTERM,
|
||||
and function nxtpwr() performs the function of subroutine NXTPWR.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
void *malloc(int);
|
||||
void free(void *);
|
||||
|
||||
/* SPICE 2G6 type utility functions */
|
||||
static double evterm(double x, int n);
|
||||
static void nxtpwr(int *pwrseq, int pdim);
|
||||
|
||||
|
||||
|
||||
|
||||
void spice2poly (Mif_Private_t *private)
|
||||
{
|
||||
int num_inputs; /* Number of inputs to model */
|
||||
int num_coefs; /* Number of coefficients */
|
||||
int *exp; /* List of exponents in products */
|
||||
/* One for each input */
|
||||
|
||||
int i; /* Counter */
|
||||
int j; /* Counter */
|
||||
int k; /* Counter */
|
||||
|
||||
double *in; /* Values of inputs to model */
|
||||
double *coef; /* Values of coefficients */
|
||||
|
||||
double sum; /* Temporary for accumulating sum of terms */
|
||||
double product; /* Temporary for accumulating product */
|
||||
|
||||
double *acgains; /* Static variable holding AC gains for AC analysis */
|
||||
|
||||
|
||||
/* Get number of input values */
|
||||
|
||||
num_inputs = private->conn[0]->size;
|
||||
|
||||
/* If this is the first call to the model, allocate the static variable */
|
||||
/* array */
|
||||
|
||||
if(private->circuit.init) {
|
||||
acgains = malloc(num_inputs * sizeof(double));
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
acgains[i] = 0.0;
|
||||
private->inst_var[0]->element[0].pvalue = acgains;
|
||||
}
|
||||
else
|
||||
acgains = private->inst_var[0]->element[0].pvalue;
|
||||
|
||||
/* If analysis type is AC, use the previously computed DC partials */
|
||||
/* for the AC gains */
|
||||
|
||||
if(private->circuit.anal_type == MIF_AC) {
|
||||
for(i = 0; i < num_inputs; i++) {
|
||||
acgains = private->inst_var[0]->element[0].pvalue;
|
||||
private->conn[1]->port[0]->ac_gain[0].port[i].real = acgains[i];
|
||||
private->conn[1]->port[0]->ac_gain[0].port[i].imag = 0.0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get input values and coefficients to local storage for faster access */
|
||||
|
||||
in = malloc(num_inputs * sizeof(double));
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
in[i] = private->conn[0]->port[i]->input.rvalue;
|
||||
|
||||
num_coefs = private->param[0]->size;
|
||||
|
||||
coef = malloc(num_coefs * sizeof(double));
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
coef[i] = private->param[0]->element[i].rvalue;
|
||||
|
||||
|
||||
/* Allocate the array of exponents used in computing the poly terms */
|
||||
exp = malloc(num_inputs * sizeof(int));
|
||||
|
||||
/* Initialize the exponents to zeros */
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
exp[i] = 0;
|
||||
|
||||
|
||||
/* Compute the output of the source by summing the required products */
|
||||
for(i = 1, sum = coef[0]; i < num_coefs; i++) {
|
||||
|
||||
/* Get the list of powers for the product terms in this term of the sum */
|
||||
nxtpwr(exp, num_inputs);
|
||||
|
||||
/* Form the product of the inputs taken to the required powers */
|
||||
for(j = 0, product = 1.0; j < num_inputs; j++)
|
||||
product *= evterm(in[j], exp[j]);
|
||||
|
||||
/* Add the product times the appropriate coefficient into the sum */
|
||||
sum += coef[i] * product;
|
||||
}
|
||||
private->conn[1]->port[0]->output.rvalue = sum;
|
||||
|
||||
|
||||
/* Compute and output the partials for each input */
|
||||
for(i = 0; i < num_inputs; i++) {
|
||||
|
||||
/* Reinitialize the exponent list to zeros */
|
||||
for(j = 0; j < num_inputs; j++)
|
||||
exp[j] = 0;
|
||||
|
||||
/* Compute the partials by summing the required products */
|
||||
for(j = 1, sum = 0.0; j < num_coefs; j++) {
|
||||
|
||||
/* Get the list of powers for the product terms in this term of the sum */
|
||||
nxtpwr(exp, num_inputs);
|
||||
|
||||
/* If power for input for which partial is being evaluated */
|
||||
/* is zero, the term is a constant, so the partial is zero */
|
||||
if(exp[i] == 0)
|
||||
continue;
|
||||
|
||||
/* Form the product of the inputs taken to the required powers */
|
||||
for(k = 0, product = 1.0; k < num_inputs; k++) {
|
||||
/* If input is not the one for which the partial is being taken */
|
||||
/* take the term to the specified exponent */
|
||||
if(k != i)
|
||||
product *= evterm(in[k], exp[k]);
|
||||
/* else, take the derivative of this term as n*x**(n-1) */
|
||||
else
|
||||
product *= exp[k] * evterm(in[k], exp[k] - 1);
|
||||
}
|
||||
|
||||
/* Add the product times the appropriate coefficient into the sum */
|
||||
sum += coef[j] * product;
|
||||
}
|
||||
|
||||
private->conn[1]->port[0]->partial[0].port[i] = sum;
|
||||
|
||||
/* If this is DC analysis, save the partial for use as AC gain */
|
||||
/* value in an AC analysis */
|
||||
|
||||
if(private->circuit.anal_type == MIF_DC)
|
||||
acgains[i] = sum;
|
||||
}
|
||||
|
||||
/* Free the allocated items and return */
|
||||
free(in);
|
||||
free(coef);
|
||||
free(exp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Function evterm computes the value of x**n */
|
||||
|
||||
static double evterm(
|
||||
double x,
|
||||
int n)
|
||||
{
|
||||
double product; /* Temporary accumlator for forming the product */
|
||||
|
||||
product = 1.0;
|
||||
while(n > 0) {
|
||||
product *= x;
|
||||
n--;
|
||||
}
|
||||
|
||||
return(product);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This function is a literal translation of subroutine NXTPWR in SPICE 2G6.
|
||||
This was done to guarantee compatibility with the ordering of
|
||||
coefficients used by 2G6. The 2G6 User Guide does not completely define
|
||||
the algorithm used and the GOTO loaded FORTRAN code is difficult to unravel.
|
||||
Therefore, a one-to-one translation was deemed the safest approach.
|
||||
|
||||
No attempt is made to document the function statements since no documentaton
|
||||
is available in the 2G6 code. However, it can be noted that the code
|
||||
appears to generate the exponents of the product terms in the sum-of-products
|
||||
produced by the following expansion for two and three dimensional polynomials:
|
||||
|
||||
2D (a + b) ** n
|
||||
3D (a + (b + c)) ** n
|
||||
|
||||
where n begins at 1 and increments as needed for as many terms as there are
|
||||
coefficients on the polynomial source SPICE deck card, and where terms that
|
||||
are identical under the laws of associativity are dropped. Thus, for example,
|
||||
the exponents for the following sums are produced:
|
||||
|
||||
2D a + b + a**2 + ab + b**2 + c**3 + ...
|
||||
3D a + b + c + a**2 + a*b + a*c + b**2 + bc + c**2 + a**3 + ...
|
||||
|
||||
*/
|
||||
|
||||
/* Define a macro to tranlate between FORTRAN-style array references */
|
||||
/* and C-style array references */
|
||||
|
||||
#define PWRSEQ(x) pwrseq[x - 1]
|
||||
|
||||
|
||||
static void nxtpwr(
|
||||
int *pwrseq, /* Array of exponents */
|
||||
int pdim)
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
int km1;
|
||||
int psum;
|
||||
|
||||
if(pdim == 1) goto stmt80;
|
||||
k = pdim;
|
||||
stmt10: if(PWRSEQ(k) != 0) goto stmt20;
|
||||
k = k - 1;
|
||||
if(k != 0) goto stmt10;
|
||||
goto stmt80;
|
||||
stmt20: if(k == pdim) goto stmt30;
|
||||
PWRSEQ(k) = PWRSEQ(k) - 1;
|
||||
PWRSEQ(k+1) = PWRSEQ(k+1) + 1;
|
||||
goto stmt100;
|
||||
stmt30: km1 = k - 1;
|
||||
for(i = 1; i <= km1; i++)
|
||||
if(PWRSEQ(i) != 0) goto stmt50;
|
||||
stmt40: PWRSEQ(1) = PWRSEQ(pdim) + 1;
|
||||
PWRSEQ(pdim) = 0;
|
||||
goto stmt100;
|
||||
stmt50: psum = 1;
|
||||
k = pdim;
|
||||
stmt60: if(PWRSEQ(k-1) >= 1) goto stmt70;
|
||||
psum = psum + PWRSEQ(k);
|
||||
PWRSEQ(k) = 0;
|
||||
k = k - 1;
|
||||
goto stmt60;
|
||||
stmt70: PWRSEQ(k) = PWRSEQ(k) + psum;
|
||||
PWRSEQ(k-1) = PWRSEQ(k-1) - 1;
|
||||
goto stmt100;
|
||||
stmt80: PWRSEQ(1) = PWRSEQ(1) + 1;
|
||||
|
||||
stmt100: return;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/* ===========================================================================
|
||||
FILE cfunc.mod
|
||||
|
||||
MEMBER OF process XSPICE
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the definition of a code model polynomial controlled
|
||||
source compatible with SPICE 2G6 poly sources.
|
||||
|
||||
INTERFACES
|
||||
|
||||
spice2poly()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
=========================================================================== */
|
||||
|
||||
/*
|
||||
|
||||
This code model implements the non-linear polynomial controlled sources
|
||||
available in SPICE 2G6. An automatic translator added into the simulator
|
||||
front end is used to map 2G6 syntax into a call to this model in the
|
||||
required syntax.
|
||||
|
||||
This model may also be called directly as follows:
|
||||
|
||||
a1 [ <input(s)> ] <output> xxx
|
||||
.model xxx spice2poly ( coef = [ <list of 2G6 compatible coefficients> ] )
|
||||
|
||||
Refer to the 2G6 User Guide for an explanation of the coefficients.
|
||||
|
||||
|
||||
This model is patterned after the FORTRAN code used in the 2G6 simulator.
|
||||
Function cm_poly() below performs the functions of subroutines NLCSRC and
|
||||
EVPOLY. Function evterm() performs the function of subroutine EVTERM,
|
||||
and function nxtpwr() performs the function of subroutine NXTPWR.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
void *malloc(int);
|
||||
void free(void *);
|
||||
|
||||
/* SPICE 2G6 type utility functions */
|
||||
static double evterm(double x, int n);
|
||||
static void nxtpwr(int *pwrseq, int pdim);
|
||||
|
||||
|
||||
|
||||
|
||||
void spice2poly (ARGS)
|
||||
{
|
||||
int num_inputs; /* Number of inputs to model */
|
||||
int num_coefs; /* Number of coefficients */
|
||||
int *exp; /* List of exponents in products */
|
||||
/* One for each input */
|
||||
|
||||
int i; /* Counter */
|
||||
int j; /* Counter */
|
||||
int k; /* Counter */
|
||||
|
||||
double *in; /* Values of inputs to model */
|
||||
double *coef; /* Values of coefficients */
|
||||
|
||||
double sum; /* Temporary for accumulating sum of terms */
|
||||
double product; /* Temporary for accumulating product */
|
||||
|
||||
double *acgains; /* Static variable holding AC gains for AC analysis */
|
||||
|
||||
|
||||
/* Get number of input values */
|
||||
|
||||
num_inputs = PORT_SIZE(in);
|
||||
|
||||
/* If this is the first call to the model, allocate the static variable */
|
||||
/* array */
|
||||
|
||||
if(INIT) {
|
||||
acgains = malloc(num_inputs * sizeof(double));
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
acgains[i] = 0.0;
|
||||
STATIC_VAR(acgains) = acgains;
|
||||
}
|
||||
else
|
||||
acgains = STATIC_VAR(acgains);
|
||||
|
||||
/* If analysis type is AC, use the previously computed DC partials */
|
||||
/* for the AC gains */
|
||||
|
||||
if(ANALYSIS == MIF_AC) {
|
||||
for(i = 0; i < num_inputs; i++) {
|
||||
acgains = STATIC_VAR(acgains);
|
||||
AC_GAIN(out,in[i]).real = acgains[i];
|
||||
AC_GAIN(out,in[i]).imag = 0.0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get input values and coefficients to local storage for faster access */
|
||||
|
||||
in = malloc(num_inputs * sizeof(double));
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
in[i] = INPUT(in[i]);
|
||||
|
||||
num_coefs = PARAM_SIZE(coef);
|
||||
|
||||
coef = malloc(num_coefs * sizeof(double));
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
coef[i] = PARAM(coef[i]);
|
||||
|
||||
|
||||
/* Allocate the array of exponents used in computing the poly terms */
|
||||
exp = malloc(num_inputs * sizeof(int));
|
||||
|
||||
/* Initialize the exponents to zeros */
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
exp[i] = 0;
|
||||
|
||||
|
||||
/* Compute the output of the source by summing the required products */
|
||||
for(i = 1, sum = coef[0]; i < num_coefs; i++) {
|
||||
|
||||
/* Get the list of powers for the product terms in this term of the sum */
|
||||
nxtpwr(exp, num_inputs);
|
||||
|
||||
/* Form the product of the inputs taken to the required powers */
|
||||
for(j = 0, product = 1.0; j < num_inputs; j++)
|
||||
product *= evterm(in[j], exp[j]);
|
||||
|
||||
/* Add the product times the appropriate coefficient into the sum */
|
||||
sum += coef[i] * product;
|
||||
}
|
||||
OUTPUT(out) = sum;
|
||||
|
||||
|
||||
/* Compute and output the partials for each input */
|
||||
for(i = 0; i < num_inputs; i++) {
|
||||
|
||||
/* Reinitialize the exponent list to zeros */
|
||||
for(j = 0; j < num_inputs; j++)
|
||||
exp[j] = 0;
|
||||
|
||||
/* Compute the partials by summing the required products */
|
||||
for(j = 1, sum = 0.0; j < num_coefs; j++) {
|
||||
|
||||
/* Get the list of powers for the product terms in this term of the sum */
|
||||
nxtpwr(exp, num_inputs);
|
||||
|
||||
/* If power for input for which partial is being evaluated */
|
||||
/* is zero, the term is a constant, so the partial is zero */
|
||||
if(exp[i] == 0)
|
||||
continue;
|
||||
|
||||
/* Form the product of the inputs taken to the required powers */
|
||||
for(k = 0, product = 1.0; k < num_inputs; k++) {
|
||||
/* If input is not the one for which the partial is being taken */
|
||||
/* take the term to the specified exponent */
|
||||
if(k != i)
|
||||
product *= evterm(in[k], exp[k]);
|
||||
/* else, take the derivative of this term as n*x**(n-1) */
|
||||
else
|
||||
product *= exp[k] * evterm(in[k], exp[k] - 1);
|
||||
}
|
||||
|
||||
/* Add the product times the appropriate coefficient into the sum */
|
||||
sum += coef[j] * product;
|
||||
}
|
||||
|
||||
PARTIAL(out,in[i]) = sum;
|
||||
|
||||
/* If this is DC analysis, save the partial for use as AC gain */
|
||||
/* value in an AC analysis */
|
||||
|
||||
if(ANALYSIS == MIF_DC)
|
||||
acgains[i] = sum;
|
||||
}
|
||||
|
||||
/* Free the allocated items and return */
|
||||
free(in);
|
||||
free(coef);
|
||||
free(exp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Function evterm computes the value of x**n */
|
||||
|
||||
static double evterm(
|
||||
double x,
|
||||
int n)
|
||||
{
|
||||
double product; /* Temporary accumlator for forming the product */
|
||||
|
||||
product = 1.0;
|
||||
while(n > 0) {
|
||||
product *= x;
|
||||
n--;
|
||||
}
|
||||
|
||||
return(product);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This function is a literal translation of subroutine NXTPWR in SPICE 2G6.
|
||||
This was done to guarantee compatibility with the ordering of
|
||||
coefficients used by 2G6. The 2G6 User Guide does not completely define
|
||||
the algorithm used and the GOTO loaded FORTRAN code is difficult to unravel.
|
||||
Therefore, a one-to-one translation was deemed the safest approach.
|
||||
|
||||
No attempt is made to document the function statements since no documentaton
|
||||
is available in the 2G6 code. However, it can be noted that the code
|
||||
appears to generate the exponents of the product terms in the sum-of-products
|
||||
produced by the following expansion for two and three dimensional polynomials:
|
||||
|
||||
2D (a + b) ** n
|
||||
3D (a + (b + c)) ** n
|
||||
|
||||
where n begins at 1 and increments as needed for as many terms as there are
|
||||
coefficients on the polynomial source SPICE deck card, and where terms that
|
||||
are identical under the laws of associativity are dropped. Thus, for example,
|
||||
the exponents for the following sums are produced:
|
||||
|
||||
2D a + b + a**2 + ab + b**2 + c**3 + ...
|
||||
3D a + b + c + a**2 + a*b + a*c + b**2 + bc + c**2 + a**3 + ...
|
||||
|
||||
*/
|
||||
|
||||
/* Define a macro to tranlate between FORTRAN-style array references */
|
||||
/* and C-style array references */
|
||||
|
||||
#define PWRSEQ(x) pwrseq[x - 1]
|
||||
|
||||
|
||||
static void nxtpwr(
|
||||
int *pwrseq, /* Array of exponents */
|
||||
int pdim)
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
int km1;
|
||||
int psum;
|
||||
|
||||
if(pdim == 1) goto stmt80;
|
||||
k = pdim;
|
||||
stmt10: if(PWRSEQ(k) != 0) goto stmt20;
|
||||
k = k - 1;
|
||||
if(k != 0) goto stmt10;
|
||||
goto stmt80;
|
||||
stmt20: if(k == pdim) goto stmt30;
|
||||
PWRSEQ(k) = PWRSEQ(k) - 1;
|
||||
PWRSEQ(k+1) = PWRSEQ(k+1) + 1;
|
||||
goto stmt100;
|
||||
stmt30: km1 = k - 1;
|
||||
for(i = 1; i <= km1; i++)
|
||||
if(PWRSEQ(i) != 0) goto stmt50;
|
||||
stmt40: PWRSEQ(1) = PWRSEQ(pdim) + 1;
|
||||
PWRSEQ(pdim) = 0;
|
||||
goto stmt100;
|
||||
stmt50: psum = 1;
|
||||
k = pdim;
|
||||
stmt60: if(PWRSEQ(k-1) >= 1) goto stmt70;
|
||||
psum = psum + PWRSEQ(k);
|
||||
PWRSEQ(k) = 0;
|
||||
k = k - 1;
|
||||
goto stmt60;
|
||||
stmt70: PWRSEQ(k) = PWRSEQ(k) + psum;
|
||||
PWRSEQ(k-1) = PWRSEQ(k-1) - 1;
|
||||
goto stmt100;
|
||||
stmt80: PWRSEQ(1) = PWRSEQ(1) + 1;
|
||||
|
||||
stmt100: return;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
/*
|
||||
* Structures for model: spice2poly
|
||||
*
|
||||
* Automatically generated by cmpp preprocessor
|
||||
*
|
||||
* !!! DO NOT EDIT !!!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// #include "prefix.h"
|
||||
#include <stdio.h>
|
||||
#include "ngspice.h"
|
||||
#include "devdefs.h"
|
||||
#include "ifsim.h"
|
||||
#include "mifdefs.h"
|
||||
#include "mifproto.h"
|
||||
#include "mifparse.h"
|
||||
// #include "suffix.h"
|
||||
|
||||
|
||||
static IFparm MIFmPTable[] = {
|
||||
IOP("coef", 0, (IF_REAL|IF_VECTOR), "2g6 compatible spice card coefficient list"),
|
||||
};
|
||||
|
||||
|
||||
static IFparm MIFpTable[] = {
|
||||
OP("acgains", 1, IF_STRING, "partial derivatives from dc analysis used for ac gains"),
|
||||
};
|
||||
|
||||
|
||||
static Mif_Port_Type_t MIFportEnum0[] = {
|
||||
MIF_DIFF_VOLTAGE,
|
||||
MIF_DIFF_CURRENT,
|
||||
MIF_VSOURCE_CURRENT,
|
||||
};
|
||||
|
||||
|
||||
static char *MIFportStr0[] = {
|
||||
"vd",
|
||||
"id",
|
||||
"vnam",
|
||||
};
|
||||
|
||||
|
||||
static Mif_Port_Type_t MIFportEnum1[] = {
|
||||
MIF_DIFF_VOLTAGE,
|
||||
MIF_DIFF_CURRENT,
|
||||
};
|
||||
|
||||
|
||||
static char *MIFportStr1[] = {
|
||||
"vd",
|
||||
"id",
|
||||
};
|
||||
|
||||
|
||||
static Mif_Conn_Info_t MIFconnTable[] = {
|
||||
{
|
||||
"in",
|
||||
"input",
|
||||
MIF_IN,
|
||||
MIF_DIFF_VOLTAGE,
|
||||
"vd",
|
||||
3,
|
||||
MIFportEnum0,
|
||||
MIFportStr0,
|
||||
MIF_TRUE,
|
||||
MIF_TRUE,
|
||||
1,
|
||||
MIF_FALSE,
|
||||
0,
|
||||
MIF_FALSE,
|
||||
},
|
||||
{
|
||||
"out",
|
||||
"output",
|
||||
MIF_OUT,
|
||||
MIF_DIFF_VOLTAGE,
|
||||
"vd",
|
||||
2,
|
||||
MIFportEnum1,
|
||||
MIFportStr1,
|
||||
MIF_FALSE,
|
||||
MIF_FALSE,
|
||||
0,
|
||||
MIF_FALSE,
|
||||
0,
|
||||
MIF_FALSE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static Mif_Param_Info_t MIFparamTable[] = {
|
||||
{
|
||||
"coef",
|
||||
"2g6 compatible spice card coefficient list",
|
||||
MIF_REAL,
|
||||
MIF_FALSE,
|
||||
{MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL},
|
||||
MIF_FALSE,
|
||||
{MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL},
|
||||
MIF_FALSE,
|
||||
{MIF_FALSE, 0, 0.0, {0.0, 0.0}, NULL},
|
||||
MIF_TRUE,
|
||||
MIF_FALSE,
|
||||
0,
|
||||
MIF_TRUE,
|
||||
2,
|
||||
MIF_FALSE,
|
||||
0,
|
||||
MIF_FALSE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static Mif_Inst_Var_Info_t MIFinst_varTable[] = {
|
||||
{
|
||||
"acgains",
|
||||
"partial derivatives from dc analysis used for ac gains",
|
||||
MIF_STRING,
|
||||
MIF_FALSE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
extern void spice2poly(Mif_Private_t *);
|
||||
|
||||
static int val_terms = 0;
|
||||
static int val_numNames = 0;
|
||||
static int val_numInstanceParms = 1;
|
||||
static int val_numModelParms = 1;
|
||||
static int val_sizeofMIFinstance = sizeof(MIFinstance);
|
||||
static int val_sizeofMIFmodel = sizeof(MIFmodel);
|
||||
|
||||
SPICEdev spice2poly_info = {
|
||||
{ "spice2poly",
|
||||
"2g6 compatible polynomial controlled source",
|
||||
&val_terms,
|
||||
&val_numNames,
|
||||
NULL,
|
||||
&val_numInstanceParms,
|
||||
MIFpTable,
|
||||
&val_numModelParms,
|
||||
MIFmPTable,
|
||||
spice2poly,
|
||||
2,
|
||||
MIFconnTable,
|
||||
1,
|
||||
MIFparamTable,
|
||||
1,
|
||||
MIFinst_varTable,
|
||||
},
|
||||
NULL,
|
||||
MIFmParam,
|
||||
MIFload,
|
||||
MIFsetup,
|
||||
NULL, /* removed by sdb MIFunsetup, */
|
||||
NULL,
|
||||
NULL,
|
||||
MIFtrunc,
|
||||
NULL,
|
||||
MIFload,
|
||||
NULL,
|
||||
MIFdestroy,
|
||||
MIFmDelete,
|
||||
MIFdelete,
|
||||
NULL,
|
||||
MIFask,
|
||||
MIFmAsk,
|
||||
NULL,
|
||||
MIFconvTest,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&val_sizeofMIFinstance,
|
||||
&val_sizeofMIFmodel,
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* ===========================================================================
|
||||
FILE ifspec.ifs
|
||||
|
||||
MEMBER OF process XSPICE
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the definition of a code model polynomial controlled
|
||||
source compatible with SPICE 2G6 poly sources.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
=========================================================================== */
|
||||
|
||||
NAME_TABLE:
|
||||
|
||||
Spice_Model_Name: spice2poly
|
||||
C_Function_Name: spice2poly
|
||||
Description: "2G6 compatible polynomial controlled source"
|
||||
|
||||
|
||||
PORT_TABLE:
|
||||
|
||||
Port_Name: in out
|
||||
Description: "input" "output"
|
||||
Direction: in out
|
||||
Default_Type: vd vd
|
||||
Allowed_Types: [vd,id,vnam] [vd,id]
|
||||
Vector: yes no
|
||||
Vector_Bounds: [1 -] -
|
||||
Null_Allowed: no no
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: coef
|
||||
Description: "2G6 compatible spice card coefficient list"
|
||||
Data_Type: real
|
||||
Default_Value: -
|
||||
Limits: -
|
||||
Vector: yes
|
||||
Vector_Bounds: [2 -]
|
||||
Null_Allowed: no
|
||||
|
||||
|
||||
STATIC_VAR_TABLE:
|
||||
|
||||
Static_Var_Name: acgains
|
||||
Data_Type: pointer
|
||||
Description: "Partial derivatives from DC analysis used for AC gains"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
cmpp -mod cfunc.mod
|
||||
cmpp -ifs
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
icm_spice2poly
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
icm_spice2poly/*.o
|
||||
Binary file not shown.
|
|
@ -39,10 +39,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
#include "mif.h"
|
||||
|
||||
/* jgroves */
|
||||
|
||||
int MIFiSize = sizeof(MIFinstance); /* jgroves */
|
||||
int MIFmSize = sizeof(MIFmodel); /* jgroves */
|
||||
int MIFiSize = sizeof(MIFinstance);
|
||||
int MIFmSize = sizeof(MIFmodel);
|
||||
|
||||
|
||||
/* Allocate global used to pass info on analysis type, etc. from */
|
||||
|
|
|
|||
|
|
@ -195,8 +195,8 @@ card *current; /* the card we are to parse */
|
|||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In MIF_INP2A, after tokenizing, name = %s, model = %s\n",
|
||||
name, model);
|
||||
printf("In MIF_INP2A, about to get ports on line %s\n",
|
||||
current->line);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -231,20 +231,21 @@ card *current; /* the card we are to parse */
|
|||
/* and reading the first token following */
|
||||
|
||||
line = current->line;
|
||||
MIFgettok(&line);
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
|
||||
|
||||
/* loop through the fixed number of connections expected */
|
||||
MIFgettok(&line); /* read instance name again . . . .*/
|
||||
|
||||
/******* loop through the fixed number of connections expected *******/
|
||||
for(i = 0; i < DEVices[type]->DEVpublic.num_conn; i++) {
|
||||
|
||||
/* there better be at least one more token besides the model name */
|
||||
if(*line == '\0') {
|
||||
LITERR("Missing connections on A device");
|
||||
LITERR("Encountered end of line before all connections were found in model.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* now get next token, should be a % after this statement */
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
|
||||
|
||||
/* prepare a pointer for fast access to info about this connection */
|
||||
conn_info = &(DEVices[type]->DEVpublic.conn[i]);
|
||||
|
||||
|
|
@ -252,6 +253,34 @@ card *current; /* the card we are to parse */
|
|||
def_port_type = conn_info->default_port_type;
|
||||
def_port_type_str = conn_info->default_type;
|
||||
|
||||
|
||||
/* Now get real info about connection type (instead of default info) */
|
||||
if(next_token_type == MIF_PERCENT_TOK) { /* next_token_type should be a % */
|
||||
|
||||
/* get the port type identifier and check it for validity */
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
MIFget_port_type(ckt,
|
||||
tab,
|
||||
current,
|
||||
&line,
|
||||
&next_token,
|
||||
&next_token_type,
|
||||
&def_port_type,
|
||||
&def_port_type_str,
|
||||
conn_info,
|
||||
&status);
|
||||
if(status == MIF_ERROR)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
LITERR("Non percent token encountered when expecting MIF_PERCENT_TOK");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* At this point, next_token should hold the token *after* the port type
|
||||
identified (%v, %id, etc). */
|
||||
|
||||
/* set analog and event_driven flags on instance and model */
|
||||
if((def_port_type == MIF_DIGITAL) || (def_port_type == MIF_USER_DEFINED)) {
|
||||
fast->event_driven = MIF_TRUE;
|
||||
|
|
@ -262,8 +291,8 @@ card *current; /* the card we are to parse */
|
|||
mdfast->analog = MIF_TRUE;
|
||||
}
|
||||
|
||||
/* check for a null connection and continue to next connection if found */
|
||||
|
||||
/* check for a null connection and continue to next connection if found */
|
||||
if(next_token_type == MIF_NULL_TOK) {
|
||||
|
||||
/* make sure null is allowed */
|
||||
|
|
@ -285,10 +314,13 @@ card *current; /* the card we are to parse */
|
|||
fast->conn[i]->is_null = MIF_FALSE;
|
||||
}
|
||||
|
||||
/* process connection as appropriate for scalar or array */
|
||||
|
||||
|
||||
/* ===== process connection as appropriate for scalar or array ====== */
|
||||
if(! conn_info->is_array) { /* a scalar connection - the simpler case */
|
||||
|
||||
/* At this point, next_token should hold the first netname in the port netlist. */
|
||||
|
||||
/* do a couple of error checks */
|
||||
if(next_token_type == MIF_LARRAY_TOK) {
|
||||
LITERR("ERROR - Scalar connection expected, [ found");
|
||||
|
|
@ -315,44 +347,27 @@ card *current; /* the card we are to parse */
|
|||
0, /* port index for scalar connection */
|
||||
&status);
|
||||
|
||||
/* upon leaving MIFget_port, we should be *ready* to read a % with the next
|
||||
get_token */
|
||||
|
||||
if(status == MIF_ERROR)
|
||||
return;
|
||||
|
||||
fast->conn[i]->size = 1;
|
||||
}
|
||||
else { /* the connection is an array - much to be done ... */
|
||||
else { /* ====== the connection is an array - much to be done ... ====== */
|
||||
|
||||
/* get the leading port type for the array if any */
|
||||
/* it will distribute across all ports inside the braces */
|
||||
/* overriding the default type in the interface spec */
|
||||
|
||||
if(next_token_type == MIF_PERCENT_TOK) {
|
||||
|
||||
/* get the port type identifier and check it for validity */
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
MIFget_port_type(ckt,
|
||||
tab,
|
||||
current,
|
||||
&line,
|
||||
&next_token,
|
||||
&next_token_type,
|
||||
&def_port_type,
|
||||
&def_port_type_str,
|
||||
conn_info,
|
||||
&status);
|
||||
if(status == MIF_ERROR)
|
||||
return;
|
||||
}
|
||||
/* At this point, the next_token should be a [ */
|
||||
|
||||
/* check for required leading array delim character and eat it if found */
|
||||
if(next_token_type != MIF_LARRAY_TOK) {
|
||||
LITERR("Missing [, an array connection was expected");
|
||||
return;
|
||||
}
|
||||
else
|
||||
else /* eat the [ */
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
|
||||
/* get and process ports until ] is encountered */
|
||||
/*------ get and process ports until ] is encountered ------*/
|
||||
|
||||
for(j = 0;
|
||||
(next_token_type != MIF_RARRAY_TOK) &&
|
||||
|
|
@ -386,16 +401,24 @@ card *current; /* the card we are to parse */
|
|||
|
||||
if(status == MIF_ERROR)
|
||||
return;
|
||||
}
|
||||
} /*------ end of for loop until ] is encountered ------*/
|
||||
|
||||
/* At this point, next_token should hold the next token after the
|
||||
port netnames. This token should be a ]. */
|
||||
|
||||
/* make sure we exited because the end of the array connection */
|
||||
/* was reached. If so, eat the closing array delimiter */
|
||||
/* was reached. If so, eat the closing array delimiter ] */
|
||||
if(*line == '\0') {
|
||||
LITERR("Missing ] in array connection");
|
||||
return;
|
||||
}
|
||||
else
|
||||
next_token = MIFget_token(&line,&next_token_type);
|
||||
|
||||
/* else {
|
||||
* next_token = MIFget_token(&line,&next_token_type);
|
||||
* }
|
||||
*/
|
||||
|
||||
/* At this point, the next time we get_token, we should get a % */
|
||||
|
||||
/* record the number of ports found for this connection */
|
||||
if(j < 1) {
|
||||
|
|
@ -404,12 +427,13 @@ card *current; /* the card we are to parse */
|
|||
}
|
||||
fast->conn[i]->size = j;
|
||||
|
||||
} /* array connection processing */
|
||||
} /* ====== array connection processing ====== */
|
||||
|
||||
/* be careful about putting stuff here, there is a 'continue' used */
|
||||
/* in the processing of NULL connections above */
|
||||
|
||||
} /* for number of connections */
|
||||
|
||||
} /******* for number of connections *******/
|
||||
|
||||
|
||||
/* *********************** */
|
||||
|
|
@ -418,8 +442,12 @@ card *current; /* the card we are to parse */
|
|||
|
||||
/* check for too many connections */
|
||||
|
||||
if(*line != '\0') {
|
||||
LITERR("Too many connections");
|
||||
/* At this point, we should have eaten all the net connections. At
|
||||
this point, line should hold only the remainder of the model line (i.e.
|
||||
the model name). */
|
||||
|
||||
if(strcmp(line,name) != 0) {
|
||||
LITERR("Too many connections -- expecting model name but encountered other tokens.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -586,7 +614,17 @@ static void MIFinit_inst(
|
|||
/*
|
||||
MIFget_port_type
|
||||
|
||||
This function gets the port type identifier and checks it for validity.
|
||||
This function gets the port type identifier and checks it for validity. It also
|
||||
replaces false default information in conn_info with the real info based upon
|
||||
the discovered port type string.
|
||||
|
||||
When we call it, we expect that the next token type (sent from above)
|
||||
should be the port type (MIF_STRING_TOK type). That is, we should be sitting right
|
||||
on the def of the port type (i.e. %vnam, %vd, %id, etc.) Note that the parser
|
||||
should have stripped the % already.
|
||||
|
||||
Upon return, this fcn should leave next_token holding the token *after* the
|
||||
port type (i.e. the thing after vnam, v, vd, id, etc).
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -643,8 +681,20 @@ MIFget_port_type(
|
|||
LITERR("Port type is invalid");
|
||||
*status = MIF_ERROR;
|
||||
}
|
||||
else
|
||||
else {
|
||||
|
||||
/* Fix by SDB so that the netlist parser uses the actual nature
|
||||
of the port instead of the default state to decide if it is an array. */
|
||||
if ( (*port_type == MIF_DIFF_VOLTAGE) ||
|
||||
(*port_type == MIF_DIFF_CURRENT) ||
|
||||
(*port_type == MIF_DIFF_CONDUCTANCE) ||
|
||||
(*port_type == MIF_DIFF_RESISTANCE) ) {
|
||||
conn_info->is_array = 1;
|
||||
}
|
||||
|
||||
*status = MIF_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -658,6 +708,13 @@ MIFget_port
|
|||
|
||||
This function processes a port being parsed, either single ended,
|
||||
or both connections of a differential.
|
||||
|
||||
When we call this fcn, next_token should be the *first* netname in the port
|
||||
net list. Depending upon the type of port, this fcn should eat the appropriate
|
||||
number of net tokens.
|
||||
|
||||
When we leave this fcn, next_token should hold the next token after the last
|
||||
netname processed.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -687,27 +744,6 @@ MIFget_port(
|
|||
|
||||
char *node;
|
||||
|
||||
/* get the leading port type if any */
|
||||
|
||||
if(*next_token_type == MIF_PERCENT_TOK) {
|
||||
|
||||
/* get the port type identifier and check it for validity */
|
||||
*next_token = MIFget_token(line, next_token_type);
|
||||
MIFget_port_type(ckt,
|
||||
tab,
|
||||
current,
|
||||
line,
|
||||
next_token,
|
||||
next_token_type,
|
||||
&def_port_type,
|
||||
&def_port_type_str,
|
||||
conn_info,
|
||||
status);
|
||||
|
||||
if(*status == MIF_ERROR) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate space in the instance data struct for this port */
|
||||
if(port_num == 0) {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
#include "suffix.h"
|
||||
|
||||
|
||||
/* This is the table of all models known to the program. */
|
||||
/* It is now defined in inpdefs.h 6.19.2003 -- SDB. */
|
||||
extern INPmodel *modtab;
|
||||
|
||||
extern SPICEdev **DEVices; /* info about all device types */
|
||||
|
|
@ -111,20 +112,29 @@ char *MIFgetMod(
|
|||
MIFmodel *mdfast;
|
||||
/* Mif_Param_Info_t *param_info;*/
|
||||
|
||||
/* locate the named model in the modtab list */
|
||||
|
||||
/* =========== First locate the named model in the modtab list ================= */
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In MIFgetMod, model name = %s . . .\n", name);
|
||||
printf("In MIFgetMod, looking for model name = %s . . .\n", name);
|
||||
#endif
|
||||
|
||||
/* maschmann : remove : from name */
|
||||
/* maschmann : remove : from name
|
||||
* char *pos;
|
||||
* if((pos=strstr(name,":"))!=NULL) *pos=0;
|
||||
*/
|
||||
|
||||
/* char *pos;
|
||||
/*------------------------------------
|
||||
for (i = &modtab; *i != (INPmodel *) NULL; i = &((*i)->INPnextModel)) {
|
||||
if (strcmp((*i)->INPmodName, token) == 0) {
|
||||
return (OK);
|
||||
}
|
||||
}
|
||||
--------------------------*/
|
||||
|
||||
if((pos=strstr(name,":"))!=NULL) *pos=0; */
|
||||
|
||||
for (modtmp = modtab; modtmp != NULL; modtmp = ((modtmp)->INPnextModel)) {
|
||||
/* loop through modtable looking for this model (*name) */
|
||||
for (modtmp = modtab; modtmp != NULL; modtmp = ((modtmp)->INPnextModel) ) {
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
|
|
@ -133,13 +143,16 @@ char *MIFgetMod(
|
|||
|
||||
if (strcmp((modtmp)->INPmodName,name) == 0) {
|
||||
|
||||
#ifdef TRACE
|
||||
/* SDB debug statement */
|
||||
printf("In MIFgetMod, found model!!!\n");
|
||||
#endif
|
||||
|
||||
|
||||
/* found the model in question - now instantiate if necessary */
|
||||
/* and return an appropriate pointer to it */
|
||||
/* ========= found the model in question - now instantiate if necessary ========== */
|
||||
/* ============== and return an appropriate pointer to it ===================== */
|
||||
|
||||
/* make sure the type is valid before proceeding */
|
||||
if(modtmp->INPmodType<0) {
|
||||
if( (modtmp)->INPmodType < 0) {
|
||||
/* illegal device type, so can't handle */
|
||||
*model = NULL;
|
||||
|
||||
|
|
@ -213,7 +226,7 @@ char *MIFgetMod(
|
|||
//err has not been allocated, but free() in INPerrCat()
|
||||
|
||||
// This did not allocate enough memory you wanker, K.A. replaced 5 March 2000
|
||||
// temp = (char *)tmalloc((40+strlen(parm)) * sizeof(char));
|
||||
// temp = (char *)tmalloc((40+strlen(parm)) * sizeof(char));
|
||||
temp = (char *)tmalloc((42+strlen(parm)) * sizeof(char));// K.A. replaced 5 March 2000
|
||||
|
||||
sprintf(temp, "MIF: unrecognized parameter (%s) - ignored\n", parm);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ is advanced to the following token and the token from the input
|
|||
string is copied to malloced storage and a pointer to that storage
|
||||
is returned. The original input string is undisturbed.
|
||||
|
||||
MIFgettok treats ( and ) like whitespace.
|
||||
|
||||
*/
|
||||
|
||||
char *MIFgettok(char **s)
|
||||
|
|
@ -140,8 +142,8 @@ char *MIFgettok(char **s)
|
|||
(*s)++;
|
||||
|
||||
/* make a copy using only the space needed by the string length */
|
||||
|
||||
ret_str = copy(buf);
|
||||
/* Changed from copy to MIFcopy by SDB on 6.22.2003 */
|
||||
ret_str = MIFcopy(buf);
|
||||
FREE(buf);
|
||||
|
||||
return(ret_str);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = resistance filters polezero bsim3soipd bsim3soifd bsim3soidd bsim4 mesa
|
||||
SUBDIRS = resistance filters polezero bsim3soipd bsim3soifd bsim3soidd bsim4 mesa TransImpedanceAmp
|
||||
|
||||
TESTS = \
|
||||
diffpair.cir \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
TESTS = \
|
||||
output.net
|
||||
|
||||
TESTS_ENVIRONMENT = $(SHELL) $(srcdir)/../check.sh $(top_builddir)/src/ngspice
|
||||
|
||||
EXTRA_DIST = output.net README
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
This directory holds a SPICE netlist with SPICE2 POLY constructs in
|
||||
controlled sources as typically found in vendor models. The circuit
|
||||
is just a two-stage transimpedance amp using an AD8009,
|
||||
along with some slow components (AD780 and OP177A) to set bias
|
||||
points. Vendor models are used for all active components.
|
||||
Successfully running this test shows that you have successfully built
|
||||
the XSpice stuff with the POLY codemodel, and that you should be able
|
||||
to simulate SPICE netlists with embedded vendor models.
|
||||
|
||||
To run this netlist, just do the following:
|
||||
|
||||
[localhost]# ngspice
|
||||
ngspice 1 -> source output.net
|
||||
ngspice 2 -> run
|
||||
ngspice 3 -> plot Vout2
|
||||
|
||||
(Note that when you read in the netlist, you will get a bunch of
|
||||
warnings saying stuff like:
|
||||
|
||||
Warning -- Level not specified on line "()"
|
||||
Using level 1.
|
||||
|
||||
Also, ngspice will complain about:
|
||||
|
||||
Error on line 50 : r:u101:1 u101:40 0 1e3 tc=7e-6
|
||||
unknown parameter (tc)
|
||||
Error on line 283 : .temp 0 25 50 75 100
|
||||
Warning: .TEMP card obsolete - use .options TEMP and TNOM
|
||||
|
||||
You can ignore all this stuff . . . .)
|
||||
|
||||
You should get a pop-up window showing two square pulses (the second
|
||||
smaller than the first) with a little bit of overshoot on the rising
|
||||
and falling edges.
|
||||
|
||||
This stuff was done as an adjunct to work on the gEDA project.
|
||||
Information about gEDA is available at http://geda.seul.org/ .
|
||||
Please direct all questions/suggestions/bugs/complaints about XSpice
|
||||
extensions to ngspice to Stuart Brorson -- mailto:sdb@cloud9.net.
|
||||
|
||||
6.23.2002 -- SDB.
|
||||
|
|
@ -0,0 +1,453 @@
|
|||
*********************************************************
|
||||
* Spice file generated by gnetlist *
|
||||
* spice-SDB version 3.30.2003 by SDB -- *
|
||||
* provides advanced spice netlisting capability. *
|
||||
* Documentation at http://www.brorson.com/gEDA/SPICE/ *
|
||||
*********************************************************
|
||||
* Command stuff
|
||||
.options gmin=1e-9
|
||||
.options abstol=1e-11
|
||||
* .ac dec 10 10MegHz 10 Ghz
|
||||
* Remainder of file
|
||||
R112 0 6 1Meg
|
||||
R111 0 8 10Meg
|
||||
R110 0 7 1Meg
|
||||
Rref2in 11 VU780out 25000
|
||||
Rref2fb VU2bias+ 11 33
|
||||
C201 0 9 1uF
|
||||
C202 10 0 1uF
|
||||
XU200 0 11 10 9 VU2bias+ OP177A
|
||||
R202 10 +5V 22
|
||||
R201 -5V 9 22
|
||||
Rref1in VU100in- VU780out 9130
|
||||
Rref1fb VU1bias+ VU100in- 33
|
||||
XU101 +5V 7 0 6 VU780out 8 AD780A
|
||||
* AD780A SPICE Macromodel 5/93, Rev. A
|
||||
* AAG / PMI
|
||||
*
|
||||
* This version of the AD780 voltage reference model simulates the worst case
|
||||
* parameters of the 'A' grade. The worst case parameters used
|
||||
* correspond to those in the data sheet.
|
||||
*
|
||||
* Copyright 1993 by Analog Devices, Inc.
|
||||
*
|
||||
* Refer to "README.DOC" file for License Statement. Use of this model
|
||||
* indicates your acceptance with the terms and provisions in the License Statement.
|
||||
*
|
||||
* NODE NUMBERS
|
||||
* VIN
|
||||
* | TEMP
|
||||
* | | GND
|
||||
* | | | TRIM
|
||||
* | | | | VOUT
|
||||
* | | | | | RANGE
|
||||
* | | | | | |
|
||||
.SUBCKT AD780A 2 3 4 5 6 8
|
||||
*
|
||||
* BANDGAP REFERENCE
|
||||
*
|
||||
I1 4 40 DC 1.21174E-3
|
||||
R1 40 4 1E3 TC=7E-6
|
||||
EN 10 40 42 0 1
|
||||
G1 4 10 2 4 4.85668E-9
|
||||
F1 4 10 POLY(2) VS1 VS2 (0,2.42834E-5,3.8E-5)
|
||||
Q1 2 10 11 QT
|
||||
I2 11 4 DC 12.84E-6
|
||||
R2 11 3 1E3
|
||||
I3 3 4 DC 0
|
||||
*
|
||||
* NOISE VOLTAGE GENERATOR
|
||||
*
|
||||
VN1 41 0 DC 2
|
||||
DN1 41 42 DEN
|
||||
DN2 42 43 DEN
|
||||
VN2 0 43 DC 2
|
||||
*
|
||||
* INTERNAL OP AMP
|
||||
*
|
||||
G2 4 12 10 20 1.93522E-4
|
||||
R3 12 4 2.5837E9
|
||||
C1 12 4 6.8444E-11
|
||||
D1 12 13 DX
|
||||
V1 2 13 DC 1.2
|
||||
*
|
||||
* SECONDARY POLE @ 508 kHz
|
||||
*
|
||||
G3 4 14 12 4 1E-6
|
||||
R4 14 4 1E6
|
||||
C2 14 4 3.1831E-13
|
||||
*
|
||||
* OUTPUT STAGE
|
||||
*
|
||||
ISY 2 4 6.8282E-4
|
||||
FSY 2 4 V1 -1
|
||||
RSY 2 4 500E3
|
||||
*
|
||||
G4 4 15 14 4 25E-6
|
||||
R5 15 4 40E3
|
||||
Q2 4 15 16 QP
|
||||
I4 2 16 DC 100E-6
|
||||
Q3 4 16 18 QP
|
||||
R6 18 23 15
|
||||
R7 16 21 150E3
|
||||
R8 2 17 34.6
|
||||
Q4 17 16 19 QN
|
||||
R9 21 20 6.46E3
|
||||
R10 20 4 6.1E3
|
||||
R11 20 5 53E3
|
||||
R12 20 8 15.6E3
|
||||
I5 5 4 DC 0
|
||||
I6 8 4 DC 0
|
||||
VS1 21 19 DC 0
|
||||
VS2 23 21 DC 0
|
||||
L1 21 6 1E-7
|
||||
*
|
||||
* OUTPUT CURRENT LIMIT
|
||||
*
|
||||
FSC 15 4 VSC 1
|
||||
VSC 2 22 DC 0
|
||||
QSC 22 2 17 QN
|
||||
*
|
||||
.MODEL QT NPN(IS=1.68E-16 BF=1E4)
|
||||
.MODEL QN NPN(IS=1E-15 BF=1E3)
|
||||
.MODEL QP PNP(IS=1E-15 BF=1E3)
|
||||
.MODEL DX D(IS=1E-15)
|
||||
.MODEL DEN D(IS=1E-12 RS=2.425E+05 AF=1 KF=6.969E-16)
|
||||
.ENDS AD780A
|
||||
C101 0 U100V- 1uF
|
||||
C102 U100V+ 0 1uF
|
||||
XU100 0 VU100in- U100V+ U100V- VU1bias+ OP177A
|
||||
* OP177A SPICE Macro-model 12/90, Rev. B
|
||||
* JCB / PMI
|
||||
*
|
||||
* Revision History:
|
||||
* REV. B
|
||||
* Re-ordered subcircuit call out nodes to put the
|
||||
* output node last.
|
||||
* Changed Ios from 1E-9 to 0.5E-9
|
||||
* Added F1 and F2 to fix short circuit current limit.
|
||||
*
|
||||
*
|
||||
* This version of the OP-177 model simulates the worst case
|
||||
* parameters of the 'A' grade. The worst case parameters
|
||||
* used correspond to those in the data book.
|
||||
*
|
||||
*
|
||||
* Copyright 1990 by Analog Devices, Inc.
|
||||
*
|
||||
* Refer to "README.DOC" file for License Statement. Use of this model
|
||||
* indicates your acceptance with the terms and provisions in the License Statement.
|
||||
*
|
||||
* Node assignments
|
||||
* non-inverting input
|
||||
* | inverting input
|
||||
* | | positive supply
|
||||
* | | | negative supply
|
||||
* | | | | output
|
||||
* | | | | |
|
||||
.SUBCKT OP177A 1 2 99 50 39
|
||||
*
|
||||
* INPUT STAGE & POLE AT 6 MHZ
|
||||
*
|
||||
R1 2 3 5E11
|
||||
R2 1 3 5E11
|
||||
R3 5 97 0.0606
|
||||
R4 6 97 0.0606
|
||||
CIN 1 2 4E-12
|
||||
C2 5 6 218.9E-9
|
||||
I1 4 51 1
|
||||
IOS 1 2 0.5E-9
|
||||
EOS 9 10 POLY(1) 30 33 10E-6 1
|
||||
Q1 5 2 7 QX
|
||||
Q2 6 9 8 QX
|
||||
R5 7 4 0.009
|
||||
R6 8 4 0.009
|
||||
D1 2 1 DX
|
||||
D2 1 2 DX
|
||||
EN 10 1 12 0 1
|
||||
GN1 0 2 15 0 1
|
||||
GN2 0 1 18 0 1
|
||||
*
|
||||
EREF 98 0 33 0 1
|
||||
EPLUS 97 0 99 0 1
|
||||
ENEG 51 0 50 0 1
|
||||
*
|
||||
* VOLTAGE NOISE SOURCE WITH FLICKER NOISE
|
||||
*
|
||||
DN1 11 12 DEN
|
||||
DN2 12 13 DEN
|
||||
VN1 11 0 DC 2
|
||||
VN2 0 13 DC 2
|
||||
*
|
||||
* CURRENT NOISE SOURCE WITH FLICKER NOISE
|
||||
*
|
||||
DN3 14 15 DIN
|
||||
DN4 15 16 DIN
|
||||
VN3 14 0 DC 2
|
||||
VN4 0 16 DC 2
|
||||
*
|
||||
* SECOND CURRENT NOISE SOURCE
|
||||
*
|
||||
DN5 17 18 DIN
|
||||
DN6 18 19 DIN
|
||||
VN5 17 0 DC 2
|
||||
VN6 0 19 DC 2
|
||||
*
|
||||
* FIRST GAIN STAGE
|
||||
*
|
||||
R7 20 98 1
|
||||
G1 98 20 5 6 119.8
|
||||
D3 20 21 DX
|
||||
D4 22 20 DX
|
||||
E1 97 21 POLY(1) 97 33 -2.4 1
|
||||
E2 22 51 POLY(1) 33 51 -2.4 1
|
||||
*
|
||||
* GAIN STAGE & DOMINANT POLE AT 0.127 HZ
|
||||
*
|
||||
R8 23 98 1.253E9
|
||||
C3 23 98 1E-9
|
||||
G2 98 23 20 33 33.3E-6
|
||||
V1 97 24 1.8
|
||||
V2 25 51 1.8
|
||||
D5 23 24 DX
|
||||
D6 25 23 DX
|
||||
*
|
||||
* NEGATIVE ZERO AT -4MHZ
|
||||
*
|
||||
R9 26 27 1
|
||||
C4 26 27 -39.75E-9
|
||||
R10 27 98 1E-6
|
||||
E3 26 98 23 33 1E6
|
||||
*
|
||||
* COMMON-MODE GAIN NETWORK WITH ZERO AT 63 HZ
|
||||
*
|
||||
R13 30 31 1
|
||||
L2 31 98 2.52E-3
|
||||
G4 98 30 3 33 0.316E-6
|
||||
D7 30 97 DX
|
||||
D8 51 30 DX
|
||||
*
|
||||
* POLE AT 2 MHZ
|
||||
*
|
||||
R14 32 98 1
|
||||
C5 32 98 79.5E-9
|
||||
G5 98 32 27 33 1
|
||||
*
|
||||
* OUTPUT STAGE
|
||||
*
|
||||
R15 33 97 1
|
||||
R16 33 51 1
|
||||
GSY 99 50 POLY(1) 99 50 0.725E-3 0.0425E-3
|
||||
F1 34 0 V3 1
|
||||
F2 0 34 V4 1
|
||||
R17 34 99 400
|
||||
R18 34 50 400
|
||||
L3 34 39 2E-7
|
||||
G6 37 50 32 34 2.5E-3
|
||||
G7 38 50 34 32 2.5E-3
|
||||
G8 34 99 99 32 2.5E-3
|
||||
G9 50 34 32 50 2.5E-3
|
||||
V3 35 34 6.8
|
||||
V4 34 36 4.4
|
||||
D9 32 35 DX
|
||||
D10 36 32 DX
|
||||
D11 99 37 DX
|
||||
D12 99 38 DX
|
||||
D13 50 37 DY
|
||||
D14 50 38 DY
|
||||
*
|
||||
* MODELS USED
|
||||
*
|
||||
.MODEL QX NPN(BF=333.3E6)
|
||||
.MODEL DX D(IS=1E-15)
|
||||
.MODEL DY D(IS=1E-15 BV=50)
|
||||
.MODEL DEN D(IS=1E-12, RS=14.61K, KF=2E-17, AF=1)
|
||||
.MODEL DIN D(IS=1E-12, RS=7.55E-6, KF=3E-15, AF=1)
|
||||
.ENDS
|
||||
R102 U100V+ +5V 22
|
||||
R101 -5V U100V- 22
|
||||
R98 0 VU2bias+ 1K
|
||||
R99 0 VU1bias+ 1K
|
||||
C95 VU2bias+ 0 100pF
|
||||
* C96 0 5 1uF
|
||||
* C97 4 0 1uF
|
||||
Cphotodiode 0 Vinput 0.9pF
|
||||
C99 0 VU1bias+ 100pF
|
||||
R25 Vout2 2 250
|
||||
C24 Vout1 VU1in- 1pF
|
||||
R24 VU1in- 1 150
|
||||
* C21 0 3 1uF
|
||||
Cc Vout2 VU2in- 1pF
|
||||
Rc Vout1 VU2in- 10
|
||||
RL 0 Vout2 50
|
||||
.TEMP 0 25 50 75 100
|
||||
C12 2 0 1.5pF
|
||||
C11 0 V2- .01uF
|
||||
C10 V2+ 0 .01uF
|
||||
R13 +5V V2+ 5
|
||||
R12 V2- -5V 5
|
||||
R26 2 VU2in- 150
|
||||
R11 Vout2 VU2in- 180
|
||||
XU2 VU2bias+ VU2in- V2+ V2- Vout2 AD8009an
|
||||
XU1 VU1bias+ VU1in- V1+ V1- Vout1 AD8009an
|
||||
***** AD8009 SPICE model Rev B SMR/ADI 8-21-97
|
||||
|
||||
* Copyright 1997 by Analog Devices, Inc.
|
||||
|
||||
* Refer to "README.DOC" file for License Statement. Use of this model
|
||||
* indicates your acceptance with the terms and provisions in the License Statement.
|
||||
|
||||
* rev B of this model corrects a problem in the output stage that would not
|
||||
* correctly reflect the output current to the voltage supplies
|
||||
|
||||
* This model will give typical performance characteristics
|
||||
* for the following parameters;
|
||||
|
||||
* closed loop gain and phase vs bandwidth
|
||||
* output current and voltage limiting
|
||||
* offset voltage (is static, will not vary with vcm)
|
||||
* ibias (again, is static, will not vary with vcm)
|
||||
* slew rate and step response performance
|
||||
* (slew rate is based on 10-90% of step response)
|
||||
* current on output will be reflected to the supplies
|
||||
* vnoise, referred to the input
|
||||
* inoise, referred to the input
|
||||
|
||||
* distortion is not characterized
|
||||
|
||||
* Node assignments
|
||||
* non-inverting input
|
||||
* | inverting input
|
||||
* | | positive supply
|
||||
* | | | negative supply
|
||||
* | | | | output
|
||||
* | | | | |
|
||||
.SUBCKT AD8009an 1 2 99 50 28
|
||||
|
||||
* input stage *
|
||||
|
||||
q1 50 3 5 qp1
|
||||
q2 99 5 4 qn1
|
||||
q3 99 3 6 qn2
|
||||
q4 50 6 4 qp2
|
||||
i1 99 5 1.625e-3
|
||||
i2 6 50 1.625e-3
|
||||
cin1 1 98 2.6e-12
|
||||
cin2 2 98 1e-12
|
||||
v1 4 2 0
|
||||
|
||||
* input error sources *
|
||||
|
||||
eos 3 1 poly(1) 20 98 2e-3 1
|
||||
fbn 2 98 poly(1) vnoise3 50e-6 1e-3
|
||||
fbp 1 98 poly(1) vnoise3 50e-6 1e-3
|
||||
|
||||
* slew limiting stage *
|
||||
|
||||
fsl 98 16 v1 1
|
||||
dsl1 98 16 d1
|
||||
dsl2 16 98 d1
|
||||
dsl3 16 17 d1
|
||||
dsl4 17 16 d1
|
||||
rsl 17 18 0.22
|
||||
vsl 18 98 0
|
||||
|
||||
* gain stage *
|
||||
|
||||
f1 98 7 vsl 2
|
||||
rgain 7 98 2.5e5
|
||||
cgain 7 98 1.25e-12
|
||||
dcl1 7 8 d1
|
||||
dcl2 9 7 d1
|
||||
vcl1 99 8 1.83
|
||||
vcl2 9 50 1.83
|
||||
|
||||
gcm 98 7 poly(2) 98 0 30 0 0 1e-5 1e-5
|
||||
|
||||
* second pole *
|
||||
|
||||
epole 14 98 7 98 1
|
||||
rpole 14 15 1
|
||||
cpole 15 98 2e-10
|
||||
|
||||
* reference stage *
|
||||
|
||||
eref 98 0 poly(2) 99 0 50 0 0 0.5 0.5
|
||||
|
||||
ecmref 30 0 poly(2) 1 0 2 0 0 0.5 0.5
|
||||
|
||||
* vnoise stage *
|
||||
|
||||
rnoise1 19 98 4.6e-3
|
||||
vnoise1 19 98 0
|
||||
vnoise2 21 98 0.53
|
||||
dnoise1 21 19 dn
|
||||
|
||||
fnoise1 20 98 vnoise1 1
|
||||
rnoise2 20 98 1
|
||||
|
||||
* inoise stage *
|
||||
|
||||
rnoise3 22 98 8.18e-6
|
||||
vnoise3 22 98 0
|
||||
vnoise4 24 98 0.575
|
||||
dnoise2 24 22 dn
|
||||
|
||||
fnoise2 23 98 vnoise3 1
|
||||
rnoise4 23 98 1
|
||||
|
||||
* buffer stage *
|
||||
|
||||
gbuf 98 13 15 98 1e-2
|
||||
rbuf 98 13 1e2
|
||||
|
||||
* output current reflected to supplies *
|
||||
|
||||
fcurr 98 40 voc 1
|
||||
vcur1 26 98 0
|
||||
vcur2 98 27 0
|
||||
dcur1 40 26 d1
|
||||
dcur2 27 40 d1
|
||||
|
||||
* output stage *
|
||||
|
||||
vo1 99 90 0
|
||||
vo2 91 50 0
|
||||
fout1 0 99 poly(2) vo1 vcur1 -9.27e-3 1 -1
|
||||
fout2 50 0 poly(2) vo2 vcur2 -9.27e-3 1 -1
|
||||
gout1 90 10 13 99 0.5
|
||||
gout2 91 10 13 50 0.5
|
||||
rout1 10 90 2
|
||||
rout2 10 91 2
|
||||
voc 10 28 0
|
||||
rout3 28 98 1e6
|
||||
dcl3 13 11 d1
|
||||
dcl4 12 13 d1
|
||||
vcl3 11 10 -0.445
|
||||
vcl4 10 12 -0.445
|
||||
|
||||
.model qp1 pnp()
|
||||
.model qp2 pnp()
|
||||
.model qn1 npn()
|
||||
.model qn2 npn()
|
||||
.model d1 d()
|
||||
.model dn d(af=1 kf=1e-8)
|
||||
.ends
|
||||
R6 1 Vout1 250
|
||||
C3 1 0 1.5pF
|
||||
V3 VU1in- Vinput DC 0V
|
||||
* .INCLUDE /home/sdb/OpticalReceiver/Simulation.cmd
|
||||
R5 -5V Vout1 1K
|
||||
I1 0 Vinput AC 1 PWL (0ns 0mA 1nS 0mA 1.01nS 1mA 10nS 1mA 10.01nS 0mA 20nS 0mA 20.01nS .1mA 30nS .1mA 30.01nS 0mA)
|
||||
R4 V1- -5V 5
|
||||
C2 0 V1- .01uF
|
||||
V2 -5V 0 DC -5V
|
||||
R2 VU1in- Vout1 180
|
||||
V1 +5V 0 DC 5V
|
||||
C1 V1+ 0 .01uF
|
||||
R1 +5V V1+ 5
|
||||
* When run, this SPICE file should output a square waveform
|
||||
* with a little overshoot
|
||||
.tran 0.05ns 40ns
|
||||
.plot Vout2
|
||||
.END
|
||||
Loading…
Reference in New Issue