From da89dcc6c5fb5f594866741162072869352c38b9 Mon Sep 17 00:00:00 2001 From: stefanjones Date: Wed, 25 Jun 2003 10:37:48 +0000 Subject: [PATCH] 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. --- ChangeLog | 28 ++ Makefile.am | 3 + NOTES | 28 ++ configure.in | 12 +- src/Makefile.am | 10 +- src/include/inpdefs.h | 5 + src/include/mif.h | 5 +- src/include/ngspice.h | 9 - src/spicelib/devices/Makefile.am | 8 +- src/spicelib/devices/cktcrte.c | 2 +- src/spicelib/devices/dev.c | 22 +- src/spicelib/parser/inpdomod.c | 5 +- src/spicelib/parser/inptyplk.c | 18 +- src/spinit | 3 + src/xspice/Makefile.am | 4 + src/xspice/README | 17 + src/xspice/enh/enhtrans.c | 161 +++++--- src/xspice/icm/Makefile.am | 190 ++++++++- src/xspice/icm/README | 52 +++ src/xspice/icm/dlinfo.h | 9 + src/xspice/icm/dlmain.c | 408 +++++++++++++++++++ src/xspice/icm/icm_spice2poly/Makefile.am | 193 +++++++++ src/xspice/icm/icm_spice2poly/README | 49 +++ src/xspice/icm/icm_spice2poly/cfunc.c | 305 +++++++++++++++ src/xspice/icm/icm_spice2poly/cfunc.mod | 302 +++++++++++++++ src/xspice/icm/icm_spice2poly/ifspec.c | 187 +++++++++ src/xspice/icm/icm_spice2poly/ifspec.ifs | 75 ++++ src/xspice/icm/icm_spice2poly/make.bat | 3 + src/xspice/icm/modpath.lst | 2 + src/xspice/icm/objects.inc | 1 + src/xspice/icm/spice2poly.cm | Bin 0 -> 18495 bytes src/xspice/mif/mif.c | 6 +- src/xspice/mif/mif_inp2.c | 166 ++++---- src/xspice/mif/mifgetmod.c | 39 +- src/xspice/mif/mifutil.c | 6 +- tests/Makefile.am | 2 +- tests/TransImpedanceAmp/Makefile.am | 10 + tests/TransImpedanceAmp/README | 41 ++ tests/TransImpedanceAmp/output.net | 453 ++++++++++++++++++++++ 39 files changed, 2681 insertions(+), 158 deletions(-) create mode 100644 src/xspice/icm/README create mode 100644 src/xspice/icm/dlinfo.h create mode 100644 src/xspice/icm/dlmain.c create mode 100644 src/xspice/icm/icm_spice2poly/Makefile.am create mode 100644 src/xspice/icm/icm_spice2poly/README create mode 100644 src/xspice/icm/icm_spice2poly/cfunc.c create mode 100644 src/xspice/icm/icm_spice2poly/cfunc.mod create mode 100644 src/xspice/icm/icm_spice2poly/ifspec.c create mode 100644 src/xspice/icm/icm_spice2poly/ifspec.ifs create mode 100644 src/xspice/icm/icm_spice2poly/make.bat create mode 100644 src/xspice/icm/modpath.lst create mode 100644 src/xspice/icm/objects.inc create mode 100755 src/xspice/icm/spice2poly.cm create mode 100644 tests/TransImpedanceAmp/Makefile.am create mode 100644 tests/TransImpedanceAmp/README create mode 100644 tests/TransImpedanceAmp/output.net diff --git a/ChangeLog b/ChangeLog index e9017f337..7fccc2057 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ + 2003-06-22 Stuart Brorson + + * 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 * Much improved spice wish interface; graph includes zooming, diff --git a/Makefile.am b/Makefile.am index 23dd8befb..23ba6a0c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,3 +18,6 @@ tcl: cd src && $(MAKE) tcl install-tcl: cd src && $(MAKE) install-tcl + +codemodels: + cd src/xspice/icm && make \ No newline at end of file diff --git a/NOTES b/NOTES index 3851bcae1..add7eaf1b 100644 --- a/NOTES +++ b/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 diff --git a/configure.in b/configure.in index 5cc429cb2..f619b38ba 100644 --- a/configure.in +++ b/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 diff --git a/src/Makefile.am b/src/Makefile.am index 512d60008..dff7eafdb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 = \ diff --git a/src/include/inpdefs.h b/src/include/inpdefs.h index 24bb8d153..232e5b908 100644 --- a/src/include/inpdefs.h +++ b/src/include/inpdefs.h @@ -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 diff --git a/src/include/mif.h b/src/include/mif.h index 106412299..a08941d46 100755 --- a/src/include/mif.h +++ b/src/include/mif.h @@ -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 */ diff --git a/src/include/ngspice.h b/src/include/ngspice.h index e9fb9bdaa..b76a0f779 100644 --- a/src/include/ngspice.h +++ b/src/include/ngspice.h @@ -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 */ diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index ea8940c63..686187710 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -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 diff --git a/src/spicelib/devices/cktcrte.c b/src/spicelib/devices/cktcrte.c index ba90b713c..9ce11a073 100644 --- a/src/spicelib/devices/cktcrte.c +++ b/src/spicelib/devices/cktcrte.c @@ -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); diff --git a/src/spicelib/devices/dev.c b/src/spicelib/devices/dev.c index 4c0f46ec1..a2fb4cfb1 100644 --- a/src/spicelib/devices/dev.c +++ b/src/spicelib/devices/dev.c @@ -289,7 +289,7 @@ void load_alldevs(void){ } #endif - +/*-------------------- XSPICE additions below ----------------------*/ #ifdef XSPICE #include #include @@ -298,8 +298,18 @@ void load_alldevs(void){ #include /*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 ----------------------*/ diff --git a/src/spicelib/parser/inpdomod.c b/src/spicelib/parser/inpdomod.c index 85f43d3d2..2e14a4557 100644 --- a/src/spicelib/parser/inpdomod.c +++ b/src/spicelib/parser/inpdomod.c @@ -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); diff --git a/src/spicelib/parser/inptyplk.c b/src/spicelib/parser/inptyplk.c index 339191728..40598c1f3 100644 --- a/src/spicelib/parser/inptyplk.c +++ b/src/spicelib/parser/inptyplk.c @@ -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; } diff --git a/src/spinit b/src/spinit index 31c8095d3..0c03be57f 100644 --- a/src/spinit +++ b/src/spinit @@ -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 diff --git a/src/xspice/Makefile.am b/src/xspice/Makefile.am index e0e1c6a10..949cd8347 100755 --- a/src/xspice/Makefile.am +++ b/src/xspice/Makefile.am @@ -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) diff --git a/src/xspice/README b/src/xspice/README index 29701bd34..d0f621920 100755 --- a/src/xspice/README +++ b/src/xspice/README @@ -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. + diff --git a/src/xspice/enh/enhtrans.c b/src/xspice/enh/enhtrans.c index ad9a33447..53cca2d49 100755 --- a/src/xspice/enh/enhtrans.c +++ b/src/xspice/enh/enhtrans.c @@ -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 */ diff --git a/src/xspice/icm/Makefile.am b/src/xspice/icm/Makefile.am index 1d1ebc2f9..120528608 100755 --- a/src/xspice/icm/Makefile.am +++ b/src/xspice/icm/Makefile.am @@ -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 + diff --git a/src/xspice/icm/README b/src/xspice/icm/README new file mode 100644 index 000000000..a969bb159 --- /dev/null +++ b/src/xspice/icm/README @@ -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 + diff --git a/src/xspice/icm/dlinfo.h b/src/xspice/icm/dlinfo.h new file mode 100644 index 000000000..f79261781 --- /dev/null +++ b/src/xspice/icm/dlinfo.h @@ -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"; + diff --git a/src/xspice/icm/dlmain.c b/src/xspice/icm/dlmain.c new file mode 100644 index 000000000..9472aab6c --- /dev/null +++ b/src/xspice/icm/dlmain.c @@ -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 +#include +#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); +} diff --git a/src/xspice/icm/icm_spice2poly/Makefile.am b/src/xspice/icm/icm_spice2poly/Makefile.am new file mode 100644 index 000000000..853011741 --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/Makefile.am @@ -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 + + diff --git a/src/xspice/icm/icm_spice2poly/README b/src/xspice/icm/icm_spice2poly/README new file mode 100644 index 000000000..c850128a6 --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/README @@ -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 + diff --git a/src/xspice/icm/icm_spice2poly/cfunc.c b/src/xspice/icm/icm_spice2poly/cfunc.c new file mode 100644 index 000000000..6afbb77ba --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/cfunc.c @@ -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 + + + +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 [ ] xxx + .model xxx spice2poly ( coef = [ ] ) + +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; + +} + diff --git a/src/xspice/icm/icm_spice2poly/cfunc.mod b/src/xspice/icm/icm_spice2poly/cfunc.mod new file mode 100644 index 000000000..4bf354e20 --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/cfunc.mod @@ -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 + + + +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 [ ] xxx + .model xxx spice2poly ( coef = [ ] ) + +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; + +} + diff --git a/src/xspice/icm/icm_spice2poly/ifspec.c b/src/xspice/icm/icm_spice2poly/ifspec.c new file mode 100644 index 000000000..016e00fde --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/ifspec.c @@ -0,0 +1,187 @@ + +/* + * Structures for model: spice2poly + * + * Automatically generated by cmpp preprocessor + * + * !!! DO NOT EDIT !!! + * + */ + + +// #include "prefix.h" +#include +#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, + +}; + diff --git a/src/xspice/icm/icm_spice2poly/ifspec.ifs b/src/xspice/icm/icm_spice2poly/ifspec.ifs new file mode 100644 index 000000000..33da52236 --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/ifspec.ifs @@ -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 + + + +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" diff --git a/src/xspice/icm/icm_spice2poly/make.bat b/src/xspice/icm/icm_spice2poly/make.bat new file mode 100644 index 000000000..19a341b81 --- /dev/null +++ b/src/xspice/icm/icm_spice2poly/make.bat @@ -0,0 +1,3 @@ +#!/bin/sh +cmpp -mod cfunc.mod +cmpp -ifs diff --git a/src/xspice/icm/modpath.lst b/src/xspice/icm/modpath.lst new file mode 100644 index 000000000..9ad9131c9 --- /dev/null +++ b/src/xspice/icm/modpath.lst @@ -0,0 +1,2 @@ +icm_spice2poly + diff --git a/src/xspice/icm/objects.inc b/src/xspice/icm/objects.inc new file mode 100644 index 000000000..fc2fd16c8 --- /dev/null +++ b/src/xspice/icm/objects.inc @@ -0,0 +1 @@ +icm_spice2poly/*.o diff --git a/src/xspice/icm/spice2poly.cm b/src/xspice/icm/spice2poly.cm new file mode 100755 index 0000000000000000000000000000000000000000..1e67d1e959327de7c7533d1ed73827d9cf46e0ba GIT binary patch literal 18495 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 literal 0 HcmV?d00001 diff --git a/src/xspice/mif/mif.c b/src/xspice/mif/mif.c index 42227c0d4..9cf711db9 100755 --- a/src/xspice/mif/mif.c +++ b/src/xspice/mif/mif.c @@ -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 */ diff --git a/src/xspice/mif/mif_inp2.c b/src/xspice/mif/mif_inp2.c index b85ef0947..9566b5f13 100755 --- a/src/xspice/mif/mif_inp2.c +++ b/src/xspice/mif/mif_inp2.c @@ -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) { diff --git a/src/xspice/mif/mifgetmod.c b/src/xspice/mif/mifgetmod.c index cd243af4e..3b257651b 100755 --- a/src/xspice/mif/mifgetmod.c +++ b/src/xspice/mif/mifgetmod.c @@ -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); diff --git a/src/xspice/mif/mifutil.c b/src/xspice/mif/mifutil.c index 35ce92f20..8e69a04e7 100755 --- a/src/xspice/mif/mifutil.c +++ b/src/xspice/mif/mifutil.c @@ -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); diff --git a/tests/Makefile.am b/tests/Makefile.am index 876e71c23..8bc95a059 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ diff --git a/tests/TransImpedanceAmp/Makefile.am b/tests/TransImpedanceAmp/Makefile.am new file mode 100644 index 000000000..6932b4b0a --- /dev/null +++ b/tests/TransImpedanceAmp/Makefile.am @@ -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 diff --git a/tests/TransImpedanceAmp/README b/tests/TransImpedanceAmp/README new file mode 100644 index 000000000..ea5c249da --- /dev/null +++ b/tests/TransImpedanceAmp/README @@ -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. diff --git a/tests/TransImpedanceAmp/output.net b/tests/TransImpedanceAmp/output.net new file mode 100644 index 000000000..aae3319ef --- /dev/null +++ b/tests/TransImpedanceAmp/output.net @@ -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