diff --git a/ChangeLog b/ChangeLog index 80adf87fe..2466f1a2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,25 @@ -008-08-25 Paolo Nenzi +2008-08-27 Paolo Nenzi + * --- TCLSPICE initial integration (Lionel Sainte Cluque) --- + * Makefile.am: Makefiles changed for libtool. We use still .a files but we let + libtool to created them in a portable manner. This slows compilation a little + bit but improves portability of ngspice/tclspice. + * src/tclspice.c, src/tclspice.map, pkgIndex.tcl.in, src/include/tclspice.h: + tclspice main and include file. (Readded files). + * src/tests/tcl/, src/tests/tcl-testbench1/, src/tests/tcl-testbench2/, + src/tests/tcl-testbench3/, src/tests/tcl-testbench4/: testbenches for + the tclspice simulator. (New dirs). + * src/frontend/plotit.c: added blt_plot for blt output device if TCL defined. + * src/frontend/com_plot.c, src/frontend/com_plot.h: added com_bltplot. + * src/frontend/commands.c: redefined plot command to combltplot if TCL is enabled. + * src/frontend/display.c: defined Tk display device. + * src/frontend/outitf.c: added blt support. + * src/frontend/terminal.c: if TCL is defined, interactive terminal stubs are copiled in. + * src/include/ngspice.h: added definitions for TCL functions. + * src/misc/alloc.c: Using TCL allocation functions when tclspice is enabled. + * src/frontend/com_measure2.c,.h: new measure command (to link and test) + * src/main.c: some static function moved for TCL interface (nutmeginfo, etc.) + +2008-08-25 Paolo Nenzi * configure.in, src/spicelib/analysis/noisean.c: removed the compilation switch --enable-intnoise. Noise analyses now generate two plot, the first one for spectrum and the second one the integrated noise. diff --git a/Makefile.am b/Makefile.am index a81208921..6c89cedaf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,4 +22,3 @@ mrproper: maintainer-clean rm -f `find . -type f -name "*.orig" -print` rm -f `find . -type f -name "*.rej" -print` - diff --git a/configure.in b/configure.in index 0b754e934..451fd305d 100644 --- a/configure.in +++ b/configure.in @@ -173,6 +173,11 @@ dnl --with-editline: Includes BSD Editline support into CLI. Default is "no". AC_ARG_WITH(editline, AS_HELP_STRING([--with-editline[=yes/no]],[Enable BSD editline support for CLI. Default=no.])) +dnl --with-tcl: define TCL_MODULE in the code. This is for tcl support +AC_ARG_WITH(tcl, + [ --with-tcl[=tcldir] Compiles the tcl module instead, experimental, see README.Tcl]) + + dnl readline and editline cannot both be enabled if test "$with_editline" = "yes"; then @@ -280,6 +285,133 @@ case $with_windows in CFLAGS="$CFLAGS -mwindows";; * ) +########################################################################## +# +# tcl libraries test +# +########################################################################## + +dnl +dnl The tclSpice options +dnl +AM_CONDITIONAL(TCL_MODULE, false) +if test "x$with_tcl" != "x" -a "$with_tcl" != "no" ; then + AM_CONDITIONAL(TCL_MODULE, true) + AC_DEFINE(TCL_MODULE,1,[Tcl Module]) + with_x=no + enable_shared=no + + AC_MSG_CHECKING([for tclConfig.sh]) + tcl_config_sh="" + if test "x$with_tcl" != "xyes" ; then + for dir in \ + $with_tcl + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + elif test -r "$dir/unix/tclConfig.sh" ; then + tcl_config_sh="$dir/unix/tclConfig.sh" + break + fi + done + else + for dir in \ + $prefix \ + $exec_prefix + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + elif test -r "$dir/unix/tclConfig.sh" ; then + tcl_config_sh="$dir/unix/tclConfig.sh" + break + fi + done + + + if test "x$tcl_config_sh" = "x" ; then + for dir in \ + `ls -dr /usr/local/tcl/tcl[[7-9]].[[0-9]]* 2>/dev/null` \ + /usr/local/tcl \ + /usr/local \ + /usr + do + if test -r "$dir/tclConfig.sh" ; then + tcl_config_sh="$dir/tclConfig.sh" + break + elif test -r "$dir/lib/tclConfig.sh" ; then + tcl_config_sh="$dir/lib/tclConfig.sh" + break + fi + done + fi + fi + +AC_MSG_RESULT([${tcl_config_sh}]) + + + +if test "x$tcl_config_sh" = "x" ; then + echo "can't find Tcl configuration script \"tclConfig.sh\"" + find /usr/lib/ -name 'tclConfig.sh' -exec echo "Should you add --with-tcl={} to ./configure arguments?" \; + exit 1 +fi + +. $tcl_config_sh + +CFLAGS="$CFLAGS $TCL_INCLUDE_SPEC" +CPPFLAGS="$CPPFLAGS $TCL_INCLUDE_SPEC" + +AC_CHECK_HEADERS(tcl.h blt.h,,AC_MSG_ERROR(Couldn't find Tcl/BLT headers),) + +if test ! -x "$TCL_EXEC_PREFIX/bin/tclsh$TCL_VERSION" ; then +AC_MSG_ERROR(Couldn't find $TCL_EXEC_PREFIX/bin/tclsh$TCL_VERSION) +fi + +AC_MSG_CHECKING(for TCL module BLT) +rm -f conftest.tcl +cat > conftest.tcl << EOF +package require BLT; +exit; +EOF +if ($TCL_EXEC_PREFIX/bin/tclsh$TCL_VERSION conftest.tcl; exit) 2>/dev/null +then + AC_MSG_RESULT(Found) +else + AC_MSG_ERROR(Couldn't find BLT) +fi +rm -f conftest.tcl + +AC_CHECK_LIB(pthread,pthread_create) +for TCL_PACKAGE_PATH_ELEMENT in $TCL_PACKAGE_PATH ; do + if test -a $TCL_PACKAGE_PATH_ELEMENT ; then + libdir=$TCL_PACKAGE_PATH_ELEMENT + AC_SUBST(libdir) + break + fi +done + +else + TCL_PACKAGE_PATH="" + TCL_LIB_SPEC="" +fi + +AC_SUBST(TCL_PACKAGE_PATH) +AC_SUBST(TCL_LIB_SPEC) +################################################################## +# +# +#End of tcl libraries test +# +################################################################# + dnl Check for /proc (virtual process information file system) AC_CHECK_HEADERS( /proc/meminfo) @@ -445,13 +577,14 @@ dnl Check for the random function: AC_CHECK_FUNCS(random,,AC_CHECK_LIB(iberty,random,AC_DEFINE([HAVE_RANDOM],1,[Have random in libiberty]) LIBS="$LIBS -liberty")) dnl If user enables garbage collection, look for garbage collector -if test "$enable_gc" = "yes"; then - AC_MSG_RESULT(Checking for the presence of the Garbage Collector:) - AC_CHECK_LIB(gc,GC_malloc, - AC_DEFINE(HAVE_LIBGC,[],[Define if we want garbage collection enabled]) - LIBS="$LIBS -lgc") +if test "$TCL_PACKAGE_PATH" = ""; then + if test "$enable_gc" = "yes"; then + AC_MSG_RESULT(Checking for the presence of the Garbage Collector:) + AC_CHECK_LIB(gc,GC_malloc, + AC_DEFINE(HAVE_LIBGC,[],[Define if we want garbage collection enabled]) + LIBS="$LIBS -lgc") + fi fi - dnl check, if we have sigsetjmp and siglongjmp. dnl A trivial AC_CHECK_FUNCS(sigsetjmp) won't do because sigsetjmp() might be a dnl macro declared in . (joze) @@ -497,7 +630,7 @@ AC_DEFINE_UNQUOTED(NGSPICEBUILDDATE,"`date`",[Define the build date]) if test "$with_windows" = "yes"; then AC_MSG_RESULT(WINDOWS code enabled) WINMAIN="winmain.o" - WINDISPLIB="frontend/wdisp/libwindisp.a" + WINDISPLIB="frontend/wdisp/libwindisp.la" AC_CHECK_FUNCS([memmove]) else WINMAIN="" @@ -613,12 +746,12 @@ dnl Define variables for YACC and LEX AC_DEFINE([IPC_UNIX_SOCKETS], [1], [Client-Server via socket.]) DLLIBS="-ldl";; esac - XSPICELIB1="$XSPICEDIR/cm/libcmxsp.a \ - $XSPICEDIR/mif/libmifxsp.a" - XSPICELIB2="$XSPICEDIR/evt/libevtxsp.a \ - $XSPICEDIR/enh/libenhxsp.a \ - $XSPICEDIR/ipc/libipcxsp.a \ - $XSPICEDIR/idn/libidnxsp.a \ + XSPICELIB1="$XSPICEDIR/cm/libcmxsp.la \ + $XSPICEDIR/mif/libmifxsp.la" + XSPICELIB2="$XSPICEDIR/evt/libevtxsp.la \ + $XSPICEDIR/enh/libenhxsp.la \ + $XSPICEDIR/ipc/libipcxsp.la \ + $XSPICEDIR/idn/libidnxsp.la \ $DLLIBS" XSPICEINIT="" XSPICETESTS="" @@ -644,16 +777,16 @@ if test "$enable_cider" = "yes"; then CIDERDIR="ciderlib" - CIDERSIM=" $CIDERDIR/twod/libcidertwod.a \ - $CIDERDIR/oned/libcideroned.a \ - $CIDERDIR/input/libciderinput.a \ - $CIDERDIR/support/libcidersuprt.a" + CIDERSIM=" $CIDERDIR/twod/libcidertwod.la \ + $CIDERDIR/oned/libcideroned.la \ + $CIDERDIR/input/libciderinput.la \ + $CIDERDIR/support/libcidersuprt.la" - NUMDEV=" spicelib/devices/nbjt/libnbjt.a \ - spicelib/devices/nbjt2/libnbjt2.a \ - spicelib/devices/numd/libnumd.a \ - spicelib/devices/numd2/libnumd2.a \ - spicelib/devices/numos/libnumos.a" + NUMDEV=" spicelib/devices/nbjt/libnbjt.la \ + spicelib/devices/nbjt2/libnbjt2.la \ + spicelib/devices/numd/libnumd.la \ + spicelib/devices/numd2/libnumd2.la \ + spicelib/devices/numos/libnumos.la" NUMDEVDIR=" nbjt \ nbjt2 \ numd \ @@ -694,11 +827,11 @@ if test "$enable_adms" = "yes"; then adms/ekv \ adms/psp102 " - VLADEV=" spicelib/devices/adms/hicum0/libhicum0.a \ - spicelib/devices/adms/hicum2/libhicum2.a \ - spicelib/devices/adms/mextram/libmextram.a \ - spicelib/devices/adms/ekv/libekv.a \ - spicelib/devices/adms/psp102/libpsp102.a " + VLADEV=" spicelib/devices/adms/hicum0/libhicum0.la \ + spicelib/devices/adms/hicum2/libhicum2.la \ + spicelib/devices/adms/mextram/libmextram.la \ + spicelib/devices/adms/ekv/libekv.la \ + spicelib/devices/adms/psp102/libpsp102.la " fi AC_SUBST(ADMSXML) @@ -711,7 +844,7 @@ if test "$enable_ndev" = "yes"; then AC_DEFINE(NDEV,[],[The NDEV interface]) NDEV="" NDEV_DIR=" ndev " - NDEV_LIB=" spicelib/devices/ndev/libndev.a " + NDEV_LIB=" spicelib/devices/ndev/libndev.la " else NDEV="" NDEV_DIR="" @@ -740,6 +873,7 @@ dnl ---- Hope to see in the future readline replacement. ---- if test "$with_readline" != "yes"; then AC_MSG_RESULT(GNU readline disabled.) else + if test "x$with_tcl" == "x" -o "$with_tcl" == "no" ; then AC_MSG_RESULT(Checking for readline:) AC_CHECK_HEADERS([readline/readline.h readline/history.h], [AC_DEFINE(HAVE_GNUREADLINE,[],[Define if we have GNU readline])], @@ -750,6 +884,7 @@ else AC_CHECK_LIB(readline, readline, [LIBS="$LIBS -lreadline"], [AC_MSG_ERROR(Couldn't find readline libraries.)]) + fi fi diff --git a/src/Makefile.am b/src/Makefile.am index b75401b52..b7482f340 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,6 +4,7 @@ SUBDIRS = misc maths frontend spicelib include @XSPICEDIR@ @CIDERDIR@ DIST_SUBDIRS = misc maths frontend spicelib include xspice ciderlib +if !TCL_MODULE bin_PROGRAMS = ngspice ngnutmeg ngmakeidx if !WINDOWS @@ -13,8 +14,10 @@ endif if !NO_HELP bin_PROGRAMS += nghelp endif +endif + EXTRA_DIST = ngspice.txt ngspice.idx setplot spectrum \ - devload devaxis ciderinit winmain.c + devload devaxis ciderinit winmain.c helpdatadir = $(pkgdatadir)/helpdir @@ -26,57 +29,57 @@ initdata_DATA = spinit setplot spectrum @CIDERSCRIPTS@ DYNAMIC_DEVICELIBS = \ - spicelib/devices/asrc/libasrc.a \ - spicelib/devices/bjt/libbjt.a \ - spicelib/devices/bjt2/libbjt2.a \ - spicelib/devices/bsim1/libbsim1.a \ - spicelib/devices/bsim2/libbsim2.a \ - spicelib/devices/bsim3/libbsim3.a \ - spicelib/devices/bsim3v0/libbsim3v0.a \ - spicelib/devices/bsim3v1/libbsim3v1.a \ - spicelib/devices/bsim3v1s/libbsim3v1s.a \ - spicelib/devices/bsim3v1a/libbsim3v1a.a \ - spicelib/devices/bsim3v32/libbsim3v32.a \ - spicelib/devices/bsim4/libbsim4.a \ - spicelib/devices/bsim4v2/libbsim4v2.a \ - spicelib/devices/bsim4v3/libbsim4v3.a \ - spicelib/devices/bsim4v4/libbsim4v4.a \ - spicelib/devices/bsim4v5/libbsim4v5.a \ - spicelib/devices/cap/libcap.a \ - spicelib/devices/bsim3soi/libbsim3soi.a \ - spicelib/devices/bsim3soi_pd/libbsim3soipd.a \ - spicelib/devices/bsim3soi_fd/libbsim3soifd.a \ - spicelib/devices/bsim3soi_dd/libbsim3soidd.a \ - spicelib/devices/cccs/libcccs.a \ - spicelib/devices/ccvs/libccvs.a \ - spicelib/devices/cpl/libcpl.a \ - spicelib/devices/csw/libcsw.a \ - spicelib/devices/dio/libdio.a \ - spicelib/devices/ind/libind.a \ - spicelib/devices/isrc/libisrc.a \ - spicelib/devices/hfet1/libhfet.a \ - spicelib/devices/hfet2/libhfet2.a \ - spicelib/devices/hisim/libhisim.a \ - spicelib/devices/jfet/libjfet.a \ - spicelib/devices/jfet2/libjfet2.a \ - spicelib/devices/ltra/libltra.a \ - spicelib/devices/mes/libmes.a \ - spicelib/devices/mesa/libmesa.a \ - spicelib/devices/mos1/libmos1.a \ - spicelib/devices/mos2/libmos2.a \ - spicelib/devices/mos3/libmos3.a \ - spicelib/devices/mos6/libmos6.a \ - spicelib/devices/mos9/libmos9.a \ - spicelib/devices/res/libres.a \ - spicelib/devices/soi3/libsoi3.a \ - spicelib/devices/sw/libsw.a \ - spicelib/devices/txl/libtxl.a \ - spicelib/devices/tra/libtra.a \ - spicelib/devices/urc/liburc.a \ - spicelib/devices/vbic/libvbic.a \ - spicelib/devices/vccs/libvccs.a \ - spicelib/devices/vcvs/libvcvs.a \ - spicelib/devices/vsrc/libvsrc.a \ + 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 \ + spicelib/devices/bsim3v0/libbsim3v0.la \ + spicelib/devices/bsim3v1/libbsim3v1.la \ + spicelib/devices/bsim3v1s/libbsim3v1s.la \ + spicelib/devices/bsim3v1a/libbsim3v1a.la \ + spicelib/devices/bsim3v32/libbsim3v32.la \ + spicelib/devices/bsim4/libbsim4.la \ + spicelib/devices/bsim4v2/libbsim4v2.la \ + spicelib/devices/bsim4v3/libbsim4v3.la \ + spicelib/devices/bsim4v4/libbsim4v4.la \ + spicelib/devices/bsim4v5/libbsim4v5.la \ + spicelib/devices/cap/libcap.la \ + spicelib/devices/bsim3soi/libbsim3soi.la \ + spicelib/devices/bsim3soi_pd/libbsim3soipd.la \ + spicelib/devices/bsim3soi_fd/libbsim3soifd.la \ + spicelib/devices/bsim3soi_dd/libbsim3soidd.la \ + spicelib/devices/cccs/libcccs.la \ + spicelib/devices/ccvs/libccvs.la \ + spicelib/devices/cpl/libcpl.la \ + spicelib/devices/csw/libcsw.la \ + spicelib/devices/dio/libdio.la \ + spicelib/devices/ind/libind.la \ + spicelib/devices/isrc/libisrc.la \ + spicelib/devices/hfet1/libhfet.la \ + spicelib/devices/hfet2/libhfet2.la \ + spicelib/devices/hisim/libhisim.la \ + spicelib/devices/jfet/libjfet.la \ + spicelib/devices/jfet2/libjfet2.la \ + spicelib/devices/ltra/libltra.la \ + spicelib/devices/mes/libmes.la \ + spicelib/devices/mesa/libmesa.la \ + spicelib/devices/mos1/libmos1.la \ + spicelib/devices/mos2/libmos2.la \ + spicelib/devices/mos3/libmos3.la \ + spicelib/devices/mos6/libmos6.la \ + spicelib/devices/mos9/libmos9.la \ + spicelib/devices/res/libres.la \ + spicelib/devices/soi3/libsoi3.la \ + spicelib/devices/sw/libsw.la \ + spicelib/devices/txl/libtxl.la \ + spicelib/devices/tra/libtra.la \ + spicelib/devices/urc/liburc.la \ + spicelib/devices/vbic/libvbic.la \ + spicelib/devices/vccs/libvccs.la \ + spicelib/devices/vcvs/libvcvs.la \ + spicelib/devices/vsrc/libvsrc.la \ @NDEV_LIB@ \ @VLADEV@ \ @NUMDEV@ @@ -94,37 +97,39 @@ ngspice_SOURCES += winmain.c endif ngspice_LDADD = \ - spice.o \ - frontend/libfte.a \ + spice.lo \ + frontend/libfte.la \ @WINDISPLIB@ \ - frontend/plotting/libplotting.a \ + frontend/plotting/libplotting.la \ @XSPICELIB1@ \ - spicelib/devices/dev.o \ + spicelib/devices/dev.lo \ $(DYNAMIC_DEVICELIBS) \ - spicelib/analysis/libckt.a \ - spicelib/devices/libdev.a \ + spicelib/analysis/libckt.la \ + spicelib/devices/libdev.la \ @XSPICELIB2@ \ - frontend/parser/libparser.a \ - frontend/numparam/libnumparam.a \ - spicelib/parser/libinp.a \ + frontend/parser/libparser.la \ + frontend/numparam/libnumparam.la \ + spicelib/parser/libinp.la \ @CIDERSIM@ \ - maths/deriv/libderiv.a \ - maths/cmaths/libcmaths.a \ - maths/misc/libmathmisc.a \ - maths/poly/libpoly.a \ - maths/ni/libni.a \ - maths/sparse/libsparse.a \ - misc/libmisc.a + maths/deriv/libderiv.la \ + maths/cmaths/libcmaths.la \ + maths/misc/libmathmisc.la \ + maths/poly/libpoly.la \ + maths/ni/libni.la \ + maths/sparse/libsparse.la \ + misc/libmisc.la if !NO_X ngspice_LDADD += \ - frontend/help/libhlp.a + frontend/help/libhlp.la endif winmain.o: winmain.c $(COMPILE) -DSIMULATOR -o winmain.o -c $(srcdir)/winmain.c -spice.o: main.c - $(COMPILE) -DSIMULATOR -o spice.o -c $(srcdir)/main.c +spice.lo: main.c + $(LTCOMPILE) -DSIMULATOR -MT spice.lo -MD -MP -MF $(DEPDIR)/spice.Tpo -c -o spice.o $< + mv -f $(DEPDIR)/spice.Tpo $(DEPDIR)/spice.Plo + ## nutmeg: @@ -139,19 +144,19 @@ ngnutmeg_SOURCES += winmain.c endif ngnutmeg_LDADD = \ - frontend/libfte.a \ + frontend/libfte.la \ @WINDISPLIB@ \ - frontend/plotting/libplotting.a \ - frontend/parser/libparser.a \ - frontend/numparam/libnumparam.a \ - maths/cmaths/libcmaths.a \ - maths/misc/libmathmisc.a \ - maths/poly/libpoly.a \ - misc/libmisc.a \ - spicelib/parser/libinp.a + frontend/plotting/libplotting.la \ + frontend/parser/libparser.la \ + frontend/numparam/libnumparam.la \ + maths/cmaths/libcmaths.la \ + maths/misc/libmathmisc.la \ + maths/poly/libpoly.la \ + misc/libmisc.la \ + spicelib/parser/libinp.la if !NO_X ngnutmeg_LDADD += \ - frontend/help/libhlp.a + frontend/help/libhlp.la endif ## help: @@ -167,11 +172,11 @@ endif # rather than the full front-end library libfte.a to avoid link errors that # that would otherwise occur (thanks to Andreas Unger for this fix). nghelp_LDADD = \ - frontend/terminal.o \ - misc/libmisc.a + frontend/terminal.lo \ + misc/libmisc.la if !NO_X nghelp_LDADD += \ - frontend/help/libhlp.a + frontend/help/libhlp.la endif endif @@ -184,19 +189,19 @@ ngsconvert_SOURCES = ngsconvert.c ngsconvert_LDADD = \ - frontend/libfte.a \ - frontend/parser/libparser.a \ - maths/misc/libmathmisc.a \ - misc/libmisc.a + frontend/libfte.la \ + frontend/parser/libparser.la \ + maths/misc/libmathmisc.la \ + misc/libmisc.la ## proc2mod: ngproc2mod_SOURCES = ngproc2mod.c ngproc2mod_LDADD = \ - frontend/parser/libparser.a \ - spicelib/parser/libinp.a \ - misc/libmisc.a + frontend/parser/libparser.la \ + spicelib/parser/libinp.la \ + misc/libmisc.la ## multidec: @@ -204,8 +209,8 @@ ngproc2mod_LDADD = \ ngmultidec_SOURCES = ngmultidec.c ngmultidec_LDADD = \ - maths/sparse/libsparse.a \ - misc/libmisc.a + maths/sparse/libsparse.la \ + misc/libmisc.la endif !WINDOWS @@ -231,3 +236,69 @@ LIBS += -lpsapi endif MAINTAINERCLEANFILES = Makefile.in ngspice.idx + +if TCL_MODULE +lib_LTLIBRARIES = libspice.la +install: install-libLTLIBRARIES install-tcl-recursive install-tclspice install-data-am +EXTRA_DIST += tclspice.c + +libspice_la_SOURCES = +libspice_la_LIBADD = ngspice.lo conf.lo \ + spice.lo \ + @X_LIBS@ \ + frontend/libfte.la \ + @WINDISPLIB@ \ + frontend/plotting/libplotting.la \ + @XSPICELIB1@ \ + $(DYNAMIC_DEVICELIBS) \ + spicelib/analysis/libckt.la \ + spicelib/devices/libdev.la \ + @XSPICELIB2@ \ + frontend/parser/libparser.la \ + frontend/numparam/libnumparam.la \ + spicelib/parser/libinp.la \ + @CIDERSIM@ \ + maths/deriv/libderiv.la \ + maths/cmaths/libcmaths.la \ + maths/misc/libmathmisc.la \ + maths/poly/libpoly.la \ + maths/ni/libni.la \ + maths/sparse/libsparse.la \ + misc/libmisc.la \ + tclspice.lo $(LIBS) +libspice_la_CFLAGS = $(AM_CFLAGS) +libspice_la_LDFALGS = -shared -Wl,--version-script=tclspice.map + +CLEANFILES = pkgIndex.tcl libspice.so + +TCL_PKG_PATH = @TCL_PACKAGE_PATH@ + +TCLSPICE_VERSION = @VERSION@ + + +TCL_FILES = libspice.la pkgIndex.tcl + + +pkgIndex.tcl: pkgIndex.tcl.in + rm -f $@ + sed -e 's;%LIB_DIR%;$(libdir);g' $< | \ + sed -e 's;%VERSION%;$(TCLSPICE_VERSION);g' > $@ + +all: $(TCL_FILES) + +install-tcl-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) install) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; + +install-tclspice: + $(mkinstalldirs) $(libdir)/spice + $(INSTALL_DATA) pkgIndex.tcl $(libdir)/spice + +tclspice.lo: tclspice.c + $(LTCOMPILE) -DTCLSPICE_version="\"$(TCLSPICE_VERSION)\"" -MT tclspice.lo -MD -MP -MF $(DEPDIR)/tclspice.Tpo -c -o tclspice.o $< + mv -f $(DEPDIR)/tclspice.Tpo $(DEPDIR)/tclspice.Plo + +endif diff --git a/src/ciderlib/input/Makefile.am b/src/ciderlib/input/Makefile.am index 9e8b1ba90..c8c34ac62 100644 --- a/src/ciderlib/input/Makefile.am +++ b/src/ciderlib/input/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libciderinput.a +noinst_LTLIBRARIES = libciderinput.la -libciderinput_a_SOURCES = \ +libciderinput_la_SOURCES = \ bdryset.c \ boundary.c \ cards.c \ diff --git a/src/ciderlib/oned/Makefile.am b/src/ciderlib/oned/Makefile.am index 4e8ea9cc5..673d5c3fb 100644 --- a/src/ciderlib/oned/Makefile.am +++ b/src/ciderlib/oned/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcideroned.a +noinst_LTLIBRARIES = libcideroned.la -libcideroned_a_SOURCES = \ +libcideroned_la_SOURCES = \ oneadmit.c \ oneaval.c \ onecond.c \ diff --git a/src/ciderlib/support/Makefile.am b/src/ciderlib/support/Makefile.am index 1ce07fd45..5bd8eca73 100644 --- a/src/ciderlib/support/Makefile.am +++ b/src/ciderlib/support/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcidersuprt.a +noinst_LTLIBRARIES = libcidersuprt.la -libcidersuprt_a_SOURCES = \ +libcidersuprt_la_SOURCES = \ database.c \ devprint.c \ geominfo.c \ diff --git a/src/ciderlib/twod/Makefile.am b/src/ciderlib/twod/Makefile.am index ff589da7b..6e103f10c 100644 --- a/src/ciderlib/twod/Makefile.am +++ b/src/ciderlib/twod/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcidertwod.a +noinst_LTLIBRARIES = libcidertwod.la -libcidertwod_a_SOURCES = \ +libcidertwod_la_SOURCES = \ twoadmit.c \ twoaval.c \ twocond.c \ diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index 64b630cd2..0832e6cef 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -4,9 +4,11 @@ SUBDIRS = plotting help parser wdisp numparam DIST_SUBDIRS = plotting help parser wdisp numparam -noinst_LIBRARIES = libfte.a +noinst_LTLIBRARIES = libfte.la -libfte_a_SOURCES = \ +libfte_la_SOURCES = \ + com_measure2.c \ + com_measure2.h \ commands.c \ commands.h \ com_ahelp.c \ diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c new file mode 100644 index 000000000..d2be8cfa2 --- /dev/null +++ b/src/frontend/com_measure2.c @@ -0,0 +1,940 @@ +#include +#include + +#include +#include + +#include "vectors.h" +#include + +typedef struct measure +{ + char *result; + + char *m_vec; // name of the output variable which determines the beginning of the measurement + char *m_vec2; + int m_rise; + int m_fall; + int m_cross; + float m_val; // value of the m_ver at which the counter for crossing, rises or falls is incremented by one + float m_td; // amount of delay before the measurement should start + float m_from; + float m_to; + float m_at; + float m_measured; + float m_measured_at; + +} measure; + +enum AnalysisType { + AT_DELAY, AT_TRIG, + AT_FIND, AT_WHEN, + AT_AVG, AT_MIN, AT_MAX, AT_RMS, AT_PP, + AT_INTEG, AT_DERIV, + AT_ERR, AT_ERR1, AT_ERR2, AT_ERR3 +}; + +void com_measure_when(struct measure *meas) { + + int i, first; + int riseCnt =0; + int fallCnt =0; + int crossCnt =0; + int section = -1; + float value, prevValue; + float timeValue, prevTimeValue; + + enum ValSide { S_ABOVE_VAL, S_BELOW_VAL }; + enum ValEdge { E_RISING, E_FALLING }; + + struct dvec *d, *dTime; + + d = vec_get(meas->m_vec); + dTime = plot_cur->pl_scale; + + if (d == NULL) { + fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec); + return; + } + + if (dTime == NULL) { + fprintf(cp_err, "Error: no such vector as time.\n"); + return; + } + + prevValue =0; + prevTimeValue =0; + first =0; + + for (i=0; i < d->v_length; i++) { + + value = d->v_realdata[i]; + timeValue = dTime->v_realdata[i]; + + if (timeValue < meas->m_td) + continue; + + if (first == 1) { + // initialise + crossCnt =0; + if (value < meas->m_val) { + section = S_BELOW_VAL; + if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) { + fallCnt =1; + crossCnt =1; + } + + } else { + section = S_ABOVE_VAL; + if ( (prevValue <= meas->m_val) && (value >= meas->m_val) ) { + riseCnt =1; + crossCnt =1; + } + } + printf(""); + } + + if (first > 1) { + + if ( (section == S_BELOW_VAL) && (value >= meas->m_val) ) { + section = S_ABOVE_VAL; + crossCnt++; + riseCnt++; + + } else if ( (section == S_ABOVE_VAL) && (value <= meas->m_val) ) { + section = S_BELOW_VAL; + crossCnt++; + fallCnt++; + } + + if ((crossCnt == meas->m_cross) || (riseCnt == meas->m_rise) || (fallCnt == meas->m_fall)) { + meas->m_measured = prevTimeValue + (meas->m_val - prevValue) * (timeValue - prevTimeValue) / (value - prevValue); + return; + + } + } + first ++; + + prevValue = value; + prevTimeValue = timeValue; + } + + meas->m_measured = 0.0e0; + return; +} + +void measure_at(struct measure *meas, float at) { + + int i; + float value, pvalue, svalue, psvalue; + struct dvec *d, *dScale; + + psvalue = pvalue = 0; + d = vec_get(meas->m_vec); + dScale = plot_cur->pl_scale; + + if (d == NULL) { + fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec); + return; + } + + if (dScale == NULL) { + fprintf(cp_err, "Error: no such vector time.\n"); + return; + } + + for (i=0; i < d->v_length; i++) { + value = d->v_realdata[i]; + svalue = dScale->v_realdata[i]; + + if ( (i > 0) && (psvalue <= at) && (svalue >= at) ) { + meas->m_measured = pvalue + (at - psvalue) * (value - pvalue) / (svalue - psvalue); + // meas->m_measured = value; + return; + } + + psvalue = svalue; + pvalue = value; + } + + meas->m_measured = 0.0e0; + return; +} + +void measure_avg( ) { + // AVG (Average): + // Calculates the area under the 'out_var' divided by the periods of intrest + return; +} + +void measure_minMaxAvg( struct measure *meas, int minMax ) { + + int i, avgCnt; + struct dvec *d, *dScale; + float value, svalue, mValue, mValueAt; + int first; + + mValue =0; + mValueAt = svalue =0; + meas->m_measured = 0.0e0; + meas->m_measured_at = 0.0e0; + first =0; + avgCnt =0; + + d = vec_get(meas->m_vec); + if (d == NULL) { + fprintf(cp_err, "Error: no such vector as %s.\n", meas->m_vec); + return; + } + + dScale = vec_get("time"); + if (d == NULL) { + fprintf(cp_err, "Error: no such vector as time.\n"); + return; + } + + for (i=0; i < d->v_length; i++) { + value = d->v_realdata[i]; + svalue = dScale->v_realdata[i]; + + if (svalue < meas->m_from) + continue; + + if ((meas->m_to != 0.0e0) && (svalue > meas->m_to) ) + break; + + if (first ==0) { + mValue = value; + mValueAt = svalue; + first =1; + + } else { + switch (minMax) { + case AT_MIN: { + if (value <= mValue) { + mValue = value; + mValueAt = svalue; + } + break; + } + case AT_MAX: { + if (value >= mValue) { + mValue = value; + mValueAt = svalue; + } + break; + } + case AT_AVG: + case AT_RMS: { + mValue = mValue + value; + avgCnt ++; + break; + } + } + + } + } + + switch (minMax) + { + case AT_AVG: { + meas->m_measured = (mValue / avgCnt); + meas->m_measured_at = svalue; + break; + } + case AT_RMS: { + // printf(" mValue %e svalue %e avgCnt %i, ", mValue, svalue, avgCnt); + meas->m_measured = sqrt(mValue) / avgCnt; + meas->m_measured_at = svalue; + break; + } + case AT_MIN: + case AT_MAX: { + meas->m_measured = mValue; + meas->m_measured_at = mValueAt; + break; + } + } + + return; +} + +void measure_rms( ) { + // RMS (root mean squared): + // Calculates the square root of the area under the 'out_var2' curve + // divided be the period of interest + return; +} + +void measure_integ( ) { + // INTEGRAL INTEG + return; +} + +void measure_deriv( ) { + // DERIVATIVE DERIV + return; +} + +// ERR Equations +void measure_ERR( ) { + return; +} + +void measure_ERR1( ) { + return; +} + +void measure_ERR2( ) { + return; +} + +void measure_ERR3( ) { + return; +} + +void measure_errMessage(char *mName, char *mFunction, char *trigTarg, char *errMsg) { + + printf("\tmeasure '%s' failed\n", mName); + printf("Error: measure %s %s(%s) :\n", mName, mFunction, trigTarg); + printf("\t%s\n",errMsg); + return; +} + +void com_dotmeasure( ) { + + // simulation info +// printf("*%s\n", plot_cur->pl_title); +// printf("\t %s, %s\n", plot_cur->pl_name, plot_cur->pl_date); // missing temp + + return; +} + +int measure_valid_vector(char *vec) { + + struct dvec *d; + + d = vec_get(vec); + if (d == NULL) + return 0; + + return 1; +} + +int measure_parse_stdParams (struct measure *meas, wordlist *wl, wordlist *wlBreak, char *errbuf) { + + int pCnt; + char *p, *pName, *pValue; + double *engVal, engVal1; + + pCnt =0; + while (wl != wlBreak) { + p = wl->wl_word; + pName = strtok(p, "="); + pValue = strtok(NULL, "="); + + if (pValue == NULL) { + sprintf(errbuf,"bad syntax of ??\n"); + return 0; + } + + if (!(engVal = ft_numparse(&pValue, FALSE))) { + sprintf(errbuf,"bad syntax of ??\n"); + return 0; + } + + engVal1 = *engVal; + + if(strcasecmp(pName,"RISE")==0) { + meas->m_rise = engVal1; + meas->m_fall = -1; + meas->m_cross = -1; + } else if(strcasecmp(pName,"FALL")==0) { + meas->m_fall = engVal1; + meas->m_rise = -1; + meas->m_cross = -1; + } else if(strcasecmp(pName,"CROSS")==0) { + meas->m_cross = engVal1; + meas->m_rise = -1; + meas->m_fall = -1; + } else if(strcasecmp(pName,"VAL")==0) { + meas->m_val = engVal1; + } else if(strcasecmp(pName,"TD")==0) { + meas->m_td = engVal1; + } else if(strcasecmp(pName,"FROM")==0) { + meas->m_from = engVal1; + } else if(strcasecmp(pName,"TO")==0) { + meas->m_to = engVal1; + } else if(strcasecmp(pName,"AT")==0) { + meas->m_at = engVal1; + } else { + sprintf(errbuf,"no such parameter as '%s'\n",pName); + return 0; + } + + pCnt ++; + wl = wl->wl_next; + } + + if (pCnt == 0) { + sprintf(errbuf,"bad syntax of ??\n"); + return 0; + } + + // valid vector + if (measure_valid_vector(meas->m_vec)==0) { + sprintf(errbuf,"no such vector as '%s'\n", meas->m_vec); + return 0; + } + + // valid vector2 + if (meas->m_vec2 != NULL) { + if (measure_valid_vector(meas->m_vec2)==0) { + sprintf(errbuf,"no such vector as '%s'\n", meas->m_vec2); + return 0; + } + } + + return 1; +} + +int measure_parse_find (struct measure *meas, wordlist *wl, wordlist *wlBreak, char *errbuf) { + + int pCnt; + char *p, *pName, *pVal; + double *engVal, engVal1; + + meas->m_vec = NULL; + meas->m_vec2 = NULL; + meas->m_val = -1; + meas->m_cross = -1; + meas->m_fall = -1; + meas->m_rise = -1; + meas->m_td = 0; + meas->m_from = 0.0e0; + meas->m_to = 0.0e0; + meas->m_at = -1; + + pCnt =0; + while(wl != wlBreak) { + p = wl->wl_word; + + if (pCnt == 0 ) { +// meas->m_vec =(char *)malloc(strlen(wl->wl_word)+1); + // strcpy(meas->m_vec, cp_unquote(wl->wl_word)); + meas->m_vec= cp_unquote(wl->wl_word); + } else if (pCnt == 1) { + + pName = strtok(p, "="); + pVal = strtok(NULL, "="); + + if (pVal == NULL) { + sprintf(errbuf,"bad syntax of WHEN\n"); + return 0; + } + + if (strcasecmp(pName,"AT")==0) { + + if (!(engVal = ft_numparse(&pVal, FALSE))) { + sprintf(errbuf,"bad syntax of WHEN\n"); + return 0; + } + + engVal1 = *engVal; + + meas->m_at = engVal1; + + } else { + sprintf(errbuf,"bad syntax of WHEN\n"); + return 0; + } + } else { + if (measure_parse_stdParams(meas, wl, NULL, errbuf) == 0) + return 0; + } + + wl = wl->wl_next; + pCnt ++; + } + + return 1; +} + +int measure_parse_when (struct measure *meas, wordlist *wl, char *errBuf) { + + int pCnt; + char *p, *pVar1, *pVar2; + + meas->m_vec = NULL; + meas->m_vec2 = NULL; + meas->m_val = -1; + meas->m_cross = -1; + meas->m_fall = -1; + meas->m_rise = -1; + meas->m_td = 0; + meas->m_from = 0.0e0; + meas->m_to = 0.0e0; + meas->m_at = -1; + + pCnt =0; + while (wl) { + p= wl->wl_word; + + if (pCnt == 0) { + pVar1 = strtok(p, "="); + pVar2 = strtok(NULL, "="); + + if (pVar2 == NULL) { + sprintf(errBuf,"bad syntax\n"); + return 0; + } + + meas->m_vec = pVar1; + if (measure_valid_vector(pVar2)==1) + meas->m_vec2 = pVar2; + else + meas->m_val = atof(pVar2); + } else { + if (measure_parse_stdParams(meas, wl, NULL, errBuf) == 0) + return 0; + break; + } + + wl = wl->wl_next; + pCnt ++; + } + return 1; +} + + +int measure_parse_trigtarg (struct measure *meas, wordlist *words, wordlist *wlTarg, char *trigTarg, char *errbuf) { + + int pcnt; + char *p; + + meas->m_vec = NULL; + meas->m_vec2 = NULL; + meas->m_cross = -1; + meas->m_fall = -1; + meas->m_rise = -1; + meas->m_td = 0; + meas->m_from = 0.0e0; + meas->m_to = 0.0e0; + meas->m_at = -1; + + pcnt =0; + while (words != wlTarg) { + p = words->wl_word; + + if (pcnt ==0) { +// meas->m_vec =(char *)malloc(strlen(words->wl_word)+1); + // strcpy(meas->m_vec, cp_unquote(words->wl_word)); + meas->m_vec= cp_unquote(words->wl_word); + } else { + + if (measure_parse_stdParams(meas, words, wlTarg, errbuf) == 0) + return 0; + break; + + } + + words = words->wl_next; + pcnt ++; + } + + if (pcnt == 0) { + sprintf(errbuf,"bad syntax of '%s'\n", trigTarg); + return 0; + } + + // valid vector + if (measure_valid_vector(meas->m_vec)==0) { + sprintf(errbuf,"no such vector as '%s'\n", meas->m_vec); + return 0; + } + + return 1; +} + +float +get_measure2(wordlist *wl) +{ + wordlist *words, *wlTarg, *wlWhen; + char errbuf[100]; + char *mType = NULL; // analysis type + char *mName = NULL; // name given to the measured output + char *mFunction = NULL; + int mFunctionType, wl_cnt; + char *p; + + mFunctionType = -1; + + if (!wl) { + printf("usage: measure .....\n"); + return 0.0e0; + } + + if (!plot_cur || !plot_cur->pl_dvecs || !plot_cur->pl_scale) { + fprintf(cp_err, "Error: no vectors available\n"); + return 0.0e0; + } + + if (!ciprefix("tran", plot_cur->pl_typename)) { + fprintf(cp_err, "Error: measure limited to transient analysis\n"); + return 0.0e0; + } + + words =wl; + wlTarg = NULL; + wlWhen = NULL; + + if (!words) { + fprintf(cp_err, "Error: no assignment found.\n"); + return 0.0e0; + } + + wl_cnt = 0; + while (words) { + + switch(wl_cnt) + { + case 0: + mType = cp_unquote(words->wl_word); + break; + case 1: + mName = cp_unquote(words->wl_word); + break; + case 2: + { + mFunction = cp_unquote(words->wl_word); + // Functions + if (strcasecmp(mFunction,"DELAY")==0) + mFunctionType = AT_DELAY; + else if (strcasecmp(mFunction,"TRIG")==0) + mFunctionType = AT_DELAY; + else if (strcasecmp(mFunction,"FIND")==0) + mFunctionType = AT_FIND; + else if (strcasecmp(mFunction,"WHEN")==0) + mFunctionType = AT_WHEN; + else if (strcasecmp(mFunction,"AVG")==0) + mFunctionType = AT_AVG; + else if (strcasecmp(mFunction,"MIN")==0) + mFunctionType = AT_MIN; + else if (strcasecmp(mFunction,"MAX")==0) + mFunctionType = AT_MAX; + else if (strcasecmp(mFunction,"RMS")==0) + mFunctionType = AT_RMS; + else if (strcasecmp(mFunction,"PP")==0) + mFunctionType = AT_PP; + else if (strcasecmp(mFunction,"INTEG")==0) + mFunctionType = AT_INTEG; + else if (strcasecmp(mFunction,"DERIV")==0) + mFunctionType = AT_DERIV; + else if (strcasecmp(mFunction,"ERR")==0) + mFunctionType = AT_ERR; + else if (strcasecmp(mFunction,"ERR1")==0) + mFunctionType = AT_ERR1; + else if (strcasecmp(mFunction,"ERR2") == 0) + mFunctionType = AT_ERR2; + else if (strcasecmp(mFunction,"ERR3") == 0) + mFunctionType = AT_ERR3; + else { + printf("\tmeasure '%s' failed\n", mName); + printf("Error: measure %s :\n", mName); + printf("\tno such function as '%s'\n", mFunction); + return 0.0e0; + } + break; + } + default: + { + p = words->wl_word; + + if (strcasecmp(p,"targ")==0) + wlTarg = words; + + if (strcasecmp(p,"when")==0) + wlWhen = words; + + break; + } + } + wl_cnt ++; + words = words->wl_next; + } + + if (wl_cnt < 3) { + printf("\tmeasure '%s' failed\n", mName); + printf("Error: measure %s :\n", mName); + printf("\tinvalid num params\n"); + return 0.0e0; + } + + //------------------------ + + + words =wl; + + if (words) + words = words->wl_next; // skip + if (words) + words = words->wl_next; // results name + if (words) + words = words->wl_next; // Function + + + // switch here + switch(mFunctionType) + { + case AT_DELAY: + case AT_TRIG: + { + // trig parameters + measure *measTrig, *measTarg; + measTrig = (struct measure*)malloc(sizeof(struct measure)); + measTarg = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_trigtarg(measTrig, words , wlTarg, "trig", errbuf)==0) { + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + + if ((measTrig->m_rise == -1) && (measTrig->m_fall == -1) && (measTrig->m_cross == -1)) { + sprintf(errbuf,"rise, fall or cross must be given\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + + while (words != wlTarg) + words = words->wl_next; // hack + + if (words) + words = words->wl_next; // skip targ + + if (measure_parse_trigtarg(measTarg, words , NULL, "targ", errbuf)==0) { + measure_errMessage(mName, mFunction, "TARG", errbuf); + return 0.0e0; + } + + if ((measTarg->m_rise == -1) && (measTarg->m_fall == -1) && (measTarg->m_cross == -1)) { + sprintf(errbuf,"rise, fall or cross must be given\n"); + measure_errMessage(mName, mFunction, "TARG", errbuf); + return 0.0e0; + } + + // measure trig + if (measTrig->m_at == -1) + com_measure_when(measTrig); + else + measTrig->m_measured = measTrig->m_at; + + + if (measTrig->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + // measure targ + com_measure_when(measTarg); + + if (measTarg->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TARG", errbuf); + return 0.0e0; + } + + // print results + printf("%-20s= %e targ= %e trig= %e\n", mName, (measTarg->m_measured - measTrig->m_measured), measTarg->m_measured, measTrig->m_measured); + + return (measTarg->m_measured - measTrig->m_measured); + } + case AT_FIND: + { + measure *meas, *measFind; + meas = (struct measure*)malloc(sizeof(struct measure)); + measFind = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_find(meas, words, wlWhen, errbuf) == 0) { + measure_errMessage(mName, mFunction, "FIND", errbuf); + return 0.0e0; + } + + if (meas->m_at == -1 ) { + // find .. when statment + + while (words != wlWhen) + words = words->wl_next; // hack + + if (words) + words = words->wl_next; // skip targ + + if (measure_parse_when(measFind, words, errbuf) ==0) { + measure_errMessage(mName, mFunction, "WHEN", errbuf); + return 0.0e0; + } + + com_measure_when(measFind); + + if (measFind->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "WHEN", errbuf); + return 0.0e0; + } + + measure_at(measFind, measFind->m_measured); + meas->m_measured = measFind->m_measured; + + } else { + measure_at(meas, meas->m_at); + } + + if (meas->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "WHEN", errbuf); + return 0.0e0; + } + + // print results + printf("%-20s= %e\n", mName, meas->m_measured); + return meas->m_measured; + } + case AT_WHEN: + { + measure *meas; + meas = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_when(meas, words, errbuf) ==0) { + measure_errMessage(mName, mFunction, "WHEN", errbuf); + return 0.0e0; + } + + com_measure_when(meas); + + if (meas->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "WHEN", errbuf); + return 0.0e0; + } + + // print results + printf("%-20s= %e\n", mName, meas->m_measured); + + return (meas->m_measured); + } + case AT_RMS: + printf("\tmeasure '%s' failed\n", mName); + printf("Error: measure %s :\n", mName); + printf("\tfunction '%s' currently not supported\n", mFunction); + break; + case AT_AVG: + { + // trig parameters + measure *meas; + meas = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_trigtarg(meas, words , NULL, "trig", errbuf)==0) { + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + + // measure + measure_minMaxAvg(meas, mFunctionType); + + if (meas->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); // ?? + return 0.0e0; + } + + if (meas->m_at == -1) + meas->m_at = 0.0e0; + + // print results + printf("%-20s= %e from= %e to= %e\n", mName, meas->m_measured, meas->m_at, meas->m_measured_at); + return meas->m_measured; + + } + case AT_MIN: + case AT_MAX: + { + // trig parameters + measure *measTrig; + measTrig = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_trigtarg(measTrig, words , NULL, "trig", errbuf)==0) { + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + + // measure + if (mFunctionType == AT_MIN) + measure_minMaxAvg(measTrig, AT_MIN); + else + measure_minMaxAvg(measTrig, AT_MAX); + + + if (measTrig->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); // ?? + return 0.0e0; + } + + // print results + printf("%-20s= %e at= %e\n", mName, measTrig->m_measured, measTrig->m_measured_at); + return measTrig->m_measured; + } + case AT_PP: + { + float minValue, maxValue; + + measure *measTrig; + measTrig = (struct measure*)malloc(sizeof(struct measure)); + + if (measure_parse_trigtarg(measTrig, words , NULL, "trig", errbuf)==0) { + measure_errMessage(mName, mFunction, "TRIG", errbuf); + return 0.0e0; + } + + // measure min + measure_minMaxAvg(measTrig, AT_MIN); + if (measTrig->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); // ?? + return 0.0e0; + } + minValue = measTrig->m_measured; + + // measure max + measure_minMaxAvg(measTrig, AT_MAX); + if (measTrig->m_measured == 0.0e0) { + sprintf(errbuf,"out of interval\n"); + measure_errMessage(mName, mFunction, "TRIG", errbuf); // ?? + return 0.0e0; + } + maxValue = measTrig->m_measured; + + // print results + printf("%-20s= %e from= %e to= %e\n", mName, (maxValue - minValue), measTrig->m_from, measTrig->m_to); + return (maxValue - minValue); + } + case AT_INTEG: + case AT_DERIV: + case AT_ERR: + case AT_ERR1: + case AT_ERR2: + case AT_ERR3: + { + printf("\tmeasure '%s' failed\n", mName); + printf("Error: measure %s :\n", mName); + printf("\tfunction '%s' currently not supported\n", mFunction); + break; + } + } + return 0.0e0; +} + +void com_measure2(wordlist *wl) { + get_measure2(wl); + return; +} + diff --git a/src/frontend/com_measure2.h b/src/frontend/com_measure2.h new file mode 100644 index 000000000..6316f3e7d --- /dev/null +++ b/src/frontend/com_measure2.h @@ -0,0 +1,9 @@ +#ifndef _COM_MEASURE_H +#define _COM_MEASURE_H + +#include + +void com_measure2(wordlist *wl); +float get_measure2(wordlist *wl); + +#endif diff --git a/src/frontend/com_plot.c b/src/frontend/com_plot.c index e1cf9b5ee..adb0e1920 100644 --- a/src/frontend/com_plot.c +++ b/src/frontend/com_plot.c @@ -16,3 +16,14 @@ com_plot(wordlist *wl) plotit(wl, (char *) NULL, (char *) NULL); return; } + +#ifdef TCL_MODULE +void +com_bltplot(wordlist *wl) +{ + plotit(wl, (char *) NULL, "blt"); + return; +} + +#endif + diff --git a/src/frontend/com_plot.h b/src/frontend/com_plot.h index b7abae3e8..7599e75a3 100644 --- a/src/frontend/com_plot.h +++ b/src/frontend/com_plot.h @@ -2,5 +2,7 @@ #define _COM_PLOT_H void com_plot(wordlist *wl); - +#ifdef TCL_MODULE +void com_bltplot(wordlist *wl); +#endif #endif diff --git a/src/frontend/commands.c b/src/frontend/commands.c index 1b09f8a60..158eef858 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -118,10 +118,21 @@ struct comm spcp_coms[] = { { 0, 0, 0, 0 }, E_DEFHMASK, 3, LOTS, (void (*)()) NULL, "spec name pat ... : Redefine vector and plot types.\n" } , +#ifdef TCL_MODULE + { "bltplot", com_bltplot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, + arg_plot, + "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, + { "plot", com_bltplot, FALSE, FALSE, TRUE, + { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, + arg_plot, + "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, +#else { "plot", com_plot, FALSE, FALSE, TRUE, { 041000, 041000, 041000, 041000 }, E_BEGINNING | E_HASPLOTS, 1, LOTS, arg_plot, "expr ... [vs expr] [xl xlo xhi] [yl ylo yhi] : Plot things." }, +#endif { "display", com_display, FALSE, FALSE, TRUE, { 040000, 040000, 040000, 040000 }, E_BEGINNING, 0, LOTS, arg_display, diff --git a/src/frontend/display.c b/src/frontend/display.c index 11a0257c5..eff8234f8 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -11,6 +11,10 @@ $Id$ #include /* for VT_STRING */ #include /* for mylog() */ +#ifdef TCL_MODULE +#include +#endif + #include "display.h" #include "variable.h" #include "error.h" @@ -70,6 +74,15 @@ DISPDEVICE device[] = { gen_DatatoScreen,}, /* WPRINT_DiagramReady */ #endif +#ifdef TCL_MODULE + {"Tk", 0, 0, 1024, 864, 0, 0, sp_Tk_Init, sp_Tk_NewViewport, + sp_Tk_Close, sp_Tk_Clear, + sp_Tk_DrawLine, sp_Tk_Arc, sp_Tk_Text, sp_Tk_DefineColor, sp_Tk_DefineLinestyle, + sp_Tk_SetLinestyle, sp_Tk_SetColor, sp_Tk_Update, + nodev, nodev, nodev, nodev, + gen_DatatoScreen,}, +#endif + {"plot5", 0, 0, 1000, 1000, 0, 0, Plt5_Init, Plt5_NewViewport, Plt5_Close, Plt5_Clear, Plt5_DrawLine, Plt5_Arc, Plt5_Text, (void*)nodev, (void*)nodev, @@ -151,6 +164,10 @@ DevInit(void) } #endif +#ifdef TCL_MODULE + dispdev = FindDev("Tk"); +#endif + if (!dispdev) { externalerror( "no graphics interface; please check compiling instructions"); diff --git a/src/frontend/help/Makefile.am b/src/frontend/help/Makefile.am index a665b63d4..79ed0d95b 100644 --- a/src/frontend/help/Makefile.am +++ b/src/frontend/help/Makefile.am @@ -2,9 +2,9 @@ if !NO_X -noinst_LIBRARIES = libhlp.a +noinst_LTLIBRARIES = libhlp.la -libhlp_a_SOURCES = \ +libhlp_la_SOURCES = \ help.c \ provide.c \ readhelp.c \ diff --git a/src/frontend/numparam/Makefile.am b/src/frontend/numparam/Makefile.am index f2ced1d85..a215afc23 100644 --- a/src/frontend/numparam/Makefile.am +++ b/src/frontend/numparam/Makefile.am @@ -2,9 +2,9 @@ EXTRA_DIST = downgrad.txt ngconfig.sh readme.txt nupatest.c washprog.c -noinst_LIBRARIES = libnumparam.a +noinst_LTLIBRARIES = libnumparam.la -libnumparam_a_SOURCES = \ +libnumparam_la_SOURCES = \ spicenum.c \ xpressn.c \ mystring.c \ diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c index 22cc00647..9ecc0da30 100644 --- a/src/frontend/outitf.c +++ b/src/frontend/outitf.c @@ -58,6 +58,12 @@ static bool name_eq(char *n1, char *n2); static bool getSpecial(dataDesc *desc, runDesc *run, IFvalue *val); static void freeRun(runDesc *run); +/*Output data to spice module saj*/ +#ifdef TCL_MODULE +#include "tclspice.h" +#endif +/*saj*/ + #define DOUBLE_PRECISION 15 @@ -354,6 +360,10 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch run->runPlot->pl_ndims = 1; } } + /*Start BLT, initilises the blt vectors saj*/ +#ifdef TCL_MODULE + blt_init(run); +#endif return (OK); } @@ -435,6 +445,9 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) #endif /* PARALLEL_ARCH */ run->pointCount++; +#ifdef TCL_MODULE + steps_completed = run->pointCount; +#endif if (run->writeOut) { if (run->pointCount == 1) @@ -473,6 +486,9 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) for (i = 0; i < run->numData; i++) { /* we've already printed reference vec first */ if (run->data[i].outIndex == -1) continue; +#ifdef TCL_MODULE + blt_add(i,refValue->rValue); +#endif if (run->data[i].regular) { if(run->data[i].type == IF_REAL) @@ -518,6 +534,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) else fprintf(stderr, "OUTpData: unsupported data type\n"); } +#ifdef TCL_MODULE + blt_add(i,valuePtr->v.vec.rVec + [run->data[i].outIndex]); +#endif } fileEndPoint(run->fp, run->binary); @@ -546,6 +566,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) } #endif for (i = 0; i < run->numData; i++) { +#ifdef TCL_MODULE + /*Locks the blt vector to stop access*/ + blt_lockvec(i); +#endif if (run->data[i].outIndex == -1) { if (run->data[i].type == IF_REAL) plotAddRealValue(&run->data[i], @@ -575,6 +599,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) else fprintf(stderr, "OUTpData: unsupported data type\n"); } +#ifdef TCL_MODULE + /*relinks and unlocks vector*/ + blt_relink(i,(run->data[i]).vec); +#endif } gr_iplot(run->runPlot); } @@ -582,6 +610,11 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) if (ft_bpcheck(run->runPlot, run->pointCount) == FALSE) shouldstop = TRUE; +#ifdef TCL_MODULE + Tcl_ExecutePerLoop(); +#endif + + return (OK); } diff --git a/src/frontend/parser/Makefile.am b/src/frontend/parser/Makefile.am index aa4caaaf1..290f04a29 100644 --- a/src/frontend/parser/Makefile.am +++ b/src/frontend/parser/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libparser.a +noinst_LTLIBRARIES = libparser.la -libparser_a_SOURCES = \ +libparser_la_SOURCES = \ backq.c \ backq.h \ complete.c \ diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am index 53e927b53..12da03853 100644 --- a/src/frontend/plotting/Makefile.am +++ b/src/frontend/plotting/Makefile.am @@ -1,6 +1,6 @@ -noinst_LIBRARIES = libplotting.a +noinst_LTLIBRARIES = libplotting.la -libplotting_a_SOURCES = \ +libplotting_la_SOURCES = \ plotting.c \ plotting.h \ agraf.c \ @@ -25,7 +25,7 @@ libplotting_a_SOURCES = \ plotit.h if !NO_X -libplotting_a_SOURCES += \ +libplotting_la_SOURCES += \ x11.c \ x11.h \ xgraph.c \ diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 468d1779a..aa60f310e 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -21,6 +21,7 @@ $Id$ #include #include "ftedbgra.h" #include "ftedev.h" +#include #include #include "graf.h" #include "graphdb.h" diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index d02287aaa..87048daee 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -21,7 +21,9 @@ static wordlist *wl_root; static bool sameflag; - +#ifdef TCL_MODULE +#include +#endif /* This routine gets parameters from the command line, which are of * the form "name number ..." It returns a pointer to the parameter @@ -976,7 +978,17 @@ plotit(wordlist *wl, char *hcopy, char *devname) goto quit; } - +#ifdef TCL_MODULE + if (devname && eq(devname, "blt")) { + /* Just send the pairs to Tcl/Tk */ + for (d = vecs; d; d = d->v_link2) { + blt_plot(d, oneval ? (struct dvec *) NULL : d->v_scale,(d==vecs?1:0)); + } + rtn = TRUE; + goto quit; + } +#endif + for (d = vecs, i = 0; d; d = d->v_link2) i++; diff --git a/src/frontend/terminal.c b/src/frontend/terminal.c index b1eea062d..bd2015663 100644 --- a/src/frontend/terminal.c +++ b/src/frontend/terminal.c @@ -44,7 +44,17 @@ $Id$ #include "variable.h" #include "terminal.h" +/* out_printf doesn't handle double arguments correctly, so we + sprintf into this buf and call out_send w/ it */ +char out_pbuf[8*BSIZE_SP]; + +bool out_moremode = TRUE; +bool out_isatty = TRUE; + +#ifndef TCL_MODULE + #ifdef HAVE_TERMCAP + static char *motion_chars; static char *clear_chars; static char *home_chars; @@ -54,17 +64,11 @@ static char *cleol_chars; #define DEF_SCRHEIGHT 24 #define DEF_SCRWIDTH 80 -bool out_moremode = TRUE; -bool out_isatty = TRUE; - static int xsize, ysize; static int xpos, ypos; static bool noprint, nopause; -/* out_printf doesn't handle double arguments correctly, so we - sprintf into this buf and call out_send w/ it */ -char out_pbuf[8*BSIZE_SP]; /* Start output... */ @@ -345,3 +349,23 @@ term_cleol(void) tputs(cleol_chars, 1, outfn); #endif } + +#else + +void out_init(void) {} +void outbufputc(void) {} +void promptreturn(void) {} +void term_clear(void) {} +void term_home(void) {} +void term_cleol(void) {} +void tcap_init(void) {} + +void out_send(char *string) {fprintf(cp_out,string);} + +void +out_printf(char *fmt, char *s1, char *s2, char *s3, char *s4, char *s5, + char *s6, char *s7, char *s8, char *s9, char *s10) { + fprintf(cp_out,fmt, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10); +} + +#endif /* TCL_MODULE */ diff --git a/src/frontend/wdisp/Makefile.am b/src/frontend/wdisp/Makefile.am index 650fbcc48..9b110432c 100644 --- a/src/frontend/wdisp/Makefile.am +++ b/src/frontend/wdisp/Makefile.am @@ -1,9 +1,9 @@ ## Process this file with automake to produce Makefile.in ## $Id$ -noinst_LIBRARIES = libwindisp.a +noinst_LTLIBRARIES = libwindisp.la -libwindisp_a_SOURCES = \ +libwindisp_la_SOURCES = \ windisp.c \ windisp.h \ winprint.c \ diff --git a/src/include/Makefile.am b/src/include/Makefile.am index a1dd98842..560860e64 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -2,6 +2,7 @@ ## $Id$ noinst_HEADERS = \ + tclspice.h \ acdefs.h \ bdrydefs.h \ bool.h \ diff --git a/src/include/ngspice.h b/src/include/ngspice.h index fa2a02b22..e18e35509 100644 --- a/src/include/ngspice.h +++ b/src/include/ngspice.h @@ -207,6 +207,21 @@ extern char *Lib_Path; extern int ARCHme; /* My logical process number */ extern int ARCHsize; /* Total number of processes */ +#ifdef TCL_MODULE + +#include + +extern int tcl_printf(const char *format, ...); +extern int tcl_fprintf(FILE *f, const char *format, ...); + +#undef printf +#define printf tcl_printf + +#undef perror +#define perror(string) fprintf(stderr,"%s: %s\n",string,sys_errlist[errno]) + +#endif + #ifdef CIDER /* Definitions of globals for Machine Accuracy Limits * Imported from cider diff --git a/src/include/tclspice.h b/src/include/tclspice.h new file mode 100755 index 000000000..6cd2e9a6d --- /dev/null +++ b/src/include/tclspice.h @@ -0,0 +1,33 @@ +/*Include file to allow spice to export certain data */ +#ifndef TCLSPICE_H +#define TCLSPICE_H + +extern int steps_completed; +extern void blt_init(void *run); +extern void blt_add(int index,double value); +extern void blt_relink(int index, void* v); +extern void blt_lockvec(int index); + +/* For things to do per loop */ +int Tcl_ExecutePerLoop(); + +/* For tk ploting */ +extern int sp_Tk_Init(void); +#include +extern int sp_Tk_NewViewport(GRAPH *graph); +extern int sp_Tk_Close(void); +extern int sp_Tk_Clear(void); +extern int sp_Tk_DrawLine(int x1, int y1, int x2, int y2); +extern int sp_Tk_Arc(int x0, int y0, int radius, double theta1, double theta2); +extern int sp_Tk_Text(char *text, int x, int y); +extern int sp_Tk_DefineColor(int colorid, double red, double green, double blue); +extern int sp_Tk_DefineLinestyle(int linestyleid, int mask); +extern int sp_Tk_SetLinestyle(int linestyleid); +extern int sp_Tk_SetColor(int colorid); +extern int sp_Tk_Update(void); + +/* The blt callback method */ +#include +extern int blt_plot(struct dvec *y,struct dvec *x,int new); + +#endif diff --git a/src/main.c b/src/main.c index 5907d886d..ffe8942d3 100644 --- a/src/main.c +++ b/src/main.c @@ -153,7 +153,7 @@ struct variable *(*if_getparam)( ); static int started = FALSE; /* static functions */ -static int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator); +int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator); static int sp_shutdown(int exitval); static void app_rl_readlines(void); @@ -190,12 +190,37 @@ bool ft_nutmeg = FALSE; extern struct comm spcp_coms[ ]; struct comm *cp_coms = spcp_coms; + +extern int OUTpBeginPlot(), OUTpData(), OUTwBeginPlot(), OUTwReference(); +extern int OUTwData(), OUTwEnd(), OUTendPlot(), OUTbeginDomain(); +extern int OUTendDomain(), OUTstopnow(), OUTerror(), OUTattributes(); + + + +IFfrontEnd nutmeginfo = { + IFnewUid, + IFdelUid, + OUTstopnow, + seconds, + OUTerror, + OUTpBeginPlot, + OUTpData, + OUTwBeginPlot, + OUTwReference, + OUTwData, + OUTwEnd, + OUTendPlot, + OUTbeginDomain, + OUTendDomain, + OUTattributes + };; + #else /* SIMULATOR */ bool ft_nutmeg = TRUE; extern struct comm nutcp_coms[ ]; struct comm *cp_coms = nutcp_coms; -static IFfrontEnd nutmeginfo; +IFfrontEnd nutmeginfo; /* -------------------------------------------------------------------------- */ int @@ -320,7 +345,7 @@ IFfrontEnd *SPfrontEnd = NULL; int DEVmaxnum = 0; /* -------------------------------------------------------------------------- */ -static int +int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator) { #ifdef SIMULATOR @@ -616,11 +641,6 @@ read_initialisation_file(char * dir, char * name) /* -------------------------------------------------------------------------- */ -#ifdef SIMULATOR -extern int OUTpBeginPlot(), OUTpData(), OUTwBeginPlot(), OUTwReference(); -extern int OUTwData(), OUTwEnd(), OUTendPlot(), OUTbeginDomain(); -extern int OUTendDomain(), OUTstopnow(), OUTerror(), OUTattributes(); -#endif /* SIMULATOR */ int #ifdef HAS_WINDOWS @@ -639,23 +659,7 @@ main(int argc, char **argv) #ifdef SIMULATOR int error2; - static IFfrontEnd nutmeginfo = { - IFnewUid, - IFdelUid, - OUTstopnow, - seconds, - OUTerror, - OUTpBeginPlot, - OUTpData, - OUTwBeginPlot, - OUTwReference, - OUTwData, - OUTwEnd, - OUTendPlot, - OUTbeginDomain, - OUTendDomain, - OUTattributes - }; + #else /* ~ SIMULATOR */ bool gdata = TRUE; #endif /* ~ SIMULATOR */ @@ -1116,4 +1120,4 @@ evl: #endif /* ~ SIMULATOR */ return sp_shutdown(EXIT_NORMAL); -} +} \ No newline at end of file diff --git a/src/maths/cmaths/Makefile.am b/src/maths/cmaths/Makefile.am index 6ab086c3a..e1aed3964 100644 --- a/src/maths/cmaths/Makefile.am +++ b/src/maths/cmaths/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcmaths.a +noinst_LTLIBRARIES = libcmaths.la -libcmaths_a_SOURCES = \ +libcmaths_la_SOURCES = \ cmath.h \ cmath1.c \ cmath1.h \ @@ -22,22 +22,25 @@ test_cx_ph_SOURCES = \ test_cx_ph.c test_cx_ph_LDADD = \ - libcmaths.a \ - ../../misc/libmisc.a + libcmaths.la \ + ../../misc/libmisc.la \ + $(TCL_LIB_SPEC) test_cx_mag_SOURCES = \ test_cx_mag.c test_cx_mag_LDADD = \ - libcmaths.a \ - ../../misc/libmisc.a + libcmaths.la \ + ../../misc/libmisc.la \ + $(TCL_LIB_SPEC) test_cx_j_SOURCES = \ test_cx_j.c test_cx_j_LDADD = \ - libcmaths.a \ - ../../misc/libmisc.a + libcmaths.la \ + ../../misc/libmisc.la \ + $(TCL_LIB_SPEC) TESTS = test_cx_mag test_cx_j test_cx_ph diff --git a/src/maths/deriv/Makefile.am b/src/maths/deriv/Makefile.am index 914fd0cb5..a15636287 100644 --- a/src/maths/deriv/Makefile.am +++ b/src/maths/deriv/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libderiv.a +noinst_LTLIBRARIES = libderiv.la -libderiv_a_SOURCES = \ +libderiv_la_SOURCES = \ atander.c \ cosderiv.c \ cubeder.c \ diff --git a/src/maths/ni/Makefile.am b/src/maths/ni/Makefile.am index 6171f5c91..22a217d65 100644 --- a/src/maths/ni/Makefile.am +++ b/src/maths/ni/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libni.a +noinst_LTLIBRARIES = libni.la -libni_a_SOURCES = \ +libni_la_SOURCES = \ niaciter.c \ niaciter.h \ nicomcof.c \ diff --git a/src/maths/poly/Makefile.am b/src/maths/poly/Makefile.am index 58e0685c4..77f8417d8 100644 --- a/src/maths/poly/Makefile.am +++ b/src/maths/poly/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libpoly.a +noinst_LTLIBRARIES = libpoly.la -libpoly_a_SOURCES = \ +libpoly_la_SOURCES = \ interpolate.c \ interpolate.h \ polyfit.c \ diff --git a/src/maths/sparse/Makefile.am b/src/maths/sparse/Makefile.am index eb2670e96..27438e5b7 100644 --- a/src/maths/sparse/Makefile.am +++ b/src/maths/sparse/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libsparse.a +noinst_LTLIBRARIES = libsparse.la -libsparse_a_SOURCES = \ +libsparse_la_SOURCES = \ spalloc.c \ spbuild.c \ spcombin.c \ diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index 9cf279a9f..3bd3c084a 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -1,10 +1,10 @@ ## Process this file with automake to produce Makefile.in ## $Id$ -noinst_LIBRARIES = libmisc.a +noinst_LTLIBRARIES = libmisc.la -libmisc_a_SOURCES = \ +libmisc_la_SOURCES = \ getopt1.c \ getopt.c \ getopt.h \ diff --git a/src/misc/alloc.c b/src/misc/alloc.c index 5dea5442f..6399fd64d 100644 --- a/src/misc/alloc.c +++ b/src/misc/alloc.c @@ -13,6 +13,11 @@ $Id$ #include #include +/*saj For Tcl module locking*/ +#ifdef TCL_MODULE +#include +//#include +#endif /* Malloc num bytes and initialize to zero. Fatal error if the space can't * be tmalloc'd. Return NULL for a request for 0 bytes. @@ -24,9 +29,22 @@ void * tmalloc(size_t num) { void *s; +/*saj*/ +#ifdef TCL_MODULE + Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); +#endif if (!num) return NULL; +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexLock(alloc); +#endif s = calloc(num,1); +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif if (!s){ fprintf(stderr,"malloc: Internal Error: can't allocate %ld bytes. \n",(long)num); exit(EXIT_BAD); @@ -38,7 +56,11 @@ void * trealloc(void *ptr, size_t num) { void *s; - +/*saj*/ +#ifdef TCL_MODULE + Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); +#endif if (!num) { if (ptr) free(ptr); @@ -47,9 +69,17 @@ trealloc(void *ptr, size_t num) if (!ptr) s = tmalloc(num); - else + else { +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexLock(alloc); +#endif s = realloc(ptr, num); - +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif + } if (!s) { fprintf(stderr,"realloc: Internal Error: can't allocate %ld bytes.\n",(long)num); exit(EXIT_BAD); @@ -111,8 +141,18 @@ trealloc(void *str, size_t num) void txfree(void *ptr) { +/*saj*/ +#ifdef TCL_MODULE + Tcl_Mutex *alloc; + alloc = Tcl_GetAllocMutex(); + Tcl_MutexLock(alloc); +#endif if (ptr) free(ptr); +/*saj*/ +#ifdef TCL_MODULE + Tcl_MutexUnlock(alloc); +#endif } #endif diff --git a/src/pkgIndex.tcl.in b/src/pkgIndex.tcl.in new file mode 100755 index 000000000..62ec633e6 --- /dev/null +++ b/src/pkgIndex.tcl.in @@ -0,0 +1,122 @@ + +proc Loadspice { version dir } { + + package require BLT + + set suffix [info sharedlibextension] + + set library spice${suffix} + + global tcl_platform + if { $tcl_platform(platform) == "unix" } { + set library [file join $dir lib${library}] + } + load $library spice + + blt::vector create ::spice::X_Data + blt::vector create ::spice::Y_Data + + namespace eval spice { + namespace export ac help save alias sens alter altermod iplot setcirc asciiplot jobs setplot aspice setscale bg let settype linearize shell bug listing shift show cdump maxstep showmod compose newhelp noise spec cross oldhelp spice dc op spice_data define spice_header deftype plot state delete plot_datapoints status delta plot_date step plot_get_value stop diff plot_name strcmp display plot_nvars tf disto plot_title dowhile plot_variables tran dump print transpose echo pz tutorial edit quit unalias else rehash undefine end repeat unlet reset fourier reshape version spicetoblt resume where get_output rspice get_param run write goto running xgraph hardcopy rusage steps_completed blt_vnum codemodel halt loadsnap savesnap getplot + + } + + # Callback functions for the plot command + # Warning: if any of these functions return an error then + # spice will probably segfault as tcl/tk will overflow somewhere + # Note: color is actually spelt COLOUR, which looks much better + # Note: they don't work in namespace so have to make global + + proc spice_gr_NewViewport { } { + set width 1000 + set height 400 + set fontwidth 12 + set fontheight 24 + canvas .c -width $width -height $height -background white + pack .c + return "$width $height $fontwidth $fontheight" + } + proc spice_gr_Close { } { + } + proc spice_gr_Clear { } { + } + proc spice_gr_DrawLine { x1 y1 x2 y2 } { + puts "draw" + .c create line [expr $x1 + 25] [expr 375 - $y1] [expr $x2 + 25] [expr 375 - $y2] + } + proc spice_gr_Arc { x0 y0 radius theta1 theta2 } { + .c create arc [expr $x0 - $radius + 25] [expr 375 - $y0 - $radius] \ + [expr $x1 + $radius + 25 ] [expr 375 - $y1 + $radius] \ + -start $theta1 -extent $theta2 + } + proc spice_gr_Text {text x y} { + .c create text [expr $x + 25] [expr 375 - $y] -text $text + } + + proc spice_gr_SetLinestyle {linestyleid} { + puts "SetLinestyle $linestyleid" + } + proc spice_gr_SetColor {colorid } { + puts "SetColor $colorid $color" + } + + proc spice_gr_Update { } { + } + + + # These seem to never be called /* + proc spice_gr_DefineColor {colorid red green blue} { + puts "DefineColor $colorid $red $green $blue" + } + proc spice_gr_DefineLinestyle {linestyleid mask} { + puts "DefineLinestyle $linestyleid $mask" + } + + proc spice_init_gui { fileName {gui 0} {batchMode 0} {rawFileName ""}} { + + # source tclcode + if {[info procs spicewish::plot] == ""} { + source [file join $::spice_library "spice/spicewish.tcl"] + } + + if {!$batchMode} { spice::version } + + if {$fileName != ""} { + + switch [file extension $fileName] { + ".tcl" { + source $fileName + } + ".raw" { + spice::load $fileName + } + default { + spice::source $fileName + + if {$batchMode} { + spice::run + if {$rawFileName != ""} { + spice::set filetype=binary + spice::write $rawFileName + } + exit + } + } + } + } + if {$gui == 1} { spicewish::gui } + wm withdraw . + } + + set ::spice_version $version + set ::spice_library $dir +} + +proc q { } { exit } + + +set version "%VERSION%" +set libdir "%LIB_DIR%" + +package ifneeded spice $version [list Loadspice $version $libdir] + diff --git a/src/spicelib/analysis/Makefile.am b/src/spicelib/analysis/Makefile.am index 8bdcedfdb..f9201b844 100644 --- a/src/spicelib/analysis/Makefile.am +++ b/src/spicelib/analysis/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libckt.a +noinst_LTLIBRARIES = libckt.la -libckt_a_SOURCES = \ +libckt_la_SOURCES = \ acan.c \ acaskq.c \ acsetp.c \ diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 2374bd73d..8007fdab5 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -117,9 +117,9 @@ DIST_SUBDIRS = \ numos -noinst_LIBRARIES = libdev.a +noinst_LTLIBRARIES = libdev.la -libdev_a_SOURCES = \ +libdev_la_SOURCES = \ dev.c \ dev.h \ devsup.c \ diff --git a/src/spicelib/devices/asrc/Makefile.am b/src/spicelib/devices/asrc/Makefile.am index 7b1e6c30b..70a8d597d 100644 --- a/src/spicelib/devices/asrc/Makefile.am +++ b/src/spicelib/devices/asrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libasrc.a +noinst_LTLIBRARIES = libasrc.la -libasrc_a_SOURCES = \ +libasrc_la_SOURCES = \ asrc.c \ asrcacld.c \ asrcask.c \ diff --git a/src/spicelib/devices/bjt/Makefile.am b/src/spicelib/devices/bjt/Makefile.am index 87ba8b0ca..c3cf7c7d8 100644 --- a/src/spicelib/devices/bjt/Makefile.am +++ b/src/spicelib/devices/bjt/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbjt.a +noinst_LTLIBRARIES = libbjt.la -libbjt_a_SOURCES = \ +libbjt_la_SOURCES = \ bjt.c \ bjtacld.c \ bjtask.c \ diff --git a/src/spicelib/devices/bjt2/Makefile.am b/src/spicelib/devices/bjt2/Makefile.am index 579b35db7..f8e5ae22a 100644 --- a/src/spicelib/devices/bjt2/Makefile.am +++ b/src/spicelib/devices/bjt2/Makefile.am @@ -4,9 +4,9 @@ ## work. ## Sensitivity analysis not compiled in. -noinst_LIBRARIES = libbjt2.a +noinst_LTLIBRARIES = libbjt2.la -libbjt2_a_SOURCES = \ +libbjt2_la_SOURCES = \ bjt2.c \ bjt2acld.c \ bjt2ask.c \ diff --git a/src/spicelib/devices/bsim1/Makefile.am b/src/spicelib/devices/bsim1/Makefile.am index 5e3909f51..9159b4256 100644 --- a/src/spicelib/devices/bsim1/Makefile.am +++ b/src/spicelib/devices/bsim1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim1.a +noinst_LTLIBRARIES = libbsim1.la -libbsim1_a_SOURCES = \ +libbsim1_la_SOURCES = \ b1.c \ b1acld.c \ b1ask.c \ diff --git a/src/spicelib/devices/bsim2/Makefile.am b/src/spicelib/devices/bsim2/Makefile.am index cfc71d52c..f7acca3b4 100644 --- a/src/spicelib/devices/bsim2/Makefile.am +++ b/src/spicelib/devices/bsim2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim2.a +noinst_LTLIBRARIES = libbsim2.la -libbsim2_a_SOURCES = \ +libbsim2_la_SOURCES = \ b2.c \ b2acld.c \ b2ask.c \ diff --git a/src/spicelib/devices/bsim3/Makefile.am b/src/spicelib/devices/bsim3/Makefile.am index f2e345088..99b42eb91 100644 --- a/src/spicelib/devices/bsim3/Makefile.am +++ b/src/spicelib/devices/bsim3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3.a +noinst_LTLIBRARIES = libbsim3.la -libbsim3_a_SOURCES = \ +libbsim3_la_SOURCES = \ b3.c \ b3acld.c \ b3ask.c \ diff --git a/src/spicelib/devices/bsim3soi/Makefile.am b/src/spicelib/devices/bsim3soi/Makefile.am index 88e13f14b..33db175ce 100644 --- a/src/spicelib/devices/bsim3soi/Makefile.am +++ b/src/spicelib/devices/bsim3soi/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3soi.a +noinst_LTLIBRARIES = libbsim3soi.la -libbsim3soi_a_SOURCES = \ +libbsim3soi_la_SOURCES = \ b4soi.c \ b4soiacld.c \ b4soiask.c \ diff --git a/src/spicelib/devices/bsim3soi_dd/Makefile.am b/src/spicelib/devices/bsim3soi_dd/Makefile.am index 907039cbb..12d28e20a 100644 --- a/src/spicelib/devices/bsim3soi_dd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_dd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3soidd.a +noinst_LTLIBRARIES = libbsim3soidd.la -libbsim3soidd_a_SOURCES = \ +libbsim3soidd_la_SOURCES = \ b3soidd.c \ b3soiddacld.c \ b3soiddask.c \ diff --git a/src/spicelib/devices/bsim3soi_fd/Makefile.am b/src/spicelib/devices/bsim3soi_fd/Makefile.am index 9367905d2..ee5a04b9a 100644 --- a/src/spicelib/devices/bsim3soi_fd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_fd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3soifd.a +noinst_LTLIBRARIES = libbsim3soifd.la -libbsim3soifd_a_SOURCES = \ +libbsim3soifd_la_SOURCES = \ b3soifd.c \ b3soifdacld.c \ b3soifdask.c \ diff --git a/src/spicelib/devices/bsim3soi_pd/Makefile.am b/src/spicelib/devices/bsim3soi_pd/Makefile.am index 00ca0f63b..45a7a1fe5 100644 --- a/src/spicelib/devices/bsim3soi_pd/Makefile.am +++ b/src/spicelib/devices/bsim3soi_pd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3soipd.a +noinst_LTLIBRARIES = libbsim3soipd.la -libbsim3soipd_a_SOURCES = \ +libbsim3soipd_la_SOURCES = \ b3soipd.c \ b3soipdacld.c \ b3soipdask.c \ diff --git a/src/spicelib/devices/bsim3v0/Makefile.am b/src/spicelib/devices/bsim3v0/Makefile.am index 2b5aa9689..5a1d4905e 100644 --- a/src/spicelib/devices/bsim3v0/Makefile.am +++ b/src/spicelib/devices/bsim3v0/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3v0.a +noinst_LTLIBRARIES = libbsim3v0.la -libbsim3v0_a_SOURCES = \ +libbsim3v0_la_SOURCES = \ b3v0.c \ b3v0acld.c \ b3v0ask.c \ diff --git a/src/spicelib/devices/bsim3v1/Makefile.am b/src/spicelib/devices/bsim3v1/Makefile.am index cef738bb2..dee686052 100644 --- a/src/spicelib/devices/bsim3v1/Makefile.am +++ b/src/spicelib/devices/bsim3v1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3v1.a +noinst_LTLIBRARIES = libbsim3v1.la -libbsim3v1_a_SOURCES = \ +libbsim3v1_la_SOURCES = \ b3v1.c \ b3v1acld.c \ b3v1ask.c \ diff --git a/src/spicelib/devices/bsim3v1a/Makefile.am b/src/spicelib/devices/bsim3v1a/Makefile.am index 5abfaf8a7..e6625fe66 100644 --- a/src/spicelib/devices/bsim3v1a/Makefile.am +++ b/src/spicelib/devices/bsim3v1a/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3v1a.a +noinst_LTLIBRARIES = libbsim3v1a.la -libbsim3v1a_a_SOURCES = \ +libbsim3v1a_la_SOURCES = \ b3v1a.c \ b3v1aacld.c \ b3v1aask.c \ diff --git a/src/spicelib/devices/bsim3v1s/Makefile.am b/src/spicelib/devices/bsim3v1s/Makefile.am index 08fbc954e..1526136b9 100644 --- a/src/spicelib/devices/bsim3v1s/Makefile.am +++ b/src/spicelib/devices/bsim3v1s/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3v1s.a +noinst_LTLIBRARIES = libbsim3v1s.la -libbsim3v1s_a_SOURCES = \ +libbsim3v1s_la_SOURCES = \ b3v1s.c \ b3v1sacld.c \ b3v1sask.c \ diff --git a/src/spicelib/devices/bsim3v32/Makefile.am b/src/spicelib/devices/bsim3v32/Makefile.am index f87859fc5..6f52c70f9 100644 --- a/src/spicelib/devices/bsim3v32/Makefile.am +++ b/src/spicelib/devices/bsim3v32/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim3v32.a +noinst_LTLIBRARIES = libbsim3v32.la -libbsim3v32_a_SOURCES = \ +libbsim3v32_la_SOURCES = \ b3v32.c \ b3v32acld.c \ b3v32ask.c \ diff --git a/src/spicelib/devices/bsim4/Makefile.am b/src/spicelib/devices/bsim4/Makefile.am index 65b19542f..20db31f7b 100644 --- a/src/spicelib/devices/bsim4/Makefile.am +++ b/src/spicelib/devices/bsim4/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim4.a +noinst_LTLIBRARIES = libbsim4.la -libbsim4_a_SOURCES = \ +libbsim4_la_SOURCES = \ b4.c \ b4acld.c \ b4ask.c \ diff --git a/src/spicelib/devices/bsim4v2/Makefile.am b/src/spicelib/devices/bsim4v2/Makefile.am index acde0a348..d5645d256 100644 --- a/src/spicelib/devices/bsim4v2/Makefile.am +++ b/src/spicelib/devices/bsim4v2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim4v2.a +noinst_LTLIBRARIES = libbsim4v2.la -libbsim4v2_a_SOURCES = \ +libbsim4v2_la_SOURCES = \ b4v2.c \ b4v2acld.c \ b4v2ask.c \ diff --git a/src/spicelib/devices/bsim4v3/Makefile.am b/src/spicelib/devices/bsim4v3/Makefile.am index 0012c3ace..bd4bf78b6 100644 --- a/src/spicelib/devices/bsim4v3/Makefile.am +++ b/src/spicelib/devices/bsim4v3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim4v3.a +noinst_LTLIBRARIES = libbsim4v3.la -libbsim4v3_a_SOURCES = \ +libbsim4v3_la_SOURCES = \ b4v3.c \ b4v3acld.c \ b4v3ask.c \ diff --git a/src/spicelib/devices/bsim4v4/Makefile.am b/src/spicelib/devices/bsim4v4/Makefile.am index dd26e003a..1a3829062 100644 --- a/src/spicelib/devices/bsim4v4/Makefile.am +++ b/src/spicelib/devices/bsim4v4/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim4v4.a +noinst_LTLIBRARIES = libbsim4v4.la -libbsim4v4_a_SOURCES = \ +libbsim4v4_la_SOURCES = \ b4v4.c \ b4v4acld.c \ b4v4ask.c \ diff --git a/src/spicelib/devices/bsim4v5/Makefile.am b/src/spicelib/devices/bsim4v5/Makefile.am index 6ce8e40ba..d1358f64c 100644 --- a/src/spicelib/devices/bsim4v5/Makefile.am +++ b/src/spicelib/devices/bsim4v5/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libbsim4v5.a +noinst_LTLIBRARIES = libbsim4v5.la -libbsim4v5_a_SOURCES = \ +libbsim4v5_la_SOURCES = \ b4v5.c \ b4v5acld.c \ b4v5ask.c \ diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am index 56635a401..bd337a8db 100644 --- a/src/spicelib/devices/cap/Makefile.am +++ b/src/spicelib/devices/cap/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcap.a +noinst_LTLIBRARIES = libcap.la -libcap_a_SOURCES = \ +libcap_la_SOURCES = \ cap.c \ capacld.c \ capask.c \ diff --git a/src/spicelib/devices/cccs/Makefile.am b/src/spicelib/devices/cccs/Makefile.am index bd295f7d7..1209fd71b 100644 --- a/src/spicelib/devices/cccs/Makefile.am +++ b/src/spicelib/devices/cccs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcccs.a +noinst_LTLIBRARIES = libcccs.la -libcccs_a_SOURCES = \ +libcccs_la_SOURCES = \ cccs.c \ cccsask.c \ cccsdefs.h \ diff --git a/src/spicelib/devices/ccvs/Makefile.am b/src/spicelib/devices/ccvs/Makefile.am index ff12a0f96..217db9efc 100644 --- a/src/spicelib/devices/ccvs/Makefile.am +++ b/src/spicelib/devices/ccvs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libccvs.a +noinst_LTLIBRARIES = libccvs.la -libccvs_a_SOURCES = \ +libccvs_la_SOURCES = \ ccvs.c \ ccvsask.c \ ccvsdefs.h \ diff --git a/src/spicelib/devices/cpl/Makefile.am b/src/spicelib/devices/cpl/Makefile.am index 7619cc511..c67e10922 100755 --- a/src/spicelib/devices/cpl/Makefile.am +++ b/src/spicelib/devices/cpl/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcpl.a +noinst_LTLIBRARIES = libcpl.la -libcpl_a_SOURCES = \ +libcpl_la_SOURCES = \ cpl.c \ cplask.c \ cpldefs.h \ diff --git a/src/spicelib/devices/csw/Makefile.am b/src/spicelib/devices/csw/Makefile.am index 7d0bc533b..5fd6d03cb 100644 --- a/src/spicelib/devices/csw/Makefile.am +++ b/src/spicelib/devices/csw/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcsw.a +noinst_LTLIBRARIES = libcsw.la -libcsw_a_SOURCES = \ +libcsw_la_SOURCES = \ csw.c \ cswacld.c \ cswask.c \ diff --git a/src/spicelib/devices/dio/Makefile.am b/src/spicelib/devices/dio/Makefile.am index 66e59a092..4e5387f47 100644 --- a/src/spicelib/devices/dio/Makefile.am +++ b/src/spicelib/devices/dio/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libdio.a +noinst_LTLIBRARIES = libdio.la -libdio_a_SOURCES = \ +libdio_la_SOURCES = \ dio.c \ dioacld.c \ dioask.c \ diff --git a/src/spicelib/devices/hfet1/Makefile.am b/src/spicelib/devices/hfet1/Makefile.am index c4abc66f9..47e7f8fa1 100644 --- a/src/spicelib/devices/hfet1/Makefile.am +++ b/src/spicelib/devices/hfet1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libhfet.a +noinst_LTLIBRARIES = libhfet.la -libhfet_a_SOURCES = \ +libhfet_la_SOURCES = \ hfet.c \ hfetacl.c \ hfetask.c \ diff --git a/src/spicelib/devices/hfet2/Makefile.am b/src/spicelib/devices/hfet2/Makefile.am index 6eebf8d5e..6e1a0687c 100644 --- a/src/spicelib/devices/hfet2/Makefile.am +++ b/src/spicelib/devices/hfet2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libhfet2.a +noinst_LTLIBRARIES = libhfet2.la -libhfet2_a_SOURCES = \ +libhfet2_la_SOURCES = \ hfet2.c \ hfet2acl.c \ hfet2ask.c \ diff --git a/src/spicelib/devices/hisim/Makefile.am b/src/spicelib/devices/hisim/Makefile.am index 4b4a43b32..bc6ef9192 100644 --- a/src/spicelib/devices/hisim/Makefile.am +++ b/src/spicelib/devices/hisim/Makefile.am @@ -2,9 +2,9 @@ EXTRA_DIST = hsm1eval1_0.c hsm1eval1_1.c -noinst_LIBRARIES = libhisim.a +noinst_LTLIBRARIES = libhisim.la -libhisim_a_SOURCES = hisim.h \ +libhisim_la_SOURCES = hisim.h \ hsm1.c \ hsm1acld.c \ hsm1ask.c \ diff --git a/src/spicelib/devices/ind/Makefile.am b/src/spicelib/devices/ind/Makefile.am index ba722a70b..200418db9 100644 --- a/src/spicelib/devices/ind/Makefile.am +++ b/src/spicelib/devices/ind/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libind.a +noinst_LTLIBRARIES = libind.la -libind_a_SOURCES = \ +libind_la_SOURCES = \ ind.c \ indacld.c \ indask.c \ diff --git a/src/spicelib/devices/isrc/Makefile.am b/src/spicelib/devices/isrc/Makefile.am index d4a6f12c1..c583953fe 100644 --- a/src/spicelib/devices/isrc/Makefile.am +++ b/src/spicelib/devices/isrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libisrc.a +noinst_LTLIBRARIES = libisrc.la -libisrc_a_SOURCES = \ +libisrc_la_SOURCES = \ isrc.c \ isrcacct.c \ isrcacld.c \ diff --git a/src/spicelib/devices/jfet/Makefile.am b/src/spicelib/devices/jfet/Makefile.am index 7350e3622..5b4e7a91e 100644 --- a/src/spicelib/devices/jfet/Makefile.am +++ b/src/spicelib/devices/jfet/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libjfet.a +noinst_LTLIBRARIES = libjfet.la -libjfet_a_SOURCES = \ +libjfet_la_SOURCES = \ jfet.c \ jfetacld.c \ jfetask.c \ diff --git a/src/spicelib/devices/jfet2/Makefile.am b/src/spicelib/devices/jfet2/Makefile.am index 4a6d4103c..5a16c7160 100644 --- a/src/spicelib/devices/jfet2/Makefile.am +++ b/src/spicelib/devices/jfet2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libjfet2.a +noinst_LTLIBRARIES = libjfet2.la -libjfet2_a_SOURCES = \ +libjfet2_la_SOURCES = \ jfet2.c \ jfet2acld.c \ jfet2ask.c \ diff --git a/src/spicelib/devices/ltra/Makefile.am b/src/spicelib/devices/ltra/Makefile.am index fb90e64a9..1c9e7f663 100644 --- a/src/spicelib/devices/ltra/Makefile.am +++ b/src/spicelib/devices/ltra/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libltra.a +noinst_LTLIBRARIES = libltra.la -libltra_a_SOURCES = \ +libltra_la_SOURCES = \ ltra.c \ ltraacct.c \ ltraacld.c \ diff --git a/src/spicelib/devices/mes/Makefile.am b/src/spicelib/devices/mes/Makefile.am index c1b487f39..4ec8d2bec 100644 --- a/src/spicelib/devices/mes/Makefile.am +++ b/src/spicelib/devices/mes/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmes.a +noinst_LTLIBRARIES = libmes.la -libmes_a_SOURCES = \ +libmes_la_SOURCES = \ mes.c \ mesacl.c \ mesask.c \ diff --git a/src/spicelib/devices/mesa/Makefile.am b/src/spicelib/devices/mesa/Makefile.am index da44c9ced..f6cc34f10 100644 --- a/src/spicelib/devices/mesa/Makefile.am +++ b/src/spicelib/devices/mesa/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmesa.a +noinst_LTLIBRARIES = libmesa.la -libmesa_a_SOURCES = \ +libmesa_la_SOURCES = \ mesa.c \ mesaacl.c \ mesaask.c \ diff --git a/src/spicelib/devices/mos1/Makefile.am b/src/spicelib/devices/mos1/Makefile.am index 9e702a8f9..ee2cb8490 100644 --- a/src/spicelib/devices/mos1/Makefile.am +++ b/src/spicelib/devices/mos1/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmos1.a +noinst_LTLIBRARIES = libmos1.la -libmos1_a_SOURCES = \ +libmos1_la_SOURCES = \ mos1.c \ mos1acld.c \ mos1ask.c \ diff --git a/src/spicelib/devices/mos2/Makefile.am b/src/spicelib/devices/mos2/Makefile.am index d432fd72d..488c4354f 100644 --- a/src/spicelib/devices/mos2/Makefile.am +++ b/src/spicelib/devices/mos2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmos2.a +noinst_LTLIBRARIES = libmos2.la -libmos2_a_SOURCES = \ +libmos2_la_SOURCES = \ mos2.c \ mos2acld.c \ mos2ask.c \ diff --git a/src/spicelib/devices/mos3/Makefile.am b/src/spicelib/devices/mos3/Makefile.am index 9e1ff43ae..e98ce9f9d 100644 --- a/src/spicelib/devices/mos3/Makefile.am +++ b/src/spicelib/devices/mos3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmos3.a +noinst_LTLIBRARIES = libmos3.la -libmos3_a_SOURCES = \ +libmos3_la_SOURCES = \ mos3.c \ mos3acld.c \ mos3ask.c \ diff --git a/src/spicelib/devices/mos6/Makefile.am b/src/spicelib/devices/mos6/Makefile.am index 13a4eb9ad..62764be9b 100644 --- a/src/spicelib/devices/mos6/Makefile.am +++ b/src/spicelib/devices/mos6/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmos6.a +noinst_LTLIBRARIES = libmos6.la -libmos6_a_SOURCES = \ +libmos6_la_SOURCES = \ mos6.c \ mos6ask.c \ mos6conv.c \ diff --git a/src/spicelib/devices/mos9/Makefile.am b/src/spicelib/devices/mos9/Makefile.am index bc03c5b91..89e9668bf 100644 --- a/src/spicelib/devices/mos9/Makefile.am +++ b/src/spicelib/devices/mos9/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libmos9.a +noinst_LTLIBRARIES = libmos9.la -libmos9_a_SOURCES = \ +libmos9_la_SOURCES = \ mos9.c \ mos9acld.c \ mos9ask.c \ diff --git a/src/spicelib/devices/nbjt/Makefile.am b/src/spicelib/devices/nbjt/Makefile.am index adb6abb96..9f01a180e 100644 --- a/src/spicelib/devices/nbjt/Makefile.am +++ b/src/spicelib/devices/nbjt/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libnbjt.a +noinst_LTLIBRARIES = libnbjt.la -libnbjt_a_SOURCES = \ +libnbjt_la_SOURCES = \ nbjt.c \ nbjtacld.c \ nbjtask.c \ diff --git a/src/spicelib/devices/nbjt2/Makefile.am b/src/spicelib/devices/nbjt2/Makefile.am index 5e4abe902..3147a3d61 100644 --- a/src/spicelib/devices/nbjt2/Makefile.am +++ b/src/spicelib/devices/nbjt2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libnbjt2.a +noinst_LTLIBRARIES = libnbjt2.la -libnbjt2_a_SOURCES = \ +libnbjt2_la_SOURCES = \ nbt2.c \ nbt2acld.c \ nbt2ask.c \ diff --git a/src/spicelib/devices/ndev/Makefile.am b/src/spicelib/devices/ndev/Makefile.am index bbd5c8e6e..8162def45 100644 --- a/src/spicelib/devices/ndev/Makefile.am +++ b/src/spicelib/devices/ndev/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libndev.a +noinst_LTLIBRARIES = libndev.la -libndev_a_SOURCES = \ +libndev_la_SOURCES = \ ndev.c \ ndevacld.c \ ndevaccept.c \ diff --git a/src/spicelib/devices/numd/Makefile.am b/src/spicelib/devices/numd/Makefile.am index 328cbb070..061b93f43 100644 --- a/src/spicelib/devices/numd/Makefile.am +++ b/src/spicelib/devices/numd/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libnumd.a +noinst_LTLIBRARIES = libnumd.la -libnumd_a_SOURCES = \ +libnumd_la_SOURCES = \ numd.c \ numdacld.c \ numdask.c \ diff --git a/src/spicelib/devices/numd2/Makefile.am b/src/spicelib/devices/numd2/Makefile.am index 1f26029ad..f032cbee2 100644 --- a/src/spicelib/devices/numd2/Makefile.am +++ b/src/spicelib/devices/numd2/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libnumd2.a +noinst_LTLIBRARIES = libnumd2.la -libnumd2_a_SOURCES = \ +libnumd2_la_SOURCES = \ nud2.c \ nud2acld.c \ nud2ask.c \ diff --git a/src/spicelib/devices/numos/Makefile.am b/src/spicelib/devices/numos/Makefile.am index 68d67b28a..f4434754f 100644 --- a/src/spicelib/devices/numos/Makefile.am +++ b/src/spicelib/devices/numos/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libnumos.a +noinst_LTLIBRARIES = libnumos.la -libnumos_a_SOURCES = \ +libnumos_la_SOURCES = \ numm.c \ nummacld.c \ nummask.c \ diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index c7a50be85..5cc2acef2 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libres.a +noinst_LTLIBRARIES = libres.la -libres_a_SOURCES = \ +libres_la_SOURCES = \ res.c \ resask.c \ resdefs.h \ diff --git a/src/spicelib/devices/soi3/Makefile.am b/src/spicelib/devices/soi3/Makefile.am index 283ba3108..d06842e1f 100644 --- a/src/spicelib/devices/soi3/Makefile.am +++ b/src/spicelib/devices/soi3/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libsoi3.a +noinst_LTLIBRARIES = libsoi3.la -libsoi3_a_SOURCES = \ +libsoi3_la_SOURCES = \ soi3.c \ soi3acld.c \ soi3ask.c \ diff --git a/src/spicelib/devices/sw/Makefile.am b/src/spicelib/devices/sw/Makefile.am index 2d41724a3..ad2ee5429 100644 --- a/src/spicelib/devices/sw/Makefile.am +++ b/src/spicelib/devices/sw/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libsw.a +noinst_LTLIBRARIES = libsw.la -libsw_a_SOURCES = \ +libsw_la_SOURCES = \ sw.c \ swacload.c \ swask.c \ diff --git a/src/spicelib/devices/tra/Makefile.am b/src/spicelib/devices/tra/Makefile.am index a6eac4324..5fdcd4ae2 100644 --- a/src/spicelib/devices/tra/Makefile.am +++ b/src/spicelib/devices/tra/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libtra.a +noinst_LTLIBRARIES = libtra.la -libtra_a_SOURCES = \ +libtra_la_SOURCES = \ tra.c \ traacct.c \ traacld.c \ diff --git a/src/spicelib/devices/txl/Makefile.am b/src/spicelib/devices/txl/Makefile.am index 0b26e2842..16d39252e 100755 --- a/src/spicelib/devices/txl/Makefile.am +++ b/src/spicelib/devices/txl/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libtxl.a +noinst_LTLIBRARIES = libtxl.la -libtxl_a_SOURCES = \ +libtxl_la_SOURCES = \ txl.c \ txlacct.c \ txlask.c \ diff --git a/src/spicelib/devices/urc/Makefile.am b/src/spicelib/devices/urc/Makefile.am index 8e4ffb698..a2daf700b 100644 --- a/src/spicelib/devices/urc/Makefile.am +++ b/src/spicelib/devices/urc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = liburc.a +noinst_LTLIBRARIES = liburc.la -liburc_a_SOURCES = \ +liburc_la_SOURCES = \ urc.c \ urcask.c \ urcdefs.h \ diff --git a/src/spicelib/devices/vbic/Makefile.am b/src/spicelib/devices/vbic/Makefile.am index 61bbeb433..7cc21e239 100644 --- a/src/spicelib/devices/vbic/Makefile.am +++ b/src/spicelib/devices/vbic/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libvbic.a +noinst_LTLIBRARIES = libvbic.la -libvbic_a_SOURCES = \ +libvbic_la_SOURCES = \ vbic.c \ vbicacld.c \ vbicask.c \ diff --git a/src/spicelib/devices/vccs/Makefile.am b/src/spicelib/devices/vccs/Makefile.am index dd34d35c0..d7a2b2a6e 100644 --- a/src/spicelib/devices/vccs/Makefile.am +++ b/src/spicelib/devices/vccs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libvccs.a +noinst_LTLIBRARIES = libvccs.la -libvccs_a_SOURCES = \ +libvccs_la_SOURCES = \ vccs.c \ vccsask.c \ vccsdefs.h \ diff --git a/src/spicelib/devices/vcvs/Makefile.am b/src/spicelib/devices/vcvs/Makefile.am index 00855043f..158876adf 100644 --- a/src/spicelib/devices/vcvs/Makefile.am +++ b/src/spicelib/devices/vcvs/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libvcvs.a +noinst_LTLIBRARIES = libvcvs.la -libvcvs_a_SOURCES = \ +libvcvs_la_SOURCES = \ vcvs.c \ vcvsask.c \ vcvsdefs.h \ diff --git a/src/spicelib/devices/vsrc/Makefile.am b/src/spicelib/devices/vsrc/Makefile.am index a91a59737..b5e35b9df 100644 --- a/src/spicelib/devices/vsrc/Makefile.am +++ b/src/spicelib/devices/vsrc/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libvsrc.a +noinst_LTLIBRARIES = libvsrc.la -libvsrc_a_SOURCES = \ +libvsrc_la_SOURCES = \ vsrc.c \ vsrcacct.c \ vsrcacld.c \ diff --git a/src/spicelib/parser/Makefile.am b/src/spicelib/parser/Makefile.am index e890ff940..6e195aa30 100644 --- a/src/spicelib/parser/Makefile.am +++ b/src/spicelib/parser/Makefile.am @@ -1,8 +1,8 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libinp.a +noinst_LTLIBRARIES = libinp.la -libinp_a_SOURCES = \ +libinp_la_SOURCES = \ ifeval.c \ ifnewuid.c \ inp2b.c \ diff --git a/src/tclspice.c b/src/tclspice.c new file mode 100755 index 000000000..fcaf74d40 --- /dev/null +++ b/src/tclspice.c @@ -0,0 +1,2377 @@ +/* Copied and written by Stefan Jones (stefan.jones@multigig.com) at Multigig Ltd + * Under GPL licence + * Code based on and copied from ScriptEDA ( http://www-cad.eecs.berkeley.edu/~pinhong/scriptEDA ) + * $Id$ + */ + +/*******************/ +/* Defines */ +/*******************/ + +#define TCLSPICE_name "spice" +#define TCLSPICE_prefix "spice::" +#define TCLSPICE_namespace "spice" + +/**********************************************************************/ +/* Header files for C functions */ +/**********************************************************************/ + +#include +#include + +/*Use Tcl threads if on W32 without pthreads*/ +#ifndef HAVE_LIBPTHREAD + +#ifdef __MINGW32__ + +#define mutex_lock(a) Tcl_MutexLock(a) +#define mutex_unlock(a) Tcl_MutexUnlock(a) +#define thread_self() Tcl_GetCurrentThread() +typedef Tcl_Mutex mutexType; +typedef Tcl_ThreadId threadId_t; +#define TCL_THREADS +#define THREADS + +#endif + +#else + +#include +#define mutex_lock(a) pthread_mutex_lock(a) +#define mutex_unlock(a) pthread_mutex_unlock(a) +#define thread_self() pthread_self() +typedef pthread_mutex_t mutexType; +typedef pthread_t threadId_t; +#define THREADS + +#endif + + +/* Copied from main.c in ngspice*/ +#include +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ +#ifdef __MINGW32__ + #include + #include + #include /* Sleep */ + #ifndef srandom + #define srandom(a) srand(a) /* srandom */ + #endif +#else + #include /* usleep */ +#endif /* __MINGW32__ */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifndef HAVE_GETRUSAGE +#ifdef HAVE_FTIME +#include +#endif +#endif + +/* To interupt a spice run */ +#include +typedef void (*sighandler)(int); + +#include +extern sigjmp_buf jbuf; + +/*Included for the module to access data*/ +#include +#include + +#ifdef __CYGWIN__ +#undef WIN32 +#endif +#include +#include + +/* defines for Tcl support + * Tcl 8.3 and Tcl 8.4 support, + * suggested by http://mini.net/tcl/3669, 07.03.03 */ +#ifndef CONST84 +#define CONST84 +#endif /* CONST84 */ +/* Arguments of Tcl_CmpProc for Tcl/Tk 8.4.x */ +#define TCL_CMDPROCARGS(clientData,interp,argc,argv) \ + (ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) + +/*For get_output*/ +#include +#include + +//#include /* for va_copy() */ + +extern IFfrontEnd nutmeginfo; + +extern struct comm spcp_coms[ ]; + +extern int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator); + +/*For blt spice to use*/ +typedef struct { + char *name; +#ifdef THREADS + mutexType mutex;/*lock for this vector*/ +#endif + double *data;/* vector data*/ + int size;/*data it can store*/ + int length;/*actual amount of data*/ +} vector; + +/*The current run (to get variable names, etc)*/ +static runDesc *cur_run; + +static vector *vectors; + +static int ownVectors; + +/* save this each time called */ +static Tcl_Interp *spice_interp; +#define save_interp() \ +do {\ + spice_interp = interp;\ +} while(0) + +/****************************************************************************/ +/* BLT and data routines */ +/****************************************************************************/ + +/*helper function*/ +inline static struct plot * get_plot(int plot){ + struct plot *pl; + pl = plot_list; + for(;0 < plot;plot--){ + pl = pl->pl_next; + if(!pl) + return (struct plot *)NULL; + } + return pl; +} + +/*this holds the number of time points done (altered by spice)*/ +int steps_completed; +/* number of bltvectors*/ +static int blt_vnum; + + +/*Native Tcl functions */ + +static int spice_header TCL_CMDPROCARGS(clientData,interp,argc,argv){ + char buf[256]; + char *date, *name, *title; + if (argc != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::spice_header",TCL_STATIC); + return TCL_ERROR; + } + if(cur_run){ + Tcl_ResetResult(interp); + date = datestring(); + title = cur_run->name; + name = cur_run->type; + sprintf(buf,"{title \"%s\"} {name \"%s\"} {date \"%s\"} {variables %u}",title,name,date,cur_run->numData); + Tcl_AppendResult(interp, (char *)buf,TCL_STATIC); + return TCL_OK; + }else return TCL_ERROR; +} + +static int spice_data TCL_CMDPROCARGS(clientData,interp,argc,argv) { + char buf[256]; + int i, type; + char *name; + if (argc > 2) { + Tcl_SetResult(interp, "Wrong # args. spice::spice_data ?plot?", + TCL_STATIC); + return TCL_ERROR; + } + if(argc == 1) { + if(blt_vnum){ + Tcl_ResetResult(interp); + for(i = 0; i < blt_vnum;i++){ + name = vectors[i].name; + if (substring("#branch", name)) + type = SV_CURRENT; + else if (cieq(name, "time")) + type = SV_TIME; + else if (cieq(name, "frequency")) + type = SV_FREQUENCY; + else + type = SV_VOLTAGE; + sprintf(buf,"{%s %s} ",name, + ft_typenames(type)); + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + return TCL_OK; + }else return TCL_ERROR; + } else { + struct plot *pl; + struct dvec *v; + if(!(pl = get_plot(atoi(argv[1])))){ + Tcl_SetResult(interp, "Bad plot number", TCL_STATIC); + return TCL_ERROR; + } + for(v = pl->pl_dvecs;v;v = v->v_next) { + name = v->v_name; + if (substring("#branch", name)) + type = SV_CURRENT; + else if (cieq(name, "time")) + type = SV_TIME; + else if (cieq(name, "frequency")) + type = SV_FREQUENCY; + else + type = SV_VOLTAGE; + sprintf(buf,"{%s %s} ",name, + ft_typenames(type)); + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + return TCL_OK; + } +} + +static int resetTriggers(); + +/*Creates and registers the blt vectors, used by spice*/ +void blt_init(void *run) { + int i; + cur_run = NULL; + /* reset varaibles and free*/ + if(vectors){ + resetTriggers(); + for(i = blt_vnum-1, blt_vnum = 0/*stops vector access*/;i >= 0;i--){ + if(ownVectors) + FREE(vectors[i].data); + FREE(vectors[i].name); +#ifdef HAVE_LIBPTHREAD + pthread_mutex_destroy(&vectors[i].mutex); +#endif + } + FREE(vectors); + } + + + /* initilise */ + cur_run = (runDesc *)run; + vectors = (vector *)MALLOC(cur_run->numData*sizeof(vector)); + for(i = 0;i < cur_run->numData;i++){ + vectors[i].name = copy((cur_run->data[i]).name); +#ifdef HAVE_LIBPTHREAD + pthread_mutex_init(&vectors[i].mutex,NULL); +#endif + vectors[i].data = NULL; + vectors[i].size = 0; + vectors[i].length = 0; + } + ownVectors = cur_run->writeOut; + blt_vnum = i;/*allows access to vectors*/ + return; +} + +/*Adds data to the stored vector*/ +void blt_add(int index,double value){ + vector *v; + v = &vectors[index]; +#ifdef THREADS + mutex_lock(&vectors[index].mutex); +#endif + if(!(v->length < v->size)){ + v->size += 100; + v->data = (double *)REALLOC(v->data,sizeof(double)*v->size); + } + v->data[v->length] = value; + v->length ++; +#ifdef THREADS + mutex_unlock(&vectors[index].mutex); +#endif + return; +} + +/* Locks the vector data to stop conflicts*/ +void blt_lockvec(int index){ +#ifdef THREADS + mutex_lock(&vectors[index].mutex); +#endif + return; +} + + +/*links a dvec to a blt vector, used to stop duplication of data when writing to a plot, + but makes BLT vectors more unsafe */ +void blt_relink(int index,void *tmp){ + struct dvec *v = (struct dvec *)tmp; + vectors[index].data = v->v_realdata; + vectors[index].length = v->v_length; + vectors[index].size = v->v_length;/*silly spice doesn't use v_rlength*/ +#ifdef THREADS + mutex_unlock(&vectors[index].mutex); +#endif + return; +} + + + + +/* Tcl functions to access spice data */ + +/* This copys the last Spice state vector to the given blt_vector + * arg1: blt_vector + */ +static int lastVector TCL_CMDPROCARGS(clientData,interp,argc,argv) { + Blt_Vector *vec; + char *blt; + int i; + double *V; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::lastVector vecName",TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetResult(interp, "test2",TCL_STATIC); + return TCL_ERROR; + blt = (char *)argv[1]; + if(Blt_GetVector(interp,blt,&vec)){ + Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)blt, TCL_STATIC); + return TCL_ERROR; + } + if(!(V = (double *)MALLOC(sizeof(double)*blt_vnum))) { + Tcl_SetResult(interp, "Out of Memory",TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetResult(interp, "test1",TCL_STATIC); + return TCL_ERROR; + + for(i=0;i < blt_vnum;i++){ +#ifdef THREADS + mutex_lock(&vectors[i].mutex); +#endif + V[i] = vectors[i].data[vectors[i].length-1]; +#ifdef THREADS + mutex_unlock(&vectors[i].mutex); +#endif + } + Blt_ResetVector(vec,V,blt_vnum, + blt_vnum,TCL_VOLATILE); + txfree(V); + return TCL_OK; +} + +/*agr1: spice variable name + *arg2: index + */ +static int get_value TCL_CMDPROCARGS(clientData,interp,argc,argv) { + char *var; + int i, vindex, j; + double val=0; + if(argc != 3) { + Tcl_SetResult(interp, + "Wrong # args. spice::get_value spice_variable index", + TCL_STATIC); + return TCL_ERROR; + } + var = (char *)argv[1]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else vindex = i; + + j = atoi(argv[2]); + +#ifdef THREADS + mutex_lock(&vectors[vindex].mutex); +#endif + + if(j < 0 || j >= vectors[vindex].length) { + i = 1; + } else { + i = 0; + val = vectors[vindex].data[j]; + } + +#ifdef THREADS + mutex_unlock(&vectors[vindex].mutex); +#endif + + if(i) { + Tcl_SetResult(interp, "Index out of range",TCL_STATIC); + return TCL_ERROR; + } else { + Tcl_SetObjResult(interp,Tcl_NewDoubleObj(val)); + return TCL_OK; + } +} +/* + * arg1: spice vector name + * arg2: real data blt vector + * arg3: Optional: imaginary data blt vector*/ +static int vectoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) { + Blt_Vector *real_BltVector, *imag_BltVector; + char *realBlt, *imagBlt, *var; + struct dvec *var_dvec; + double *realData, *compData; + + if (argc < 3 || argc > 4){ + Tcl_SetResult(interp, "Wrong # args. spice::vectoblt spice_variable real_bltVector [imag_bltVector]",TCL_STATIC); + return TCL_ERROR; + } + + real_BltVector = NULL; + imag_BltVector = NULL; + var = (char *)argv[1]; + var_dvec = vec_get(var); + if ( var_dvec == NULL ){ + Tcl_SetResult(interp, "Bad spice vector",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } + realBlt = (char *)argv[2]; + if(Blt_GetVector(interp,realBlt,&real_BltVector)){ + Tcl_SetResult(interp, "Bad real blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)realBlt, TCL_STATIC); + return TCL_ERROR; + } + if (argc == 4) { + imagBlt = (char *)argv[3]; + if(Blt_GetVector(interp,imagBlt,&imag_BltVector)){ + Tcl_SetResult(interp, "Bad imag blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)imagBlt, TCL_STATIC); + return TCL_ERROR; + } + } +/*If data is complex, it is harder (more complex :) to export...*/ + int compIndex; //index to loop inside the vectors' data + if (var_dvec->v_realdata==NULL){ + if (var_dvec->v_compdata==NULL){ + Tcl_SetResult(interp, "The vector contains no data",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + } + else{ + realData = (double *)tmalloc((unsigned) sizeof(double)*(var_dvec->v_length)); + for (compIndex=0; compIndexv_length; compIndex++){ + realData[compIndex] = ((var_dvec->v_compdata+compIndex)->cx_real); + } + Blt_ResetVector(real_BltVector, realData, var_dvec->v_length, var_dvec->v_length, TCL_VOLATILE); + if (imag_BltVector != NULL) { + compData = (double *)tmalloc((unsigned) sizeof(double)*(var_dvec->v_length)); + for (compIndex=0; compIndexv_length; compIndex++){ + compData[compIndex] = ((var_dvec->v_compdata+compIndex)->cx_imag); + } + Blt_ResetVector(imag_BltVector, compData, var_dvec->v_length, var_dvec->v_length, TCL_VOLATILE); + } + }; + } else + { + Blt_ResetVector(real_BltVector, var_dvec->v_realdata, var_dvec->v_length, var_dvec->v_length, TCL_VOLATILE); + if (imag_BltVector != NULL) { + compData = (double *)tmalloc((unsigned) sizeof(double)*(var_dvec->v_length)); + for (compIndex=0; compIndexv_length; compIndex++){ + compData[compIndex] = 0; + } + Blt_ResetVector(imag_BltVector, compData, var_dvec->v_length, var_dvec->v_length, TCL_VOLATILE); + } + + } + Tcl_SetResult(interp, "finished!",TCL_STATIC); + return TCL_OK; + +} + +/*agr1: spice variable name + *arg2: blt_vector + *arg3: start copy index, optional + *arg4: end copy index. optional + */ +static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) { + Blt_Vector *vec; + int j, i; + char *blt, *var; + int start=0,end=-1,len; + + if (argc < 3 || argc > 5) { + Tcl_SetResult(interp, "Wrong # args. spice::spicetoblt spice_variable vecName ?start? ?end?",TCL_STATIC); + return TCL_ERROR; + } + + var = (char *)argv[1]; + blt = (char *)argv[2]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else j = i; + + if(Blt_GetVector(interp,blt,&vec)){ + Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)blt, TCL_STATIC); + return TCL_ERROR; + } + + + if(argc >= 4) + start = atoi(argv[3]); + if(argc == 5) + end = atoi(argv[4]); + if(vectors[j].length) { +#ifdef THREADS + mutex_lock(&vectors[j].mutex); +#endif + + len = vectors[j].length; + + if(start){ + start = start % len; + if(start < 0) + start += len; + } + + end = end % len; + if(end < 0) + end += len; + + len = abs(end - start + 1); + + Blt_ResetVector(vec,(vectors[j].data + start),len, + len,TCL_VOLATILE); + +#ifdef THREADS + mutex_unlock(&vectors[j].mutex); +#endif + } + return TCL_OK; +} + + +/******************************************************************/ +/* Main spice command executions and thread control */ +/*****************************************************************/ + +#ifdef THREADS +static threadId_t tid, bgtid=(threadId_t)0; + +static bool fl_running = FALSE; +static bool fl_exited = TRUE; + + +static void *_thread_run(void *string){ + fl_exited = FALSE; + bgtid = thread_self(); + cp_evloop((char *)string); + FREE(string); + bgtid = (threadId_t)0; + fl_exited = TRUE; + return 0; +} + +/*Stops a running thread, hopefully */ +static int _thread_stop(){ + int timeout = 0; + if(fl_running) { + while(!fl_exited && timeout < 100){ + ft_intrpt = TRUE; + timeout++; +#ifdef __MINGW32__ + Sleep(10); /* va: windows native */ +#else + usleep(10000); +#endif + } + if(!fl_exited) { + fprintf(stderr,"Couldn't stop tclspice\n"); + return TCL_ERROR; + } +#ifdef HAVE_LIBPTHREAD + pthread_join(tid, NULL); +#endif + fl_running = FALSE; + ft_intrpt = FALSE; + return TCL_OK; + }else { + fprintf(stderr,"Spice not running\n"); + } + return TCL_OK; +} + +void sighandler_tclspice(int num) { + if(fl_running) _thread_stop(); + return; +} + +#endif /*THREADS*/ + +static int _run(int argc,char **argv){ + char buf[1024] = ""; + int i; + sighandler oldHandler; +#ifdef THREADS + char *string; + bool fl_bg = FALSE; + /* run task in background if preceeded by "bg"*/ + if(!strcmp(argv[0],"bg")) { + argc--; + argv = &argv[1]; + fl_bg = TRUE; + } +#endif + + /* Catch Ctrl-C to break simulations */ + oldHandler = signal(SIGINT,ft_sigintr); + if(sigsetjmp(jbuf, 1)!=0) { + signal(SIGINT,oldHandler); + return TCL_OK; + } + + /*build a char * to pass to cp_evloop */ + for(i=0;i 1) + cp_evloop(buf); + else{ + _thread_stop(); + cp_evloop(buf); + } + else { + /* cannot do anything if spice is running in the bg*/ + if(fl_running){ + if(fl_exited){ + _thread_stop(); + cp_evloop(buf); + }else + fprintf(stderr,"type \"spice stop\" first\n"); + }else{ + /*do the command*/ + cp_evloop(buf); + } + } +#else + cp_evloop(buf); +#endif /*THREADS*/ + signal(SIGINT,oldHandler); + return TCL_OK; +} + +static int _tcl_dispatch TCL_CMDPROCARGS(clientData,interp,argc,argv) { + int i; + save_interp(); + /* Looks backwards through the first command and strips the :: part */ + for(i = strlen(argv[0])-1;i > 0;i--) + if(argv[0][i] == *":") + argv[0] += i + 1; + return _run(argc,(char **)argv); +} + + +/* Runs the spice command given in spice */ +static int _spice_dispatch TCL_CMDPROCARGS(clientData,interp,argc,argv) { + save_interp(); + if(argc == 1) return TCL_OK; + return _run(argc-1,(char **)&argv[1]); +} + +#ifdef THREADS +/*Checks if spice is runnuing in the background */ +static int running TCL_CMDPROCARGS(clientData,interp,argc,argv) { + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) (fl_running && !fl_exited))); + return TCL_OK; +} +#endif + +/**************************************/ +/* plot manipulation functions */ +/* only usefull if plots are saved */ +/**************************************/ + +/*Outputs the names of all variables in the plot */ +static int plot_variables TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + int plot; + struct dvec *v; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_variables plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp,"Bad plot given",TCL_STATIC); + return TCL_ERROR; + } + + for(v = pl->pl_dvecs;v;v = v->v_next){ + Tcl_AppendElement(interp,v->v_name); + } + return TCL_OK; +} + +static int plot_variablesInfo TCL_CMDPROCARGS(clientData,interp,argc,argv){ + + struct plot *pl; + int plot; + struct dvec *v; + char buf[256]; + char *name; + int length; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_variablesInfo plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp,"Bad plot given",TCL_STATIC); + return TCL_ERROR; + } + + Tcl_ResetResult(interp); + for(v = pl->pl_dvecs;v;v = v->v_next){ + name = v->v_name; + length = v->v_length; + + sprintf(buf,"{%s %s %i} ",name, ft_typenames(v->v_type), length); + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + return TCL_OK; +} + + +/*returns the value of a variable */ +static int plot_get_value TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + struct dvec *v; + char *name; + int plot,index; + + if (argc != 4) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_get_value name plot index",TCL_STATIC); + return TCL_ERROR; + } + + name = (char *)argv[1]; + plot = atoi(argv[2]); + index = atoi(argv[3]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot",TCL_STATIC); + return TCL_ERROR; + } + for(v = pl->pl_dvecs;v;v = v->v_next) + if(!strcmp(v->v_name,name)){ + if (index < v->v_length) { + Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) v->v_realdata[index])); + return TCL_OK; + } else { + Tcl_SetResult(interp, "Bad index",TCL_STATIC); + return TCL_ERROR; + } + } + Tcl_SetResult(interp, "variable not found",TCL_STATIC); + return TCL_ERROR; +} + + +/*The length of the first vector in a plot*/ +static int plot_datapoints TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + struct dvec *v; + int plot; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_datapoints plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot", TCL_STATIC); + return TCL_ERROR; + } + + v = pl->pl_dvecs; + + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) v->v_length));// could be very dangeous + return TCL_OK; +} + +/*These functions give you infomation about a plot*/ + +static int plot_title TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_title plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_title,-1)); + return TCL_OK; +} + +static int plot_date TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_date plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_date,-1)); + return TCL_OK; +} + +static int plot_name TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_name plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_name,-1)); + return TCL_OK; +} + +static int plot_typename TCL_CMDPROCARGS(clientData,interp,argc,argv) { + struct plot *pl; + int plot; + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_typename plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot", TCL_STATIC); + return TCL_ERROR; + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_typename,-1)); + return TCL_OK; +} + +/*number of variables in a plot*/ + +static int plot_nvars TCL_CMDPROCARGS(clientData,interp,argc,argv){ + struct plot *pl; + struct dvec *v; + int plot; + int i=0; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_nvars plot",TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot",TCL_STATIC); + return TCL_ERROR; + } + for(v = pl->pl_dvecs;v;v = v->v_next) + i++; + Tcl_SetObjResult(interp,Tcl_NewIntObj((long) i)); + return TCL_OK; +} + +static int plot_defaultscale TCL_CMDPROCARGS(clientData,interp,argc,argv){ + struct plot *pl; + int plot; + + if (argc != 2) { + Tcl_SetResult(interp, "Wrong # args. spice::plot_defaultscale plot", + TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot",TCL_STATIC); + return TCL_ERROR; + } + + if(pl->pl_scale) + Tcl_SetObjResult(interp,Tcl_NewStringObj(pl->pl_scale->v_name,-1)); + return TCL_OK; +} + +/*agr1: plot index + *agr2: spice variable name + *arg3: blt_vector + *arg4: start copy index, optional + *arg5: end copy index. optional + */ +static int plot_getvector TCL_CMDPROCARGS(clientData,interp,argc,argv) { + Blt_Vector *vec; + char *blt, *var; + int start=0,end=-1,len; + int plot; + struct dvec *v; + struct plot *pl; + + if (argc < 4 || argc > 6) { + Tcl_SetResult(interp, + "Wrong # args. spice::plot_getvector plot spice_variable vecName ?start? ?end?", + TCL_STATIC); + return TCL_ERROR; + } + + plot = atoi(argv[1]); + + if(!(pl = get_plot(plot))){ + Tcl_SetResult(interp, "Bad plot",TCL_STATIC); + return TCL_ERROR; + } + + var = (char *)argv[2]; + blt = (char *)argv[3]; + + for(v = pl->pl_dvecs;v;v = v->v_next) + if(!strcmp(v->v_name,var)){ + break; + } + if(v == NULL) { + Tcl_SetResult(interp, "variable not found: ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } + + if(Blt_GetVector(interp,blt,&vec)){ + Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)blt, TCL_STATIC); + return TCL_ERROR; + } + + if(argc >= 5) + start = atoi(argv[4]); + if(argc == 6) + end = atoi(argv[5]); + if(v->v_length) { + + len = v->v_length; + + if(start){ + start = start % len; + if(start < 0) + start += len; + } + + end = end % len; + if(end < 0) + end += len; + + len = abs(end - start + 1); + + Blt_ResetVector(vec,(v->v_realdata + start),len, + len,TCL_VOLATILE); + } + return TCL_OK; +} + +static int plot_getplot TCL_CMDPROCARGS(clientData,interp,argc,argv) { + if(plot_cur) { + Tcl_SetObjResult(interp,Tcl_NewStringObj(plot_cur->pl_typename,-1)); + } + return TCL_OK; +} + +/*******************************************/ +/* Misc functions */ +/*******************************************/ + +/*Runs a tcl script and returns the output*/ +static int get_output TCL_CMDPROCARGS(clientData,interp,argc,argv) { + FILE *pipein; + int tmp_1,tmp_2=0; + char buf[1024]; + int outfd,outfd2=0; + save_interp(); + if ((argc < 2) || (argc > 3)) { + Tcl_SetResult(interp, "Wrong # args. spice::get_output script ?var_for_stderr?",TCL_STATIC); + return TCL_ERROR; + } + tmp_1=dup(1); + outfd=open("/tmp/tclspice.tmp_out",O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU); + if(argc==3){ + tmp_2=dup(2); + outfd2=open("/tmp/tclspice.tmp_err",O_WRONLY|O_CREAT|O_TRUNC,S_IRWXU); + } + freopen("/tmp/tclspice.tmp_out","w",stdout); + if(argc==3)freopen("/tmp/tclspice.tmp_err","w",stderr); + dup2(outfd,1); + if(argc==3)dup2(outfd2,2); + + Tcl_Eval(interp,argv[1]); + + fclose(stdout); + close(outfd); + if(argc==3){ + fclose(stderr); + close(outfd2); + } + dup2(tmp_1, 1); + close(tmp_1); + if(argc==3){ + dup2(tmp_2, 2); + close(tmp_2); + } + freopen("/dev/fd/1","w",stdout); + if(argc==3)freopen("/dev/fd/2","w",stderr); + pipein=fopen("/tmp/tclspice.tmp_out","r"); + if(pipein==NULL){ + fprintf(stderr,"pipein==NULL\n"); + } + Tcl_ResetResult(interp); + while(fgets(buf,1024,pipein)!=NULL){ + Tcl_AppendResult(interp, (char *)buf, TCL_STATIC); + } + fclose(pipein); + if(argc==3){ + pipein=fopen("/tmp/tclspice.tmp_err","r"); + Tcl_SetVar(interp,argv[2],"",0); + while(fgets(buf,1024,pipein)!=NULL){ + Tcl_SetVar(interp,argv[2],buf,TCL_APPEND_VALUE); + } + fclose(pipein); + } + return TCL_OK; +} + +/* Returns the current value of a parameter + * has lots of memory leaks + */ +static int get_param TCL_CMDPROCARGS(clientData,interp,argc,argv) { + wordlist *wl= NULL; + char *device, *param; + struct variable *v; + char buf[128]; + if (argc != 3) { + Tcl_SetResult(interp, "Wrong # args. spice::get_param device param",TCL_STATIC); + return TCL_ERROR; + } + if (!ft_curckt) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + device = (char *)argv[1]; + param = (char *)argv[2]; + /* copied from old_show(wordlist *) */ + v = (*if_getparam)(ft_curckt->ci_ckt, + &device, param, 0, 0); + if (!v) + v = (*if_getparam)(ft_curckt->ci_ckt, + &device, param, 0, 1); + if (v) { + wl = cp_varwl(v); + Tcl_SetResult(interp,wl->wl_word,TCL_VOLATILE); + wl_free(wl); + tfree(v); + return TCL_OK; + + } else { + sprintf(buf,"%s in %s not found",param, device); + Tcl_AppendResult(interp,buf,TCL_STATIC); + } + return TCL_ERROR; + +} + +/* va - added + call: s. errormessage + returns: param == all: list of all model parameters of device/model + param == name: description of given model parameter +*/ +int get_mod_param TCL_CMDPROCARGS(clientData,interp,argc,argv) { + char *name; + char *paramname; + void *devptr=NULL; + void *modptr=NULL; + IFdevice *device; + IFparm *opt; + IFvalue pv; + int i, err, typecode=-1; + char buf[128]; + bool found; + + if (argc < 2 || argc >3) { + Tcl_SetResult(interp, + "Wrong # args. spice::get_mod_param device|model [all|param]", TCL_STATIC); + return TCL_ERROR; + } + if (ft_curckt==NULL) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + name = (char *)argv[1]; + if (argc>2) { + paramname=(char *)argv[2]; + } else { + paramname="all"; + } + if (name==NULL || name[0]=='\0') { + Tcl_SetResult(interp, "No model or device name provided.",TCL_STATIC); + return TCL_ERROR; + } + + /* get the unique IFuid for name (device/model) */ + INPretrieve(&name,(INPtables *)ft_curckt->ci_symtab); + err = (*(ft_sim->findInstance))(ft_curckt->ci_ckt,&typecode,&devptr,name,NULL,NULL); + if (err != OK) { + typecode = -1; + devptr = (void *)NULL; + err = (*(ft_sim->findModel))(ft_curckt->ci_ckt,&typecode,&modptr,name); + } + if (err != OK) { + sprintf(buf,"No such device or model name %s",name); + Tcl_SetResult(interp,buf,TCL_VOLATILE); + return TCL_ERROR; + } + device = ft_sim->devices[typecode]; + found = FALSE; + for (i = 0; i < *(device->numModelParms); i++) { + opt = &device->modelParms[i]; + if (opt->dataType != (IF_SET|IF_ASK|IF_REAL)) continue; /* only real IO-parameter */ + if (strcmp(paramname,"all")==0) { + Tcl_AppendElement(interp,opt->keyword); + found=TRUE; + } else if (strcmp(paramname,opt->keyword)==0) { + if (devptr) + err = (*(ft_sim->askInstanceQuest))(ft_curckt->ci_ckt, devptr, + opt->id, &pv, (IFvalue *)NULL); + else + err = (*(ft_sim->askModelQuest))(ft_curckt->ci_ckt, modptr, + opt->id, &pv, (IFvalue *)NULL); + if (err==OK) { + sprintf(buf,"%g",pv.rValue); /* dataType is here always real */ + Tcl_SetResult(interp,buf,TCL_VOLATILE); + return TCL_OK; + } + } + } + if (found!=TRUE) { + sprintf(buf,"unknown parameter %s",paramname); + Tcl_SetResult(interp,buf,TCL_VOLATILE); + return TCL_ERROR; + } + return TCL_OK; +} + +/* Direct control over the step size + * Spice will still adjust it to keep accuracy wuithin reltol and abstol + */ +static int delta TCL_CMDPROCARGS(clientData,interp,argc,argv) { + if (argc < 1 ||argc > 2) { + Tcl_SetResult(interp, "Wrong # args. spice::delta ?value?",TCL_STATIC); + return TCL_ERROR; + } + if (ft_curckt==NULL) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + if(argc == 2) { + ((CKTcircuit *)ft_curckt->ci_ckt)->CKTdelta = atof(argv[1]); + } + /*Ok, as log as string less than 200 chars*/ + sprintf(interp->result,"%G",((CKTcircuit *)ft_curckt->ci_ckt)->CKTdelta); + return TCL_OK; +} + +#include +/* Direct control over the maximum stepsize + * Spice will still adjust it to keep accuracy wuithin reltol and abstol + */ +static int maxstep TCL_CMDPROCARGS(clientData,interp,argc,argv) { + TRANan *job; + if (argc < 1 ||argc > 2) { + Tcl_SetResult(interp, "Wrong # args. spice::maxstep ?value?",TCL_STATIC); + return TCL_ERROR; + } + if (ft_curckt == NULL) { + Tcl_SetResult(interp, "No circuit loaded ",TCL_STATIC); + return TCL_ERROR; + } + + job = (TRANan*)((CKTcircuit *)ft_curckt->ci_ckt)->CKTcurJob; + if(argc == 2) { + job->TRANmaxStep = atof(argv[1]); + } + /*Ok, as log as string less than 200 chars*/ + sprintf(interp->result,"%G",job->TRANmaxStep); + return TCL_OK; + +} + + +/****************************************/ +/* The Tk frontend for plot */ +/****************************************/ + +/* Use Tcl_GetStringResult to get canvas size etc. from Tcl */ +#include +int sp_Tk_Init(void) { + /* This is hard coded in C at the mo, use X11 values */ + dispdev->numlinestyles = 8; + dispdev->numcolors = 20; + dispdev->width = 1280; + dispdev->height = 1024; + + return 0; +} + +#include +int sp_Tk_NewViewport(GRAPH *graph) { + const char *result; + int width, height, fontwidth, fontheight; + graph->devdep = (char *) NULL; + + if(Tcl_GlobalEval(spice_interp,"spice_gr_NewViewport") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + + result = Tcl_GetStringResult(spice_interp); + if(sscanf(result,"%i %i %i %i",&width,&height,&fontwidth, &fontheight) != 4) { + Tcl_ResetResult(spice_interp); + return 1; + } + graph->absolute.xpos = 0; /* these always seem sensible, let Tcl adjust coods */ + graph->absolute.ypos = 0; + graph->absolute.width = width; + graph->absolute.height = height; + graph->fontwidth = fontwidth; + graph->fontheight = fontheight; + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Close(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Close") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Clear(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Clear") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DrawLine(int x1, int y1, int x2, int y2) { + char buf[1024]; + sprintf(buf,"spice_gr_DrawLine %i %i %i %i",x1, y1, x2, y2); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Arc(int x0, int y0, int radius, double theta1, double theta2) { + char buf[1024]; + sprintf(buf,"spice_gr_Arc %i %i %i %f %f", x0, y0, radius, theta1, theta2); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Text(char *text, int x, int y) { + char buf[1024]; + sprintf(buf,"spice_gr_Text \"%s\" %i %i",text,x,y); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DefineColor(int colorid, double red, double green, double blue) { + char buf[1024]; + sprintf(buf,"spice_gr_DefineColor %i %g %g %g",colorid, red, green, blue); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_DefineLinestyle(int linestyleid, int mask) { + char buf[1024]; + sprintf(buf,"spice_gr_DefineLinestyle %i %i", linestyleid, mask); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_SetLinestyle(int linestyleid) { + char buf[1024]; + sprintf(buf,"spice_gr_SetLinestyle %i", linestyleid); + if(Tcl_Eval(spice_interp, buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_SetColor(int colorid) { + char buf[1024]; + sprintf(buf,"spice_gr_SetColor %i", colorid); + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + +int sp_Tk_Update(void) { + if(Tcl_Eval(spice_interp,"spice_gr_Update") != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + Tcl_ResetResult(spice_interp); + return 0; +} + + +/********************************************************/ +/* The Blt method for plotting */ +/********************************************************/ + +static void dvecToBlt(Blt_Vector *Data, struct dvec *x) { + if(x->v_flags & VF_REAL) { + Blt_ResetVector (Data, x->v_realdata ,x->v_length, + x->v_length, TCL_VOLATILE); + } else { + double *data; + int i; + + data = tmalloc(x->v_length * sizeof(double)); + + for(i=0;iv_length;i++) { + data[i] = realpart(&x->v_compdata[i]); + } + + Blt_ResetVector (Data, data, x->v_length, x->v_length, TCL_VOLATILE); + + tfree(data); + } + + return; +} + +static void escape_brackets(char *string) { + int printed=strlen(string), i; + + for(i=0;i=i;j--) { + string[j+3] = string[j]; + } + string[i] = '\\'; + string[i+1] = '\\'; + string[i+2] = '\\'; + i+=3; + printed+=3; + } + } + return; +} + +int blt_plot(struct dvec *y,struct dvec *x,int new){ + static int ctr=-1; + Blt_Vector *X_Data=NULL, *Y_Data=NULL; + char buf[1024]; + + /* A bug in these functions? , crashes if used so make vectors in Tcl + Blt_CreateVector(spice_interp,"::spice::X_Data",1,&X_Data); + Blt_CreateVector(spice_interp,"::spice::Y_Data",1,&Y_Data); + */ + Blt_GetVector(spice_interp,"::spice::X_Data",&X_Data); + Blt_GetVector(spice_interp,"::spice::Y_Data",&Y_Data); + + if(!X_Data || !Y_Data) { + fprintf(stderr,"Error: Blt vector X_Data or Y_Data not created\n"); + return 1; + } + + dvecToBlt(X_Data,x); + dvecToBlt(Y_Data,y); + + if(new) ctr++; + + sprintf(buf,"spice_gr_Plot %s %s %s %s %s %s %d", + x->v_name, ft_typenames(x->v_type), ft_typabbrev(x->v_type), + y->v_name, ft_typenames(y->v_type), ft_typabbrev(y->v_type),ctr); + escape_brackets(buf); + + if(Tcl_Eval(spice_interp,buf) != TCL_OK) { + Tcl_ResetResult(spice_interp); + return 1; + } + + Tcl_ResetResult(spice_interp); + + return 0; +} + +/********************************************************/ +/* Triggering stuff */ +/********************************************************/ + +struct triggerEvent { + struct triggerEvent *next; + int vector; + int type; + int stepNumber; + double time; + double voltage; + char ident[16]; +}; + + +struct triggerEvent *eventQueue; +struct triggerEvent *eventQueueEnd; + +#ifdef THREADS +mutexType triggerMutex; +#endif + +struct watch { + struct watch *next; + char name[16]; + int vector;/* index of vector to watch */ + int type; /* +ive or -ive trigger */ + int state; /* pretriggered or not */ + double Vmin; /* the boundaries */ + double Vmax; + /* To get the exact trigger time */ + double Vavg; + double oT; + double oV; +}; + +struct watch *watches; + +char *triggerCallback; +unsigned int triggerPollTime=1; + +char *stepCallback; +unsigned int stepPollTime=1; +unsigned int stepCount=1; +int stepCallbackPending; + +void stepEventSetup(ClientData clientData,int flags) { + Tcl_Time t; + if(stepCallbackPending) { + t.sec = 0; + t.usec = 0; + } else { + t.sec = stepPollTime / 1000; + t.usec = (stepPollTime % 1000) * 1000; + } + Tcl_SetMaxBlockTime(&t); +} + +int stepEventHandler(Tcl_Event *evPtr, int flags) { + if(stepCallbackPending) { + stepCallbackPending = 0; + Tcl_Preserve((ClientData)spice_interp); + Tcl_Eval(spice_interp,stepCallback); + Tcl_ResetResult(spice_interp); + Tcl_Release((ClientData)spice_interp); + } + return TCL_OK; +} + +void stepEventCheck(ClientData clientData,int flags) { + if(stepCallbackPending) { + Tcl_Event *tclEvent; + tclEvent = (Tcl_Event *) ckalloc(sizeof(Tcl_Event)); + tclEvent->proc = stepEventHandler; + Tcl_QueueEvent(tclEvent,TCL_QUEUE_TAIL); + } +} + +int triggerEventHandler(Tcl_Event *evPtr, int flags) { + static char buf[512]; + int rtn=TCL_OK; + Tcl_Preserve((ClientData)spice_interp); +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + while(eventQueue) { + struct triggerEvent *event = eventQueue; + eventQueue = eventQueue->next; + + snprintf(buf,512,"%s %s %g %d %d %g %s",triggerCallback,vectors[event->vector].name, + event->time,event->stepNumber,event->type,event->voltage,event->ident); + + rtn = Tcl_Eval(spice_interp,buf); + FREE(event); + if(rtn) { + goto quit; + } + } + eventQueueEnd = NULL; +quit: +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + Tcl_ResetResult(spice_interp); + Tcl_Release((ClientData)spice_interp); + return TCL_OK; +} + +void triggerEventSetup(ClientData clientData,int flags) { + Tcl_Time t; + if(eventQueue) { + t.sec = 0; + t.usec = 0; + } else { + t.sec = triggerPollTime / 1000; + t.usec = (triggerPollTime % 1000) * 1000; + } + Tcl_SetMaxBlockTime(&t); +} + +void triggerEventCheck(ClientData clientData,int flags) { +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + if(eventQueue) { + Tcl_Event *tclEvent; + tclEvent = (Tcl_Event *) ckalloc(sizeof(Tcl_Event)); + tclEvent->proc = triggerEventHandler; + Tcl_QueueEvent(tclEvent,TCL_QUEUE_TAIL); + } +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif +} + +int Tcl_ExecutePerLoop() { + + struct watch *current; + +#ifdef THREADS + mutex_lock(&vectors[0].mutex); + mutex_lock(&triggerMutex); +#endif + + for(current=watches;current;current = current->next) { + vector *v; + v = &vectors[current->vector]; +#ifdef THREADS + mutex_lock(&v->mutex); +#endif + + if((current->type > 0 && current->state && v->data[v->length-1] > current->Vmax) || + (current->type < 0 && current->state && v->data[v->length-1] < current->Vmin) ) { + struct triggerEvent *tmp = (struct triggerEvent *)MALLOC(sizeof(struct triggerEvent)); + + tmp->next = NULL; + + if(eventQueue) { + eventQueueEnd->next = tmp; + eventQueueEnd = tmp; + } else { + eventQueue = tmp; + } + + eventQueueEnd = tmp; + + tmp->vector = current->vector; + tmp->type = current->type; + tmp->stepNumber = vectors[0].length; + + { + double T = vectors[0].data[vectors[0].length-1]; + double V = v->data[v->length-1]; + + tmp->time = current->oT + + (current->Vavg - current->oV) * (T - current->oT) / (V - current->oV); + tmp->voltage = current->Vavg; + } + + strcpy(tmp->ident,current->name); + current->state = 0; + + } else + if((current->type > 0 && v->data[v->length-1] < current->Vmin) || + (current->type < 0 && v->data[v->length-1] > current->Vmax)) + current->state = 1; + + current->oT = vectors[0].data[vectors[0].length-1]; + current->oV = v->data[v->length-1]; + +#ifdef THREADS + mutex_unlock(&v->mutex); +#endif + } + + if(stepCallback && vectors[0].length % stepCount == 0) { + stepCallbackPending=1; + } + +#ifdef THREADS + mutex_unlock(&triggerMutex); + + mutex_unlock(&vectors[0].mutex); + + if(triggerCallback && eventQueue && bgtid != thread_self()) { + triggerEventHandler(NULL,0); + } + + if(stepCallback && stepCallbackPending && bgtid != thread_self()) { + stepEventHandler(NULL,0); + } +#else + if(triggerCallback && eventQueue) { + triggerEventHandler(NULL,0); + } + if(stepCallback && stepCallbackPending) { + triggerEventHandler(NULL,0); + } +#endif + + + return 0; +} + +static int resetTriggers() { +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + + while(watches) { + struct watch *tmp = watches; + watches = tmp->next; + FREE(tmp); + } + + while(eventQueue) { + struct triggerEvent *tmp = eventQueue; + eventQueue = tmp->next; + FREE(tmp); + } + + eventQueueEnd = NULL; + +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + return 0; +} + + +/* Registers a watch for a trigger + *arg0: Callback function (optional - none removes callback) + *arg1: Poll interval usec (optional - defaults to 500000 ) + */ +static int registerTriggerCallback TCL_CMDPROCARGS(clientData,interp,argc,argv){ + + if (argc > 3) { + Tcl_SetResult(interp, + "Wrong # args. spice::registerTriggerCallback ?proc? ?ms?", + TCL_STATIC); + return TCL_ERROR; + } + + if(triggerCallback) { + Tcl_DeleteEventSource(triggerEventSetup,triggerEventCheck,NULL); + free(triggerCallback); + triggerCallback = NULL; + } + + if(argc == 1) { + return TCL_OK; + } + + triggerCallback = strdup(argv[1]); + Tcl_CreateEventSource(triggerEventSetup,triggerEventCheck,NULL); + + if(argc == 3) { + triggerPollTime = atoi(argv[2]); + if(triggerPollTime == 0) + triggerPollTime = 500; + } + + return TCL_OK; +} + +/* Registers step counter callback + *arg0: Callback function (optional - none removes callback) + *arg1: Number of steps per Callback + *arg2: Poll interval usec (optional - defaults to 500000 ) + */ +static int registerStepCallback TCL_CMDPROCARGS(clientData,interp,argc,argv){ + + if (argc > 4) { + Tcl_SetResult(interp, + "Wrong # args. spice::registerStepCallback ?proc? ?steps? ?ms?", + TCL_STATIC); + return TCL_ERROR; + } + + if(stepCallback) { + Tcl_DeleteEventSource(stepEventSetup,stepEventCheck,NULL); + free(stepCallback); + stepCallback = NULL; + } + + if(argc == 1) { + return TCL_OK; + } + + stepCallback = strdup(argv[1]); + Tcl_CreateEventSource(stepEventSetup,stepEventCheck,NULL); + + if(argc >= 3) { + stepCount = atoi(argv[2]); + if(stepCount == 0) + stepCount = 1; + } + + if(argc == 4) { + stepPollTime = atoi(argv[3]); + if(stepPollTime == 0) + stepPollTime = 50; + } + + return TCL_OK; +} + +/* Registers a watch for a trigger + *arg0: Vector Name to watch + *arg1: Vmin + *arg2: Vmax + *arg3: 1 / -1 for +ive(voltage goes +ive) or -ive trigger + */ +static int registerTrigger TCL_CMDPROCARGS(clientData,interp,argc,argv){ + int i, index; + const char *var; + char ident[16]; + struct watch *tmp; + int type; + double Vavg, Vmin, Vmax; + + if (argc < 4 && argc > 6) { + Tcl_SetResult(interp, "Wrong # args. spice::registerTrigger vecName Vmin Vmax ?type? ?string?",TCL_STATIC); + return TCL_ERROR; + } + + var = argv[1]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) { + Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } else index = i; + + if(argc >= 5) + type = atoi(argv[4]); + else + type = 1; + + if(argc >= 6) { + strncpy(ident,argv[5],sizeof(ident)); + ident[sizeof(ident)-1] = '\0'; + } else + ident[0] = '\0'; + + Vmin = atof(argv[2]); + Vmax = atof(argv[3]); + Vavg = (Vmin + Vmax) / 2 ; + +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + + for(tmp = watches;tmp != NULL;tmp=tmp->next) { + if(ident[0] != '\0') { + if(strcmp(ident,tmp->name) == 0) { + watches->vector = index; + watches->type = type; + strcpy(watches->name,ident); + + watches->state = 0; + watches->Vmin = Vmin; + watches->Vmax = Vmax; + watches->Vavg = Vavg; + + break; + } + } else { + if(tmp->vector == index && tmp->type == type + && tmp->Vavg == Vavg ) { + tmp->Vmin = Vmin; + tmp->Vmax = Vmax; + break; + } + } + } + + if(tmp == NULL) { + + tmp = (struct watch *)MALLOC(sizeof(struct watch)); + tmp->next = watches; + watches = tmp; + + watches->vector = index; + watches->type = type; + strcpy(watches->name,ident); + + watches->state = 0; + watches->Vmin = Vmin; + watches->Vmax = Vmax; + watches->Vavg = Vavg; + + } + +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + + return TCL_OK; +} +/*unregisters a trigger + *arg0: Vector name + *arg1: type + */ +static int unregisterTrigger TCL_CMDPROCARGS(clientData,interp,argc,argv){ + int i, index, type; + char *var; + struct watch *tmp; + struct watch **cut; + + if (argc != 2 && argc != 3) { + Tcl_SetResult(interp, "Wrong # args. spice::unregisterTrigger vecName ?type?",TCL_STATIC); + return TCL_ERROR; + } + + var = (char *)argv[1]; + + for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++); + + if(i == blt_vnum) + index = -1; + else + index = i; + + if(argc == 3) + type = atoi(argv[4]); + else + type = 1; + +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + + cut = &watches; + + tmp = watches; + + while(tmp) + if((tmp->vector == index && tmp->type == type) || strcmp(var,tmp->name) == 0) { + *cut = tmp->next; + txfree(tmp); + break; + } else { + cut = &tmp->next; + tmp = tmp->next; + } + +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + + if(tmp == NULL) { + Tcl_SetResult(interp, "Could not find trigger ",TCL_STATIC); + Tcl_AppendResult(interp, (char *)var, TCL_STATIC); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* returns: +"vecName" "time" "stepNumber" "type" +*/ +static int popTriggerEvent TCL_CMDPROCARGS(clientData,interp,argc,argv){ + + if (argc != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::popTriggerEvent",TCL_STATIC); + return TCL_ERROR; + } + + if(eventQueue) { + struct triggerEvent *popedEvent; + Tcl_Obj *list; + +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + + popedEvent = eventQueue; + + eventQueue = popedEvent->next; + if(eventQueue == NULL) + eventQueueEnd = NULL; + + list = Tcl_NewListObj(0,NULL); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewStringObj(vectors[popedEvent->vector].name,strlen(vectors[popedEvent->vector].name))); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewDoubleObj(popedEvent->time)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewIntObj(popedEvent->stepNumber)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewIntObj(popedEvent->type)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewDoubleObj(popedEvent->voltage)); + + Tcl_ListObjAppendElement(interp,list,Tcl_NewStringObj(popedEvent->ident,strlen(popedEvent->ident))); + + Tcl_SetObjResult(interp,list); + + FREE(popedEvent); + +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + } + + return TCL_OK; +} + +static int listTriggers TCL_CMDPROCARGS(clientData,interp,argc,argv){ + struct watch *tmp; + Tcl_Obj *list; + + if (argc != 1) { + Tcl_SetResult(interp, "Wrong # args. spice::listTriggers",TCL_STATIC); + return TCL_ERROR; + } + + list = Tcl_NewListObj(0,NULL); + +#ifdef THREADS + mutex_lock(&triggerMutex); +#endif + + for(tmp=watches;tmp;tmp=tmp->next) + Tcl_ListObjAppendElement(interp,list,Tcl_NewStringObj(vectors[tmp->vector].name,strlen(vectors[tmp->vector].name))); + +#ifdef THREADS + mutex_unlock(&triggerMutex); +#endif + + Tcl_SetObjResult(interp,list); + + return TCL_OK; +} + +static int tmeasure TCL_CMDPROCARGS(clientData,interp,argc,argv){ + + wordlist *wl= NULL; + float mvalue; + + if (argc <= 2) { + Tcl_SetResult(interp, "Wrong # args. spice::listTriggers",TCL_STATIC); + return TCL_ERROR; + } + + wl =wl_build(argv); + + mvalue = get_measure2(wl); + + printf(" %e \n", mvalue); + + Tcl_ResetResult(spice_interp); + + Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) mvalue)); + + return TCL_OK; +} + + +/*******************************************************/ +/* Initialise spice and setup native methods */ +/*******************************************************/ + +#ifdef __MINGW32__ +__declspec(dllexport) +#endif +int Spice_Init(Tcl_Interp *interp) { + + if (interp == 0) return TCL_ERROR; + +#ifdef USE_TCL_STUBS + if(Tcl_InitStubs(interp, (char *)"8.1",0) == NULL) + return TCL_ERROR; +#endif + + Tcl_PkgProvide(interp, (char*)TCLSPICE_name, (char*)TCLSPICE_version); + + Tcl_Eval(interp, "namespace eval " TCLSPICE_namespace " { }"); + + save_interp(); + + { + extern void DevInit(); + int i; + char *key; + Tcl_CmdInfo infoPtr; + char buf[256]; + sighandler old_sigint; + + ft_rawfile = NULL; + ivars( ); + + cp_in = stdin; + cp_out = stdout; + cp_err = stderr; + + /*timer*/ + init_time( ); + + /*IFsimulator struct initilised*/ + SIMinit(&nutmeginfo, &ft_sim); + + /* program name*/ + cp_program = ft_sim->simulator; + + srandom(getpid()); + + /*parameter fetcher, used in show*/ + if_getparam = spif_getparam; + + /*Command prompt stuff */ + ft_cpinit(); + + + /* Read the user config files */ + /* To catch interrupts during .spiceinit... */ + old_sigint = signal(SIGINT, ft_sigintr); + if (sigsetjmp(jbuf, 1) == 1) { + fprintf(cp_err, "Warning: error executing .spiceinit.\n"); + goto bot; + } + +#ifdef HAVE_PWD_H + /* Try to source either .spiceinit or ~/.spiceinit. */ + if (access(".spiceinit", 0) == 0) + inp_source(".spiceinit"); + else { + char *s; + struct passwd *pw; + pw = getpwuid(getuid()); + +#define INITSTR "/.spiceinit" +#ifdef HAVE_ASPRINTF + asprintf(&s, "%s%s", pw->pw_dir,INITSTR); +#else /* ~ HAVE_ASPRINTF */ + s=(char *) tmalloc(1 + strlen(pw->pw_dir)+strlen(INITSTR)); + sprintf(s,"%s%s",pw->pw_dir,INITSTR); +#endif /* HAVE_ASPRINTF */ + if (access(s, 0) == 0) + inp_source(s); + } +#else /* ~ HAVE_PWD_H */ + { + FILE *fp; + /* Try to source the file "spice.rc" in the current directory. */ + if ((fp = fopen("spice.rc", "r")) != NULL) { + (void) fclose(fp); + inp_source("spice.rc"); + } + } +#endif /* ~ HAVE_PWD_H */ +bot: + signal(SIGINT, old_sigint); + + /* initilise Tk display */ + DevInit(); + + /*parrallel arch support, or not */ + ARCHme = 0; + ARCHsize = 1; + + /* init the mutex */ +#ifdef HAVE_LIBPTHREAD + pthread_mutex_init(&triggerMutex,NULL); +#endif +#ifdef THREADS + signal(SIGINT,sighandler_tclspice); +#endif + + /*register functions*/ + for (i = 0;(key = cp_coms[i].co_comname); i++) { + sprintf(buf,"%s%s",TCLSPICE_prefix,key); + if(Tcl_GetCommandInfo(interp,buf, &infoPtr)!= 0){ + printf("Command '%s' can not be registered!\n", buf); + }else{ + Tcl_CreateCommand(interp,buf, _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + } + } + + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice_header", spice_header, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice_data", spice_data, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spicetoblt", spicetoblt, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "vectoblt", vectoblt, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "lastVector", lastVector, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_value", get_value, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "spice", _spice_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_output", get_output, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_param", get_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "get_mod_param", get_mod_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "delta", delta, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "maxstep", maxstep, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_variables", plot_variables, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_variablesInfo", plot_variablesInfo, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_get_value", plot_get_value, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_datapoints", plot_datapoints, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_title", plot_title, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_date", plot_date, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_name", plot_name, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_typename", plot_typename, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_nvars", plot_nvars, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_defaultscale", plot_defaultscale, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_getvector", plot_getvector, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "getplot", plot_getplot, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTrigger", registerTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTriggerCallback", registerTriggerCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "popTriggerEvent", popTriggerEvent, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "unregisterTrigger", unregisterTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "listTriggers", listTriggers, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + Tcl_CreateCommand(interp, TCLSPICE_prefix "registerStepCallback", registerTriggerCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); +#ifdef THREADS + Tcl_CreateCommand(interp, TCLSPICE_prefix "bg", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "halt", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, TCLSPICE_prefix "running", running, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); +#endif + + Tcl_CreateCommand(interp, TCLSPICE_prefix "tmeasure", tmeasure, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + Tcl_CreateCommand(interp, TCLSPICE_prefix "registerStepCallback", registerStepCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL); + + Tcl_LinkVar(interp, TCLSPICE_prefix "steps_completed", (char *)&steps_completed, TCL_LINK_READ_ONLY|TCL_LINK_INT); + Tcl_LinkVar(interp, TCLSPICE_prefix "blt_vnum", (char *)&blt_vnum, TCL_LINK_READ_ONLY|TCL_LINK_INT); + } + return TCL_OK; +} + +/***************************************/ +/* printf wrappers to redirect to puts */ +/***************************************/ + +/* Contributed by Tim Edwards (tim@stravinsky.jhuapl.edu), 2003 */ + + +/*------------------------------------------------------*/ +/* Redefine the vfprintf() functions for use with tkcon */ +/*------------------------------------------------------*/ + +int tcl_vfprintf(FILE *f, const char *fmt, ...) +{ + static char outstr[128] = "puts -nonewline std"; + char *outptr, *bigstr = NULL, *finalstr = NULL; + int i, nchars, result, escapes = 0; + va_list arg; + + va_start (arg, fmt); + if((fileno(f) != STDOUT_FILENO && fileno(f) != STDERR_FILENO && + f != stderr && f != stdout ) +#ifdef THREADS + || ( fl_running && bgtid == thread_self()) +#endif + ) + return fprintf(f,fmt, arg); + + strcpy (outstr + 18, (f == stderr) ? "err \"" : "out \""); + outptr = outstr; + nchars = snprintf(outptr + 20, 102, fmt, arg); + if (nchars >= 102) + { + bigstr = Tcl_Alloc(nchars + 26); + strncpy(bigstr, outptr, 24); + outptr = bigstr; + snprintf(outptr + 24, nchars + 2, fmt, arg); + } + else if (nchars == -1) nchars = 126; + + for (i = 24; *(outptr + i) != '\0'; i++) { + if (*(outptr + i) == '\"' || *(outptr + i) == '[' || + *(outptr + i) == ']' || *(outptr + i) == '\\') + escapes++; + } + + + if (escapes > 0) + { + finalstr = Tcl_Alloc(nchars + escapes + 26); + strncpy(finalstr, outptr, 24); + escapes = 0; + for (i = 24; *(outptr + i) != '\0'; i++) + { + if (*(outptr + i) == '\"' || *(outptr + i) == '[' || + *(outptr + i) == ']' || *(outptr + i) == '\\') + { + *(finalstr + i + escapes) = '\\'; + escapes++; + } + *(finalstr + i + escapes) = *(outptr + i); + } + outptr = finalstr; + } + + *(outptr + 24 + nchars + escapes) = '\"'; + *(outptr + 25 + nchars + escapes) = '\0'; + + result = Tcl_Eval(spice_interp, outptr); + + if (bigstr != NULL) Tcl_Free(bigstr); + if (finalstr != NULL) Tcl_Free(finalstr); + return nchars; +} + +/*----------------------------------------------------------------------*/ +/* Reimplement fprintf() as a call to Tcl_Eval(). */ +/*----------------------------------------------------------------------*/ + +int tcl_fprintf(FILE *f, const char *format, ...) +{ + va_list arg; + int rtn; + + va_start (arg, format); + rtn = tcl_vfprintf(f, format, arg); + + return rtn; +} + +/*----------------------------------------------------------------------*/ +/* Reimplement fprintf() as a call to Tcl_Eval(). */ +/*----------------------------------------------------------------------*/ + +int tcl_printf(const char *format, ...) +{ + va_list arg; + int rtn; + + va_start (arg, format); + rtn = tcl_vfprintf(stdout, format, arg); + + return rtn; +} +/*------------------------------------------------------*/ +/* Console output flushing which goes along with the */ +/* routine tcl_vprintf() above. */ +/*------------------------------------------------------*/ + +void tcl_stdflush(FILE *f) +{ + Tcl_SavedResult state; + static char stdstr[] = "flush stdxxx"; + char *stdptr = stdstr + 9; + +#ifdef THREADS + if ( fl_running && bgtid == thread_self()) + return; +#endif + + Tcl_SaveResult(spice_interp, &state); + strcpy(stdptr, (f == stderr) ? "err" : "out"); + Tcl_Eval(spice_interp, stdstr); + Tcl_RestoreResult(spice_interp, &state); +} diff --git a/src/tclspice.map b/src/tclspice.map new file mode 100644 index 000000000..8e9e4a73d --- /dev/null +++ b/src/tclspice.map @@ -0,0 +1,5 @@ +TCLSPICE_0.2 +{ + global: Spice_Init; + local: *; +}; diff --git a/src/xspice/cm/Makefile.am b/src/xspice/cm/Makefile.am index 56cd8cae0..6898e4947 100755 --- a/src/xspice/cm/Makefile.am +++ b/src/xspice/cm/Makefile.am @@ -2,9 +2,9 @@ # # JW 3/9/01 - had a go and makeing an autoconf script. -noinst_LIBRARIES = libcmxsp.a +noinst_LTLIBRARIES = libcmxsp.la -libcmxsp_a_SOURCES = \ +libcmxsp_la_SOURCES = \ cm.c \ cmevt.c \ cmmeters.c \ diff --git a/src/xspice/enh/Makefile.am b/src/xspice/enh/Makefile.am index 09614da7d..d7246c32f 100755 --- a/src/xspice/enh/Makefile.am +++ b/src/xspice/enh/Makefile.am @@ -2,9 +2,9 @@ # # JW 3/9/01 - had a go and makeing an autoconf script. -noinst_LIBRARIES = libenhxsp.a +noinst_LTLIBRARIES = libenhxsp.la -libenhxsp_a_SOURCES = \ +libenhxsp_la_SOURCES = \ enh.c \ enhtrans.c diff --git a/tests/tcl-testbench1/PN2222.mod b/tests/tcl-testbench1/PN2222.mod new file mode 100644 index 000000000..d683d374e --- /dev/null +++ b/tests/tcl-testbench1/PN2222.mod @@ -0,0 +1,7 @@ +.model PN2222 NPN(Is=14.34f Xti=3 Eg=1.11 Vaf=74.03 Bf=255.9 Ne=1.307 ++ Ise=14.34f Ikf=.2847 Xtb=1.5 Br=6.092 Nc=2 Isc=0 Ikr=0 Rc=1 ++ Cjc=7.306p Mjc=.3416 Vjc=.75 Fc=.5 Cje=22.01p Mje=.377 Vje=.75 ++ Tr=46.91n Tf=411.1p Itf=.6 Vtf=1.7 Xtf=3 Rb=10) + +* Fairchild pid=19 case=TO92 +* 88-09-07 bam creation diff --git a/tests/tcl-testbench1/capa.cir b/tests/tcl-testbench1/capa.cir new file mode 100644 index 000000000..35478a724 --- /dev/null +++ b/tests/tcl-testbench1/capa.cir @@ -0,0 +1,30 @@ +* Capa variable sur la base de la thèse de Marc KODRNJA + +.SUBCKT capa 4 6 5 7 8 0 +Vref1 26 0 DC 3 +Vref2 16 0 DC 3 +Vdp 7 0 DC 7 +I0 3 0 DC 0.07 +Ia1 15 0 DC 0.01 +Ia2 25 0 DC 0.01 +Ib1 14 0 DC 0.01 +Ib2 24 0 DC 0.01 + +.INCLUDE PN2222.mod +Qv1 4 16 14 PN2222 +Qv2 4 26 24 PN2222 +Q1 11 14 3 PN2222 +Q2 21 24 3 PN2222 +Qp1 5 8 11 PN2222 +Qm1 6 7 11 PN2222 +Qp2 6 8 21 PN2222 +Qm2 5 7 21 PN2222 +Qc1 4 5 15 PN2222 +Qc2 4 6 25 PN2222 + +R1 4 5 100 +R2 4 6 100 +C1 15 14 10n +C2 25 24 10n +.ENDS + diff --git a/tests/tcl-testbench1/tcl-testbench1.tcl b/tests/tcl-testbench1/tcl-testbench1.tcl new file mode 100644 index 000000000..54b441993 --- /dev/null +++ b/tests/tcl-testbench1/tcl-testbench1.tcl @@ -0,0 +1,63 @@ +#!/bin/sh +# WishFix \ + exec wish -f "$0" ${1+"$@"} + ### + +# old name: analyse-20070504-0.tcl +package require BLT +load ../../src/.libs/libspice.so + +# Test of virtual capacitore circuit +# Vary the control voltage and log the resulting capacitance +spice::source "testCapa.cir" + +set n 30 +set dv 0.2 +set vmax [expr $dv/2] +set vmin [expr -1 * $dv/2] +set pas [expr $dv/ $n] + +blt::vector create Ctmp +blt::vector create Cim +blt::vector create check + +blt::vector create Vcmd +blt::graph .cimvd -title "Cim = f(Vd)" +blt::graph .checkvd -title "Rim = f(Vd)" + +blt::vector create Iex +blt::vector create freq +blt::graph .freqanal -title "Analyse frequentielle" + +set v [expr {$vmin + $n * $pas / 4}] +spice::alter vd = $v +spice::op +spice::ac dec 10 100 100k +spice::vectoblt {Vex#branch} Iex +spice::vectoblt {frequency} freq +pack .freqanal +.freqanal element create line1 -xdata freq -ydata Iex + +for {set i 0} {[expr $n - $i]} {incr i } { +set v [expr {$vmin + $i * $pas}] +spice::alter vd = $v +spice::op +spice::ac dec 10 100 100k + + +spice::let Cim = real(mean(Vex#branch/(2*Pi*i*frequency*(V(5)-V(6))))) +spice::vectoblt Cim Ctmp +Cim append $Ctmp(0:end) +spice::let err = real(mean(sqrt((Vex#branch-(2*Pi*i*frequency*Cim*V(5)-V(6)))^2))) +spice::vectoblt err Ctmp +check append $Ctmp(0:end) +Vcmd append $v + +} + +pack .cimvd +.cimvd element create line1 -xdata Vcmd -ydata Cim +pack .checkvd +.checkvd element create line1 -xdata Vcmd -ydata check + + diff --git a/tests/tcl-testbench1/testCapa.cir b/tests/tcl-testbench1/testCapa.cir new file mode 100644 index 000000000..c74cb5311 --- /dev/null +++ b/tests/tcl-testbench1/testCapa.cir @@ -0,0 +1,9 @@ +Banc de test pour la Capa variable sur la base de la thèse de Marc KODRNJA + +.INCLUDE capa.cir + +Valim 4 0 DC 12 +Vex 6 5 DC 0 AC 0.01 0 +Vd 7 8 DC 0.0 +xcapa 4 6 5 7 8 0 capa +.END diff --git a/tests/tcl-testbench2/example.cir b/tests/tcl-testbench2/example.cir new file mode 100644 index 000000000..145def7f8 --- /dev/null +++ b/tests/tcl-testbench2/example.cir @@ -0,0 +1,587 @@ +TITLE: proj1.cir.cir - Rotary Traveling Wave Oscillator +.control +set filetype=ascii +.endc + +VDD0 VDD0 VDD DC 0 +VSS0 VSS0 0 DC 0 +VDD_A0 VDD_A0 VDD0 DC 0 +VSS_A0 VSS_A0 VSS0 DC 0 +VDD_B0 VDD_B0 VDD0 DC 0 +VSS_B0 VSS_B0 VSS0 DC 0 +LA0 A0 LCA0 3.69030941553353e-11 +RA0 LCA0 A1 0.266535044422507 +LB0 B0 LCB0 3.69030941553353e-11 +RB0 LCB0 B1 0.266535044422507 +C0 A1 B1 2.50418376625721e-14 +MNA0 B0 A0 VSS_B0 VSS_B0 Nmod L=2.53696435353243e-07 W= ++4.24857778403814e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.49715556807627e-05 PS=8.49715556807627e-05 NQSMOD=1 +MPA0 B0 A0 VDD_B0 VDD_B0 Pmod L=2.55343565546106e-07 W= ++0.000101772203908557 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203544407817114 PS=0.000203544407817114 NQSMOD=1 +MNB0 A0 B0 VSS_A0 VSS_A0 Nmod L=2.53941602497219e-07 W= ++4.10652659629401e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.21305319258802e-05 PS=8.21305319258802e-05 NQSMOD=1 +MPB0 A0 B0 VDD_A0 VDD_A0 Pmod L=2.52010168145607e-07 W= ++0.000103533977891464 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207067955782928 PS=0.000207067955782928 NQSMOD=1 +LA1 A1 LCA1 3.69030941553353e-11 +RA1 LCA1 A2 0.266535044422507 +LB1 B1 LCB1 3.69030941553353e-11 +RB1 LCB1 B2 0.266535044422507 +C1 A2 B2 2.50418376625721e-14 +MNA1 B1 A1 0 0 Nmod L=2.52370578161099e-07 W=4.12246995102289e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.24493990204578e-05 PS= ++8.24493990204578e-05 NQSMOD=1 +MPA1 B1 A1 VDD VDD Pmod L=2.45709468983316e-07 W=0.000103710764679465 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207421529358929 PS= ++0.000207421529358929 NQSMOD=1 +MNB1 A1 B1 0 0 Nmod L=2.48115895523017e-07 W=4.26306134285554e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.52612268571108e-05 PS= ++8.52612268571108e-05 NQSMOD=1 +MPB1 A1 B1 VDD VDD Pmod L=2.55265156192223e-07 W=0.000102043840486507 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204087680973014 PS= ++0.000204087680973014 NQSMOD=1 +LA2 A2 LCA2 3.69030941553353e-11 +RA2 LCA2 A3 0.266535044422507 +LB2 B2 LCB2 3.69030941553353e-11 +RB2 LCB2 B3 0.266535044422507 +C2 A3 B3 2.50418376625721e-14 +MNA2 B2 A2 0 0 Nmod L=2.53484220592882e-07 W=4.16915225420459e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.33830450840917e-05 PS= ++8.33830450840917e-05 NQSMOD=1 +MPA2 B2 A2 VDD VDD Pmod L=2.44256748076514e-07 W=0.00010549295960702 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000210985919214039 PS= ++0.000210985919214039 NQSMOD=1 +MNB2 A2 B2 0 0 Nmod L=2.48805892712811e-07 W=4.15734692647458e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.31469385294916e-05 PS= ++8.31469385294916e-05 NQSMOD=1 +MPB2 A2 B2 VDD VDD Pmod L=2.54004987710956e-07 W=0.00010229621219808 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020459242439616 PS= ++0.00020459242439616 NQSMOD=1 +LA3 A3 LCA3 3.69030941553353e-11 +RA3 LCA3 A4 0.266535044422507 +LB3 B3 LCB3 3.69030941553353e-11 +RB3 LCB3 B4 0.266535044422507 +C3 A4 B4 2.50418376625721e-14 +MNA3 B3 A3 0 0 Nmod L=2.54307430347219e-07 W=4.11339076756089e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22678153512179e-05 PS= ++8.22678153512179e-05 NQSMOD=1 +MPA3 B3 A3 VDD VDD Pmod L=2.52369109463781e-07 W=0.000103371681055656 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206743362111311 PS= ++0.000206743362111311 NQSMOD=1 +MNB3 A3 B3 0 0 Nmod L=2.4960708801709e-07 W=4.21794611046917e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.43589222093833e-05 PS= ++8.43589222093833e-05 NQSMOD=1 +MPB3 A3 B3 VDD VDD Pmod L=2.53834779766428e-07 W=0.000105556314711602 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000211112629423204 PS= ++0.000211112629423204 NQSMOD=1 +LA4 A4 LCA4 3.69030941553353e-11 +RA4 LCA4 A5 0.266535044422507 +LB4 B4 LCB4 3.69030941553353e-11 +RB4 LCB4 B5 0.266535044422507 +C4 A5 B5 2.50418376625721e-14 +MNA4 B4 A4 0 0 Nmod L=2.48091656083177e-07 W=4.11207568141106e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22415136282211e-05 PS= ++8.22415136282211e-05 NQSMOD=1 +MPA4 B4 A4 VDD VDD Pmod L=2.47723605289033e-07 W=0.000103463392309261 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206926784618522 PS= ++0.000206926784618522 NQSMOD=1 +MNB4 A4 B4 0 0 Nmod L=2.49254771880382e-07 W=4.25122425012226e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50244850024452e-05 PS= ++8.50244850024452e-05 NQSMOD=1 +MPB4 A4 B4 VDD VDD Pmod L=2.49689766979065e-07 W=0.000103227993619608 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206455987239216 PS= ++0.000206455987239216 NQSMOD=1 +LA5 A5 LCA5 3.69030941553353e-11 +RA5 LCA5 A6 0.266535044422507 +LB5 B5 LCB5 3.69030941553353e-11 +RB5 LCB5 B6 0.266535044422507 +C5 A6 B6 2.50418376625721e-14 +MNA5 B5 A5 0 0 Nmod L=2.53960031106522e-07 W=4.1129961792588e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22599235851759e-05 PS= ++8.22599235851759e-05 NQSMOD=1 +MPA5 B5 A5 VDD VDD Pmod L=2.47418707088064e-07 W=0.000101621693062467 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203243386124935 PS= ++0.000203243386124935 NQSMOD=1 +MNB5 A5 B5 0 0 Nmod L=2.49659687529522e-07 W=4.2524931640785e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50498632815701e-05 PS= ++8.50498632815701e-05 NQSMOD=1 +MPB5 A5 B5 VDD VDD Pmod L=2.46328059754468e-07 W=0.000102061546065548 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204123092131096 PS= ++0.000204123092131096 NQSMOD=1 +LA6 A6 LCA6 3.69030941553353e-11 +RA6 LCA6 A7 0.266535044422507 +LB6 B6 LCB6 3.69030941553353e-11 +RB6 LCB6 B7 0.266535044422507 +C6 A7 B7 2.50418376625721e-14 +MNA6 B6 A6 0 0 Nmod L=2.54326804653788e-07 W=4.17332976706085e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34665953412171e-05 PS= ++8.34665953412171e-05 NQSMOD=1 +MPA6 B6 A6 VDD VDD Pmod L=2.48727427835127e-07 W=0.000103244611103459 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206489222206918 PS= ++0.000206489222206918 NQSMOD=1 +MNB6 A6 B6 0 0 Nmod L=2.49697035135609e-07 W=4.23570035518e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.47140071036001e-05 PS= ++8.47140071036001e-05 NQSMOD=1 +MPB6 A6 B6 VDD VDD Pmod L=2.48995485890626e-07 W=0.000103695454759978 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207390909519956 PS= ++0.000207390909519956 NQSMOD=1 +LA7 A7 LCA7 3.69030941553353e-11 +RA7 LCA7 A8 0.266535044422507 +LB7 B7 LCB7 3.69030941553353e-11 +RB7 LCB7 B8 0.266535044422507 +C7 A8 B8 2.50418376625721e-14 +MNA7 B7 A7 0 0 Nmod L=2.53418975114981e-07 W=4.06421756574473e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.12843513148946e-05 PS= ++8.12843513148946e-05 NQSMOD=1 +MPA7 B7 A7 VDD VDD Pmod L=2.4471861043622e-07 W=0.000104600862141835 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020920172428367 PS= ++0.00020920172428367 NQSMOD=1 +MNB7 A7 B7 0 0 Nmod L=2.50159056393584e-07 W=4.06845582724173e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.13691165448345e-05 PS= ++8.13691165448345e-05 NQSMOD=1 +MPB7 A7 B7 VDD VDD Pmod L=2.55032245177227e-07 W=0.000106482118141681 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000212964236283363 PS= ++0.000212964236283363 NQSMOD=1 +LA8 A8 LCA8 3.69030941553353e-11 +RA8 LCA8 A9 0.266535044422507 +LB8 B8 LCB8 3.69030941553353e-11 +RB8 LCB8 B9 0.266535044422507 +C8 A9 B9 2.50418376625721e-14 +MNA8 B8 A8 0 0 Nmod L=2.45729547191971e-07 W=4.18266198665335e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.3653239733067e-05 PS=8.3653239733067e-05 ++NQSMOD=1 +MPA8 B8 A8 VDD VDD Pmod L=2.45156004861421e-07 W=0.000101593205477244 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203186410954489 PS= ++0.000203186410954489 NQSMOD=1 +MNB8 A8 B8 0 0 Nmod L=2.49014342219656e-07 W=4.14314219478801e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.28628438957603e-05 PS= ++8.28628438957603e-05 NQSMOD=1 +MPB8 A8 B8 VDD VDD Pmod L=2.50396673007567e-07 W=0.000103029640740115 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020605928148023 PS= ++0.00020605928148023 NQSMOD=1 +LA9 A9 LCA9 3.69030941553353e-11 +RA9 LCA9 A10 0.266535044422507 +LB9 B9 LCB9 3.69030941553353e-11 +RB9 LCB9 B10 0.266535044422507 +C9 A10 B10 2.50418376625721e-14 +MNA9 B9 A9 0 0 Nmod L=2.51066307645916e-07 W=4.17044186844862e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34088373689724e-05 PS= ++8.34088373689724e-05 NQSMOD=1 +MPA9 B9 A9 VDD VDD Pmod L=2.4945438501494e-07 W=0.000104601836030031 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000209203672060063 PS= ++0.000209203672060063 NQSMOD=1 +MNB9 A9 B9 0 0 Nmod L=2.56178041422984e-07 W=4.17990098329256e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.35980196658511e-05 PS= ++8.35980196658511e-05 NQSMOD=1 +MPB9 A9 B9 VDD VDD Pmod L=2.5274010042983e-07 W=0.000103578149162769 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207156298325537 PS= ++0.000207156298325537 NQSMOD=1 +LA10 A10 LCA10 3.69030941553353e-11 +RA10 LCA10 A11 0.266535044422507 +LB10 B10 LCB10 3.69030941553353e-11 +RB10 LCB10 B11 0.266535044422507 +C10 A11 B11 2.50418376625721e-14 +MNA10 B10 A10 0 0 Nmod L=2.45772611943267e-07 W=4.24345922952649e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.48691845905299e-05 PS= ++8.48691845905299e-05 NQSMOD=1 +MPA10 B10 A10 VDD VDD Pmod L=2.55544710347746e-07 W= ++0.000105625826497323 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211251652994645 PS=0.000211251652994645 NQSMOD=1 +MNB10 A10 B10 0 0 Nmod L=2.55886308364338e-07 W=4.0850956346516e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.17019126930321e-05 PS= ++8.17019126930321e-05 NQSMOD=1 +MPB10 A10 B10 VDD VDD Pmod L=2.44778614470725e-07 W= ++0.000105511594248206 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211023188496411 PS=0.000211023188496411 NQSMOD=1 +LA11 A11 LCA11 3.69030941553353e-11 +RA11 LCA11 A12 0.266535044422507 +LB11 B11 LCB11 3.69030941553353e-11 +RB11 LCB11 B12 0.266535044422507 +C11 A12 B12 2.50418376625721e-14 +MNA11 B11 A11 0 0 Nmod L=2.4768739676619e-07 W=4.14724461551725e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29448923103449e-05 PS= ++8.29448923103449e-05 NQSMOD=1 +MPA11 B11 A11 VDD VDD Pmod L=2.46276216123912e-07 W= ++0.000101782633723501 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203565267447002 PS=0.000203565267447002 NQSMOD=1 +MNB11 A11 B11 0 0 Nmod L=2.54985612770668e-07 W=4.24608643314108e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49217286628216e-05 PS= ++8.49217286628216e-05 NQSMOD=1 +MPB11 A11 B11 VDD VDD Pmod L=2.45772463970764e-07 W= ++0.000106109588792745 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021221917758549 PS=0.00021221917758549 NQSMOD=1 +LA12 A12 LCA12 3.69030941553353e-11 +RA12 LCA12 A13 0.266535044422507 +LB12 B12 LCB12 3.69030941553353e-11 +RB12 LCB12 B13 0.266535044422507 +C12 A13 B13 2.50418376625721e-14 +MNA12 B12 A12 0 0 Nmod L=2.45480481009462e-07 W=4.20858793029857e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41717586059714e-05 PS= ++8.41717586059714e-05 NQSMOD=1 +MPA12 B12 A12 VDD VDD Pmod L=2.48462320158069e-07 W= ++0.00010650127744954 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021300255489908 PS=0.00021300255489908 NQSMOD=1 +MNB12 A12 B12 0 0 Nmod L=2.51992945030792e-07 W=4.17981435096244e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.35962870192489e-05 PS= ++8.35962870192489e-05 NQSMOD=1 +MPB12 A12 B12 VDD VDD Pmod L=2.49941922576661e-07 W= ++0.0001044851795426 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208970359085199 PS=0.000208970359085199 NQSMOD=1 +LA13 A13 LCA13 3.69030941553353e-11 +RA13 LCA13 A14 0.266535044422507 +LB13 B13 LCB13 3.69030941553353e-11 +RB13 LCB13 B14 0.266535044422507 +C13 A14 B14 2.50418376625721e-14 +MNA13 B13 A13 0 0 Nmod L=2.51146190542173e-07 W=4.23276196447018e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.46552392894035e-05 PS= ++8.46552392894035e-05 NQSMOD=1 +MPA13 B13 A13 VDD VDD Pmod L=2.46359362747576e-07 W= ++0.00010249565409785 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.0002049913081957 PS=0.0002049913081957 NQSMOD=1 +MNB13 A13 B13 0 0 Nmod L=2.44656485453628e-07 W=4.11044634633624e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.22089269267248e-05 PS= ++8.22089269267248e-05 NQSMOD=1 +MPB13 A13 B13 VDD VDD Pmod L=2.56119611942636e-07 W= ++0.0001064085618438 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002128171236876 ++PS=0.0002128171236876 NQSMOD=1 +LA14 A14 LCA14 3.69030941553353e-11 +RA14 LCA14 A15 0.266535044422507 +LB14 B14 LCB14 3.69030941553353e-11 +RB14 LCB14 B15 0.266535044422507 +C14 A15 B15 2.50418376625721e-14 +MNA14 B14 A14 0 0 Nmod L=2.47663439668801e-07 W=4.20889991075918e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41779982151835e-05 PS= ++8.41779982151835e-05 NQSMOD=1 +MPA14 B14 A14 VDD VDD Pmod L=2.51252450429323e-07 W= ++0.000103622229824819 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207244459649638 PS=0.000207244459649638 NQSMOD=1 +MNB14 A14 B14 0 0 Nmod L=2.5044796612668e-07 W=4.24685059762319e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49370119524638e-05 PS= ++8.49370119524638e-05 NQSMOD=1 +MPB14 A14 B14 VDD VDD Pmod L=2.4786360459861e-07 W= ++0.000104258615459431 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208517230918863 PS=0.000208517230918863 NQSMOD=1 +LA15 A15 LCA15 3.69030941553353e-11 +RA15 LCA15 A16 0.266535044422507 +LB15 B15 LCB15 3.69030941553353e-11 +RB15 LCB15 B16 0.266535044422507 +C15 A16 B16 2.50418376625721e-14 +MNA15 B15 A15 0 0 Nmod L=2.5213362488047e-07 W=4.26610931467994e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.53221862935989e-05 PS= ++8.53221862935989e-05 NQSMOD=1 +MPA15 B15 A15 VDD VDD Pmod L=2.44411053097269e-07 W= ++0.000104344399065411 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208688798130821 PS=0.000208688798130821 NQSMOD=1 +MNB15 A15 B15 0 0 Nmod L=2.44947739168727e-07 W=4.18061319080677e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.36122638161354e-05 PS= ++8.36122638161354e-05 NQSMOD=1 +MPB15 A15 B15 VDD VDD Pmod L=2.45133067349567e-07 W= ++0.000103673770597555 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020734754119511 PS=0.00020734754119511 NQSMOD=1 +LA16 A16 LCA16 3.69030941553353e-11 +RA16 LCA16 A17 0.266535044422507 +LB16 B16 LCB16 3.69030941553353e-11 +RB16 LCB16 B17 0.266535044422507 +C16 A17 B17 2.50418376625721e-14 +MNA16 B16 A16 0 0 Nmod L=2.5558903414348e-07 W=4.23651981762607e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.47303963525215e-05 PS= ++8.47303963525215e-05 NQSMOD=1 +MPA16 B16 A16 VDD VDD Pmod L=2.46968507923118e-07 W= ++0.000101577430536373 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203154861072746 PS=0.000203154861072746 NQSMOD=1 +MNB16 A16 B16 0 0 Nmod L=2.52441475326891e-07 W=4.0963445615255e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.192689123051e-05 PS= ++8.192689123051e-05 NQSMOD=1 +MPB16 A16 B16 VDD VDD Pmod L=2.49958772476576e-07 W= ++0.000102341104143712 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204682208287424 PS=0.000204682208287424 NQSMOD=1 +LA17 A17 LCA17 3.69030941553353e-11 +RA17 LCA17 A18 0.266535044422507 +LB17 B17 LCB17 3.69030941553353e-11 +RB17 LCB17 B18 0.266535044422507 +C17 A18 B18 2.50418376625721e-14 +MNA17 B17 A17 0 0 Nmod L=2.46623947628415e-07 W=4.07033737509309e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.14067475018618e-05 PS= ++8.14067475018618e-05 NQSMOD=1 +MPA17 B17 A17 VDD VDD Pmod L=2.52274212428759e-07 W= ++0.000105423152156798 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000210846304313596 PS=0.000210846304313596 NQSMOD=1 +MNB17 A17 B17 0 0 Nmod L=2.51233452024547e-07 W=4.12815452669714e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.25630905339429e-05 PS= ++8.25630905339429e-05 NQSMOD=1 +MPB17 A17 B17 VDD VDD Pmod L=2.49324495416238e-07 W= ++0.000104142717459091 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208285434918183 PS=0.000208285434918183 NQSMOD=1 +LA18 A18 LCA18 3.69030941553353e-11 +RA18 LCA18 A19 0.266535044422507 +LB18 B18 LCB18 3.69030941553353e-11 +RB18 LCB18 B19 0.266535044422507 +C18 A19 B19 2.50418376625721e-14 +MNA18 B18 A18 0 0 Nmod L=2.52038203439398e-07 W=4.17044670825126e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.34089341650252e-05 PS= ++8.34089341650252e-05 NQSMOD=1 +MPA18 B18 A18 VDD VDD Pmod L=2.46465042965348e-07 W= ++0.000102305682920291 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204611365840582 PS=0.000204611365840582 NQSMOD=1 +MNB18 A18 B18 0 0 Nmod L=2.45695550122768e-07 W=4.2510656912981e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.50213138259621e-05 PS= ++8.50213138259621e-05 NQSMOD=1 +MPB18 A18 B18 VDD VDD Pmod L=2.56212134001568e-07 W= ++0.000101696358889307 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203392717778614 PS=0.000203392717778614 NQSMOD=1 +LA19 A19 LCA19 3.69030941553353e-11 +RA19 LCA19 A20 0.266535044422507 +LB19 B19 LCB19 3.69030941553353e-11 +RB19 LCB19 B20 0.266535044422507 +C19 A20 B20 2.50418376625721e-14 +MNA19 B19 A19 0 0 Nmod L=2.46298724559332e-07 W=4.26183323927543e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.52366647855085e-05 PS= ++8.52366647855085e-05 NQSMOD=1 +MPA19 B19 A19 VDD VDD Pmod L=2.53903413760174e-07 W= ++0.000103580270078538 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207160540157077 PS=0.000207160540157077 NQSMOD=1 +MNB19 A19 B19 0 0 Nmod L=2.4541336381424e-07 W=4.1471197163819e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.2942394327638e-05 PS=8.2942394327638e-05 ++NQSMOD=1 +MPB19 A19 B19 VDD VDD Pmod L=2.51953325753565e-07 W= ++0.0001019745929959 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002039491859918 ++PS=0.0002039491859918 NQSMOD=1 +LA20 A20 LCA20 3.69030941553353e-11 +RA20 LCA20 A21 0.266535044422507 +LB20 B20 LCB20 3.69030941553353e-11 +RB20 LCB20 B21 0.266535044422507 +C20 A21 B21 2.50418376625721e-14 +MNA20 B20 A20 0 0 Nmod L=2.55318350883171e-07 W=4.2257523363596e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.4515046727192e-05 PS= ++8.4515046727192e-05 NQSMOD=1 +MPA20 B20 A20 VDD VDD Pmod L=2.50733395598687e-07 W= ++0.000105848300738233 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211696601476467 PS=0.000211696601476467 NQSMOD=1 +MNB20 A20 B20 0 0 Nmod L=2.53961238224852e-07 W=4.07467605160825e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.1493521032165e-05 PS= ++8.1493521032165e-05 NQSMOD=1 +MPB20 A20 B20 VDD VDD Pmod L=2.52173406118976e-07 W= ++0.000104205251139887 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208410502279773 PS=0.000208410502279773 NQSMOD=1 +LA21 A21 LCA21 3.69030941553353e-11 +RA21 LCA21 A22 0.266535044422507 +LB21 B21 LCB21 3.69030941553353e-11 +RB21 LCB21 B22 0.266535044422507 +C21 A22 B22 2.50418376625721e-14 +MNA21 B21 A21 0 0 Nmod L=2.46323292867561e-07 W=4.1601573531982e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.32031470639639e-05 PS= ++8.32031470639639e-05 NQSMOD=1 +MPA21 B21 A21 VDD VDD Pmod L=2.54613442115316e-07 W= ++0.000104931161465525 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020986232293105 PS=0.00020986232293105 NQSMOD=1 +MNB21 A21 B21 0 0 Nmod L=2.55836584454404e-07 W=4.10424160274173e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.20848320548346e-05 PS= ++8.20848320548346e-05 NQSMOD=1 +MPB21 A21 B21 VDD VDD Pmod L=2.54709741956022e-07 W= ++0.000102062091080516 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204124182161031 PS=0.000204124182161031 NQSMOD=1 +LA22 A22 LCA22 3.69030941553353e-11 +RA22 LCA22 A23 0.266535044422507 +LB22 B22 LCB22 3.69030941553353e-11 +RB22 LCB22 B23 0.266535044422507 +C22 A23 B23 2.50418376625721e-14 +MNA22 B22 A22 0 0 Nmod L=2.54430620981417e-07 W=4.19307535657001e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.38615071314001e-05 PS= ++8.38615071314001e-05 NQSMOD=1 +MPA22 B22 A22 VDD VDD Pmod L=2.46694525572975e-07 W= ++0.000103108817734331 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000206217635468663 PS=0.000206217635468663 NQSMOD=1 +MNB22 A22 B22 0 0 Nmod L=2.4991048194413e-07 W=4.12343575509987e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.24687151019974e-05 PS= ++8.24687151019974e-05 NQSMOD=1 +MPB22 A22 B22 VDD VDD Pmod L=2.53435790976082e-07 W= ++0.000105540213369592 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211080426739185 PS=0.000211080426739185 NQSMOD=1 +LA23 A23 LCA23 3.69030941553353e-11 +RA23 LCA23 A24 0.266535044422507 +LB23 B23 LCB23 3.69030941553353e-11 +RB23 LCB23 B24 0.266535044422507 +C23 A24 B24 2.50418376625721e-14 +MNA23 B23 A23 0 0 Nmod L=2.47985427798248e-07 W=4.14939059451511e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29878118903023e-05 PS= ++8.29878118903023e-05 NQSMOD=1 +MPA23 B23 A23 VDD VDD Pmod L=2.50625862917368e-07 W= ++0.000104857443713713 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000209714887427425 PS=0.000209714887427425 NQSMOD=1 +MNB23 A23 B23 0 0 Nmod L=2.48906363214973e-07 W=4.09072154111792e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.18144308223583e-05 PS= ++8.18144308223583e-05 NQSMOD=1 +MPB23 A23 B23 VDD VDD Pmod L=2.544246792556e-07 W= ++0.000106667496188909 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000213334992377817 PS=0.000213334992377817 NQSMOD=1 +RCROSS1 A0 B24 0.001 +RCROSS2 B0 A24 0.001 + +.SAVE VDD0 +.SAVE VSS0 +.SAVE VDD_A0 +.SAVE VSS_A0 +.SAVE VDD_B0 +.SAVE VSS_B0 +.SAVE A0 B0 LA0#branch LB0#branch A1 B1 LA1#branch LB1#branch A2 B2 ++LA2#branch LB2#branch A3 B3 LA3#branch LB3#branch A4 B4 LA4#branch ++LB4#branch A5 B5 LA5#branch LB5#branch A6 B6 LA6#branch LB6#branch ++A7 B7 LA7#branch LB7#branch A8 B8 LA8#branch LB8#branch A9 B9 ++LA9#branch LB9#branch A10 B10 LA10#branch LB10#branch A11 B11 ++LA11#branch LB11#branch A12 B12 LA12#branch LB12#branch A13 B13 ++LA13#branch LB13#branch A14 B14 LA14#branch LB14#branch A15 B15 ++LA15#branch LB15#branch A16 B16 LA16#branch LB16#branch A17 B17 ++LA17#branch LB17#branch A18 B18 LA18#branch LB18#branch A19 B19 ++LA19#branch LB19#branch A20 B20 LA20#branch LB20#branch A21 B21 ++LA21#branch LB21#branch A22 B22 LA22#branch LB22#branch A23 B23 ++LA23#branch LB23#branch + + +** +**INCLUDING FILE: ./proj1/process.models.... +* +* Typical N Typical P - from process corners (taken from tsmc025_corners.bsim3 fron NCSU) +* +* TSMC 0.25u 5M 1P process. 2.5V transistor models + + +.MODEL Nmod NMOS LEVEL=8 ++TNOM = 25 ++VERSION = 3.2.2 TOX = 5.8e-9 ++XJ = 1E-07 NCH = 2.354946E+17 LLN = 1 ++LWN = 1 WLN = 1 WWN = 1 ++LINT = 1.76E-08 WINT = 6.75E-09 MOBMOD = 1 ++BINUNIT = 2 DWG = 0 DWB = 0 ++VTH0 = 0.4321336 LVTH0 = 2.081814E-08 WVTH0 = -5.470342E-11 ++PVTH0 = -6.721795E-16 K1 = 0.3281252 LK1 = 9.238362E-08 ++WK1 = 2.878255E-08 PK1 = -2.426481E-14 K2 = 0.0402824 ++LK2 = -3.208392E-08 WK2 = -1.154091E-08 PK2 = 9.192045E-15 ++K3 = 0 DVT0 = 0 DVT1 = 0 ++DVT2 = 0 DVT0W = 0 DVT1W = 0 ++DVT2W = 0 NLX = 0 W0 = 0 ++K3B = 0 VSAT = 7.586954E+04 LVSAT = 3.094656E-03 ++WVSAT = -1.747416E-03 PVSAT = 8.820956E-10 UA = 8.924498E-10 ++LUA = -1.511745E-16 WUA = -3.509821E-17 PUA = -3.08778E-23 ++UB = 8.928832E-21 LUB = -1.655745E-27 WUB = -2.03282E-27 ++PUB = 3.4578E-34 UC = -1.364265E-11 LUC = 1.170473E-17 ++WUC = -1.256705E-18 PUC = -6.249644E-24 RDSW = 447.8871 ++PRWB = 0 PRWG = 0 WR = 0.99 ++U0 = 0.06005258 LU0 = -6.31976E-09 WU0 = -8.819531E-09 ++PU0 = 3.57209E-15 A0 = -1.468837 LA0 = 6.419548E-07 ++WA0 = 5.512414E-07 PA0 = -9.222928E-14 KETA = -0.04922795 ++LKETA = 2.360844E-08 WKETA = 1.560385E-08 PKETA = -5.98377E-15 ++A1 = 0.02659908 LA1 = -6.511454E-09 A2 = 1 ++AGS = -4.01637 LAGS = 1.090294E-06 WAGS = 1.162021E-06 ++PAGS = -3.108579E-13 B0 = 0 B1 = 0 ++VOFF = -0.1829426 LVOFF = 9.941631E-09 WVOFF = 1.568082E-08 ++PVOFF = -2.832958E-15 NFACTOR = 0.6790636 LNFACTOR= 3.454948E-08 ++WNFACTOR= 1.501016E-07 PNFACTOR= -2.955591E-14 CIT = 2.218499E-04 ++LCIT = -1.076934E-10 WCIT = -3.286884E-10 PCIT = 1.658928E-16 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = 1.215578E-04 LETA0 = -1.037758E-11 WETA0 = -3.030225E-11 ++PETA0 = 1.529658E-17 ETAB = 3.548681E-03 LETAB = -1.791374E-09 ++WETAB = -6.897268E-10 PETAB = 3.481742E-16 DSUB = 0 ++PCLM = 3.583838 PDIBLC1 = 0 PDIBLC2 = 5.379674E-03 ++LPDIBLC2= 7.808481E-09 WPDIBLC2= 5.516945E-10 PPDIBLC2= -2.784957E-16 ++PDIBLCB = -0.1229374 LPDIBLCB= 4.956215E-08 WPDIBLCB= 3.299946E-08 ++PPDIBLCB= -9.624918E-15 DROUT = 0 PSCBE1 = 4.472639E+08 ++LPSCBE1 = 28.64041 WPSCBE1 = 15.7154 PPSCBE1 = -7.933138E-06 ++PSCBE2 = 1.842585E-06 LPSCBE2 = 2.871008E-12 WPSCBE2 = 2.579183E-12 ++PPSCBE2 = -1.301972E-18 PVAG = -2.015254E-03 LPVAG = 1.017757E-09 ++WPVAG = 3.07622E-10 PPVAG = -1.55418E-16 DELTA = -0.02862256 ++LDELTA = 1.492454E-08 WDELTA = -6.71663E-09 PDELTA = 3.407521E-15 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.2579945 ++LKT1 = -1.664895E-08 WKT1 = -1.633463E-08 PKT1 = 3.755864E-15 ++KT2 = -0.05347481 LKT2 = 8.244731E-09 WKT2 = 1.13705E-09 ++PKT2 = -1.240924E-15 AT = -1.132632E+04 LAT = 6.469047E-03 ++WAT = 6.829220E-04 PAT = -4.154249E-10 UTE = -2.309089 ++LUTE = 1.662427E-07 WUTE = 1.244801E-07 PUTE = -5.627924E-14 ++UA1 = -3.461758E-10 LUA1 = 1.747495E-16 WUA1 = -1.42065E-16 ++PUA1 = 7.171442E-23 UB1 = 0 UC1 = -2.38157E-12 ++LUC1 = -2.895726E-18 WUC1 = -1.990052E-17 PUC1 = 1.004497E-23 ++KT1L = 0 PRT = -1E-18 CJ = 2.024128E-3 ++MJ = 0.4960069 PB = 0.9173808 CJSW = 2.751528E-10 ++MJSW = 0.443145 PBSW = 0.9173808 CJSWG = 2.135064E-10 ++MJSWG = 0.443145 PBSWG = 0.9173808 ++RSH = 4.5 ++XTI = 3 ++CGDO = 3.11E-10 CGSO = 3.11E-10 CAPMOD = 2 ++XPART = 1 CF = 0 ++JS = 1E-06 ++JSW = 5E-11 + + + +.MODEL Pmod PMOS LEVEL=8 ++VERSION = 3.2.2 ++TNOM = 25 TOX = 5.8e-9 ++XJ = 1E-7 NCH = 4.1589E17 ++LLN = 1 LWN = 1 WLN = 1 ++WWN = 1 LINT = 1.2365E-8 WINT = 7.8E-9 ++MOBMOD = 1 BINUNIT = 2 DWG = 0 ++DWB = 0 VTH0 = -0.6236538 LVTH0 = 2.649834E-8 ++WVTH0 = 3.214189E-8 PVTH0 = -3.22268E-15 K1 = 0.4198155 ++LK1 = 5.770498E-8 WK1 = 5.577151E-8 PK1 = -2.81684E-14 ++K2 = 0.0429467 LK2 = -2.296405E-8 WK2 = -1.355302E-8 ++PK2 = 6.848271E-15 K3 = 0 DVT0 = 0 ++DVT1 = 0 DVT2 = 0 DVT0W = 0 ++DVT1W = 0 DVT2W = 0 NLX = 0 ++W0 = 0 K3B = 0 VSAT = 1.443912E5 ++LVSAT = -7.688012E-4 WVSAT = -6.083648E-3 PVSAT = 2.186471E-10 ++UA = 1.846811E-9 LUA = -3.27694E-16 WUA = -2.82106E-16 ++PUA = 7.180233E-23 UB = -7.84535E-19 LUB = 4.772849E-25 ++WUB = 2.599205E-25 PUB = -1.46530E-31 UC = -1.75560E-10 ++LUC = 3.360832E-17 WUC = 1.504425E-17 PUC = -1.30556E-23 ++RDSW = 1.03E3 PRWB = 0 PRWG = 0 ++WR = 1 U0 = 0.0136443 LU0 = -7.22084E-10 ++WU0 = -1.088554E-9 PU0 = 2.730854E-16 A0 = 0.1071803 ++LA0 = 4.64252E-7 WA0 = 5.383179E-7 PA0 = -1.32033E-13 ++KETA = -4.943762E-3 LKETA = -3.565304E-9 WKETA = -5.226247E-9 ++PKETA = 2.640665E-15 A1 = 0 A2 = 0.4 ++AGS = 0.1664005 LAGS = 1.19106E-7 WAGS = 5.29237E-8 ++PAGS = -2.67304E-14 B0 = 0 B1 = 0 ++VOFF = -0.0592623 LVOFF = -1.96686E-8 WVOFF = -1.486398E-8 ++PVOFF = 7.510321E-15 NFACTOR = 0.8588103 LNFACTOR= -1.158881E-7 ++WNFACTOR= 1.210664E-8 PNFACTOR= -6.11712E-15 CIT = 6.439495E-5 ++LCIT = 2.916437E-10 WCIT = -3.11284E-11 PCIT = 1.572825E-17 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = -3.819468E-3 LETA0 = 2.155422E-9 WETA0 = 8.235612E-10 ++PETA0 = -4.16037E-16 ETAB = 1.334637E-3 LETAB = -7.93631E-10 ++WETAB = 5.284657E-11 PETAB = -2.68353E-17 DSUB = 0 ++PCLM = 0.1098002 LPCLM = 6.874263E-7 WPCLM = 6.724724E-7 ++PPCLM = -1.97766E-13 PDIBLC1 = 0 PDIBLC2 = 5.801323E-3 ++LPDIBLC2= -1.81964E-9 WPDIBLC2= -5.853396E-9 PPDIBLC2= 2.957545E-15 ++PDIBLCB = 0.1921199 DROUT = 0 PSCBE1 = 7.19E8 ++PSCBE2 = 1E-20 PVAG = 0 DELTA = 0.01 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.3248987 ++LKT1 = -1.160393E-8 WKT1 = 4.153356E-8 PKT1 = -4.62347E-15 ++KT2 = -0.0367632 AT = 1E4 UTE = -1.04 ++UA1 = 3.992421E-10 UB1 = -9.23294E-19 LUB1 = -5.28718E-26 ++WUB1 = -6.13069E-26 PUB1 = 1.503674E-32 UC1 = -1.00699E-12 ++KT1L = 0 PRT = 0 CJ = 1.931092e-3 ++MJ = 0.4812153 PB = 0.9134669 CJSW = 2.232277e-10 ++MJSW = 0.3237595 PBSW = 0.9134669 CJSWG = 1.607088e-10 ++MJSWG = 0.3237595 PBSWG = 0.9134669 ++RSH = 3.5 ++CGDO = 2.68e-10 CGSO = 2.68e-10 ++CAPMOD = 2 ++XPART = 1 ++CF = 0 XTI = 3 ++JS = 3E-7 ++JSW = 5E-12 + +**.... FINISHED INCLUDING: ./proj1/process.models +** +.OPTIONS TEMP=25 +VSLEW_CONTROL VSLEW 0 (PULSE 0 1 0 1e-09) +EVLOGIC VRAMP 0 VSLEW 0 2.5 +VDDPOWER VDD VRAMP DC 0 +VARACTOR_V VARACTOR_V 0 DC 2.5 +.SAVE vddpower#branch +.SAVE vdd +.SAVE varactor_v +.TRAN 0.02n 3000n 0n 0.5n +.END \ No newline at end of file diff --git a/tests/tcl-testbench2/tcl-testbench2.tcl b/tests/tcl-testbench2/tcl-testbench2.tcl new file mode 100644 index 000000000..394b46fe0 --- /dev/null +++ b/tests/tcl-testbench2/tcl-testbench2.tcl @@ -0,0 +1,49 @@ +#!/bin/sh +# WishFix \ + exec wish -f "$0" ${1+"$@"} +### + +package require BLT +load ../../src/.libs/libspice.so +namespace import blt::* + +wm title . "Vector Test script" +wm geometry . 800x600+40+40 +pack propagate . false + +stripchart .chart +pack .chart -side top -fill both -expand true +.chart axis configure x -title "Time" + + +# Create a vector (and call it $vector) +#vector create v1 +spice::source example.cir +spice::bg run + +after 1000 + +vector create a0 +vector create b0 +vector create a1 +vector create b1 +vector create stime +proc bltupdate {} { + puts [spice::spice_data] + spice::spicetoblt a0 a0 + spice::spicetoblt b0 b0 + spice::spicetoblt a1 a1 + spice::spicetoblt b1 b1 + spice::spicetoblt time stime + #puts $spice::lastitercount + after 100 bltupdate +} +bltupdate + + + +.chart element create a0 -color red -xdata stime -ydata a0 +.chart element create b0 -color blue -xdata stime -ydata b0 +.chart element create a1 -color yellow -xdata stime -ydata a1 +.chart element create b1 -color black -xdata stime -ydata b1 + diff --git a/tests/tcl-testbench3/FB14.cir b/tests/tcl-testbench3/FB14.cir new file mode 100644 index 000000000..b7a0b254b --- /dev/null +++ b/tests/tcl-testbench3/FB14.cir @@ -0,0 +1,457 @@ +* gnetlist -g spice-sdb -o tmp.lst FB14_batterie.sch +********************************************************* +* Spice file generated by gnetlist * +* spice-sdb version 12.27.2005 by SDB -- * +* provides advanced spice netlisting capability. * +* Documentation at http://www.brorson.com/gEDA/SPICE/ * +********************************************************* +*vvvvvvvv Included SPICE model from models/tl431.cir vvvvvvvv +* modele du TL431 +.subckt TL431-R REFIN ANODE CATHODE +Q8 Q2_C Q2_C R4_N 0 P1 +Q9 CATHODE Q7_C Q9_E 0 n1 +R8 Q4_E ANODE 800 +R9 Q2_E R9_N 4k +Q10 CATHODE R6_P ANODE 0 n1 5 +Q11 Q7_C R10_P ANODE 0 n1 +*.nodeset R3_N 1 +C2 R9_N C2_N 20p +R10 R10_P R1_N 1k +C1 CATHODE Q7_C 20p +D1 ANODE Q7_C DIODE +D2 ANODE CATHODE DIODE +R4 CATHODE R4_N 800 +Q2 Q2_C Q1_E Q2_E 0 n1 +Q3 R9_N C2_N ANODE 0 n1 +R5 CATHODE R5_N 800 +R6 R6_P Q9_E 150 +Q1 CATHODE REFIN Q1_E 0 n1 +R7 ANODE R6_P 10k +Q6 Q7_C Q7_C REFIN 0 n1 +Q7 Q7_C Q2_C R5_N 0 P1 +R1 R3_N R1_N 2.4k +R2 R3_N C2_N 7.2k +Q4 C2_N R1_N Q4_E 0 n1 +Q5 R1_N R1_N ANODE 0 n1 +R3 Q1_E R3_N 3.28k +.model p1 pnp bf=50 +.model n1 npn bf=100 tf=2n cjc=1p is=5e-18 NF=1.07 +.model diode d rs=1 cjo=2p +.ends +*^^^^^^^^ End of included SPICE model from models/tl431.cir ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/irf4905.spi vvvvvvvv +.SUBCKT irf4905 1 2 3 +************************************** +* Model Generated by MODPEX * +*Copyright(c) Symmetry Design Systems* +* All Rights Reserved * +* UNPUBLISHED LICENSED SOFTWARE * +* Contains Proprietary Information * +* Which is The Property of * +* SYMMETRY OR ITS LICENSORS * +*Commercial Use or Resale Restricted * +* by Symmetry License Agreement * +************************************** +* Model generated on Jun 19, 96 +* Model format: SPICE3 +* Symmetry POWER MOS Model (Version 1.0) +* External Node Designations +* Node 1 -> Drain +* Node 2 -> Gate +* Node 3 -> Source +M1 9 7 8 8 MM L=100u W=100u +* Default values used in MM: +* The voltage-dependent capacitances are +* not included. Other default values are: +* RS=0 RD=0 LD=0 CBD=0 CBS=0 CGBO=0 +.MODEL MM PMOS LEVEL=1 IS=1e-32 ++VTO=-3.53713 LAMBDA=0.00549383 KP=23.3701 ++CGSO=2.84439e-05 CGDO=1e-11 +RS 8 3 0.0101265 +D1 1 3 MD +.MODEL MD D IS=1.29014e-08 RS=0.00297795 N=1.46717 BV=55 ++IBV=0.00025 EG=1.2 XTI=4 TT=0 ++CJO=3.56968e-09 VJ=1.17553 M=0.500933 FC=0.5 +RDS 3 1 2.2e+06 +RD 9 1 0.0001 +RG 2 7 6 +D2 5 4 MD1 +* Default values used in MD1: +* RS=0 EG=1.11 XTI=3.0 TT=0 +* BV=infinite IBV=1mA +.MODEL MD1 D IS=1e-32 N=50 ++CJO=4.83772e-09 VJ=0.625334 M=0.543532 FC=1e-08 +D3 5 0 MD2 +* Default values used in MD2: +* EG=1.11 XTI=3.0 TT=0 CJO=0 +* BV=infinite IBV=1mA +.MODEL MD2 D IS=1e-10 N=0.4 RS=3e-06 +RL 5 10 1 +FI2 7 9 VFI2 -1 +VFI2 4 0 0 +EV16 10 0 9 7 1 +CAP 11 10 6.08035e-09 +FI1 7 9 VFI1 -1 +VFI1 11 6 0 +RCAP 6 10 1 +D4 6 0 MD3 +* Default values used in MD3: +* EG=1.11 XTI=3.0 TT=0 CJO=0 +* RS=0 BV=infinite IBV=1mA +.MODEL MD3 D IS=1e-10 N=0.4 +.ENDS + +*^^^^^^^^ End of included SPICE model from models/irf4905.spi ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/LM2902.MOD vvvvvvvv +*////////////////////////////////////////////////////////////////////// +* (C) National Semiconductor, Inc. +* Models developed and under copyright by: +* National Semiconductor, Inc. + +*///////////////////////////////////////////////////////////////////// +* Legal Notice: This material is intended for free software support. +* The file may be copied, and distributed; however, reselling the +* material is illegal + +*//////////////////////////////////////////////////////////////////// +* For ordering or technical information on these models, contact: +* National Semiconductor's Customer Response Center +* 7:00 A.M.--7:00 P.M. U.S. Central Time +* (800) 272-9959 +* For Applications support, contact the Internet address: +* amps-apps@galaxy.nsc.com + +*////////////////////////////////////////////////////////// +*LM2902 QUAD OPERATIONAL AMPLIFIER MACRO-MODEL +*////////////////////////////////////////////////////////// +* +* connections: non-inverting input +* | inverting input +* | | positive power supply +* | | | negative power supply +* | | | | output +* | | | | | +* | | | | | +.SUBCKT LM2902/NS 1 2 99 50 28 +* +*Features: +*Eliminates need for dual supplies +*Large DC voltage gain = 100dB +*High bandwidth = 1MHz +*Low input offset voltage = 2mV +*Wide supply range = +-1.5V to +-16V +* +*NOTE: Model is for single device only and simulated +* supply current is 1/4 of total device current. +* Output crossover distortion with dual supplies +* is not modeled. +* +****************INPUT STAGE************** +* +IOS 2 1 5N +*^Input offset current +R1 1 3 500K +R2 3 2 500K +I1 99 4 100U +R3 5 50 517 +R4 6 50 517 +Q1 5 2 4 QX +Q2 6 7 4 QX +*Fp2=1.2 MHz +C4 5 6 128.27P +* +***********COMMON MODE EFFECT*********** +* +I2 99 50 75U +*^Quiescent supply current +EOS 7 1 POLY(1) 16 49 2E-3 1 +*Input offset voltage.^ +R8 99 49 60K +R9 49 50 60K +* +*********OUTPUT VOLTAGE LIMITING******** +V2 99 8 1.63 +D1 9 8 DX +D2 10 9 DX +V3 10 50 .635 +* +**************SECOND STAGE************** +* +EH 99 98 99 49 1 +G1 98 9 POLY(1) 5 6 0 9.8772E-4 0 .3459 +*Fp1=7.86 Hz +R5 98 9 101.2433MEG +C3 98 9 200P +* +***************POLE STAGE*************** +* +*Fp=2 MHz +G3 98 15 9 49 1E-6 +R12 98 15 1MEG +C5 98 15 7.9577E-14 +* +*********COMMON-MODE ZERO STAGE********* +* +*Fpcm=10 KHz +G4 98 16 3 49 5.6234E-8 +L2 98 17 15.9M +R13 17 16 1K +* +**************OUTPUT STAGE************** +* +F6 50 99 POLY(1) V6 300U 1 +E1 99 23 99 15 1 +R16 24 23 17.5 +D5 26 24 DX +V6 26 22 .63V +R17 23 25 17.5 +D6 25 27 DX +V7 22 27 .63V +V5 22 21 0.27V +D4 21 15 DX +V4 20 22 0.27V +D3 15 20 DX +L3 22 28 500P +RL3 22 28 100K +* +***************MODELS USED************** +* +.MODEL DX D(IS=1E-15) +.MODEL QX PNP(BF=1.111E3) +* +.ENDS +*$ +*^^^^^^^^ End of included SPICE model from models/LM2902.MOD ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/bas70.mod vvvvvvvv +* +.SUBCKT BAS70 1 3 +* The Resistor R1 does not reflect +* a physical device. Instead it +* improves modeling in the reverse +* mode of operation. +R1 1 3 1.409E+09 +D1 1 3 modBAS70 +.MODEL modBAS70 D( ++ IS = 3.22E-09 ++ N = 1.018 ++ BV = 77 ++ IBV = 1.67E-07 ++ RS = 20.89 ++ CJO = 1.655E-12 ++ VJ = 0.349 ++ M = 0.3583 ++ FC = 0.5 ++ TT = 0 ++ EG = 0.69 ++ XTI = 2) +.ENDS +* +*^^^^^^^^ End of included SPICE model from models/bas70.mod ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/BC547B.spi vvvvvvvv +* +.MODEL QBC547B NPN( ++ IS=2.39E-14 ++ NF=1.008 ++ ISE=3.545E-15 ++ NE=1.541 ++ BF=294.3 ++ IKF=0.1357 ++ VAF=63.2 ++ NR=1.004 ++ ISC=6.272E-14 ++ NC=1.243 ++ BR=7.946 ++ IKR=0.1144 ++ VAR=25.9 ++ RB=1 ++ IRB=1E-06 ++ RBM=1 ++ RE=0.4683 ++ RC=0.85 ++ XTB=0 ++ EG=1.11 ++ XTI=3 ++ CJE=1.358E-11 ++ VJE=0.65 ++ MJE=0.3279 ++ TF=4.391E-10 ++ XTF=120 ++ VTF=2.643 ++ ITF=0.7495 ++ PTF=0 ++ CJC=3.728E-12 ++ VJC=0.3997 ++ MJC=0.2955 ++ XCJC=0.6193 ++ TR=1E-32 ++ CJS=0 ++ VJS=0.75 ++ MJS=0.333 ++ FC=0.9579 ) +* +*^^^^^^^^ End of included SPICE model from models/BC547B.spi ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/LM293.5_1 vvvvvvvv +* LM293 VOLTAGE COMPARATOR "MACROMODEL" SUBCIRCUIT +* CREATED USING PARTS VERSION 4.03 ON 03/07/90 AT 14:17 +* REV (N/A) +* CONNECTIONS: NON-INVERTING INPUT +* | INVERTING INPUT +* | | POSITIVE POWER SUPPLY +* | | | NEGATIVE POWER SUPPLY +* | | | | OPEN COLLECTOR OUTPUT +* | | | | | +.SUBCKT LM293 1 2 3 4 5 +* + F1 9 3 V1 1 + IEE 3 7 DC 100.0E-6 + VI1 21 1 DC .75 + VI2 22 2 DC .75 + Q1 9 21 7 QIN + Q2 8 22 7 QIN + Q3 9 8 4 QMO + Q4 8 8 4 QMI +.MODEL QIN PNP(IS=800.0E-18 BF=2.000E3) +.MODEL QMI NPN(IS=800.0E-18 BF=1002) +.MODEL QMO NPN(IS=800.0E-18 BF=1000 CJC=1E-15 TR=807.4E-9) + E1 10 4 9 4 1 + V1 10 11 DC 0 + Q5 5 11 4 QOC +.MODEL QOC NPN(IS=800.0E-18 BF=20.29E3 CJC=1E-15 TF=942.6E-12 TR=543.8E-9) + DP 4 3 modDX + RP 3 4 46.3E3 +.MODEL modDX D(IS=800.0E-18) +* +.ENDS + +*^^^^^^^^ End of included SPICE model from models/LM293.5_1 ^^^^^^^^ +* +*vvvvvvvv Included SPICE model from models/NTD18N06L.REV0.SP3 vvvvvvvv +.SUBCKT ntd18n06l 1 2 3 +************************************** +* Model Generated by MODPEX * +*Copyright(c) Symmetry Design Systems* +* All Rights Reserved * +* UNPUBLISHED LICENSED SOFTWARE * +* Contains Proprietary Information * +* Which is The Property of * +* SYMMETRY OR ITS LICENSORS * +*Commercial Use or Resale Restricted * +* by Symmetry License Agreement * +************************************** +* Model generated on Aug 3, 04 +* MODEL FORMAT: SPICE3 +* Symmetry POWER MOS Model (Version 1.0) +* External Node Designations +* Node 1 -> Drain +* Node 2 -> Gate +* Node 3 -> Source +M1 9 7 8 8 MM L=100u W=100u +* Default values used in MM: +* The voltage-dependent capacitances are +* not included. Other default values are: +* RS=0 RD=0 LD=0 CBD=0 CBS=0 CGBO=0 +.MODEL MM NMOS LEVEL=1 IS=1e-32 ++VTO=1.98948 LAMBDA=0 KP=21.272 ++CGSO=4.18085e-06 CGDO=8.56633e-08 +RS 8 3 0.0375073 +D1 3 1 MD +.MODEL MD D IS=8.82716e-09 RS=0.00616994 N=1.5 BV=60 ++IBV=0.00025 EG=1 XTI=2.2423 TT=0 ++CJO=5.77207e-10 VJ=0.656334 M=0.448458 FC=0.5 +RDS 3 1 2.4e+11 +RD 9 1 0.0001 +RG 2 7 17.1584 +D2 4 5 MD1 +* Default values used in MD1: +* RS=0 EG=1.11 XTI=3.0 TT=0 +* BV=infinite IBV=1mA +.MODEL MD1 D IS=1e-32 N=50 ++CJO=6.54462e-10 VJ=1.69471 M=0.891807 FC=1e-08 +D3 0 5 MD2 +* Default values used in MD2: +* EG=1.11 XTI=3.0 TT=0 CJO=0 +* BV=infinite IBV=1mA +.MODEL MD2 D IS=1e-10 N=0.400114 RS=3e-06 +RL 5 10 1 +FI2 7 9 VFI2 -1 +VFI2 4 0 0 +EV16 10 0 9 7 1 +CAP 11 10 6.54462e-10 +FI1 7 9 VFI1 -1 +VFI1 11 6 0 +RCAP 6 10 1 +D4 0 6 MD3 +* Default values used in MD3: +* EG=1.11 XTI=3.0 TT=0 CJO=0 +* RS=0 BV=infinite IBV=1mA +.MODEL MD3 D IS=1e-10 N=0.400114 +.ENDS ntd18n06l + +*^^^^^^^^ End of included SPICE model from models/NTD18N06L.REV0.SP3 ^^^^^^^^ +* +*============== Begin SPICE netlist of main design ============ +X10 iimage vertsup Vcc 0 ledverte LM293 +R20 vmbatm 1 10k +*.INCLUDE models/NTD18N06L.REV0.SP3 +*.INCLUDE models/LM293.5_1 +R33 Imbat V9p 100 +*.INCLUDE models/BC547B.spi +R32 V9p 0 10k +*.INCLUDE models/bas70.mod +R31 ledverte Vcc 22k +*.INCLUDE models/LM2902.MOD +R30 ledrouge Vcc 22k +*.INCLUDE models/irf4905.spi +*.INCLUDE models/tl431.cir +Vbat 2 vmbatm DC 9V +V3 3 0 DC 6V +R? 0 Vcc 2.2k +R19 vmbat Vs2 22k +V1 Vcc 0 DC 26V +R18 Vs2 Vcc 2.2k +R17 vref2 0 430 +R16 v7m Vs2 100k +X9 V9p V9m Vcc 0 Iimage LM2902/NS +R15 iimage v7m 100 +R14 vmbat imbat 0.1 +X8 vcc 1 BAS70 +R9 Vcc vref1 2.2k +R29 0 vertsup 1K +X7 vref2 v7m Vcc 0 Vs2 LM293 +R8 V2p Vs2 100k +R13 Vcc vref_temp 2.2k +R28 vertsup ledrouge 22k +X6 Vcc Vs2 imbat ntd18n06l +R7 V2p Vimage 1k +R12 0 Vtest_temp 6.05k +R27 rougesup rougeinf 20k +X5 0 1 vmbatm ntd18n06l +R6 vref2 Vtest1 660 +R11 Vtest_temp vref_temp 10k +R26 0 rougeinf 2.2k +R10 Vtest_temp vref_temp 9.387k +X4 Vtest1 0 vref1 TL431-R +R5 Vtest1 vref1 2.83k +R25 3 rougesup 2.2k +X3 Vtest_temp 0 vref_temp TL431-R +R4 0 v1p 22k +Vvcc cmd_buck 0 DC 0V +R24 V9m Iimage 10k +X2 vref_temp V2p Vcc 0 Vs2 LM293 +R3 V1m Vimage 22k +X13 ledrouge 4 BAS70 +R23 Vmbat V9m 100 +X1 v1p V1m Vcc 0 Vimage LM2902/NS +R2 vref1 V1m 22k +Rbat 2 vmbat 100 +X12 vimage rougeinf Vcc 0 4 LM293 +R22 Vmbatm V1m 22k +R1 vmbat v1p 22k +X11 rougesup vimage Vcc 0 4 LM293 +R21 0 v1p 22k +.end diff --git a/tests/tcl-testbench3/differentiate.tcl b/tests/tcl-testbench3/differentiate.tcl new file mode 100644 index 000000000..2356cd1de --- /dev/null +++ b/tests/tcl-testbench3/differentiate.tcl @@ -0,0 +1,201 @@ +# differentiate.tcl -- +# Numerical differentiation +# + +namespace eval ::math::calculus { +} +namespace eval ::math::optimize { +} + +# deriv -- +# Return the derivative of a function at a given point +# Arguments: +# func Name of a procedure implementing the function +# point Coordinates of the point +# scale (Optional) the scale of the coordinates +# Result: +# List representing the gradient vector at the given point +# Note: +# The scale is necessary to create a proper step in the +# coordinates. The derivative is estimated using central +# differences. +# The function may have an arbitrary number of arguments, +# for each the derivative is determined - this results +# in a list of derivatives rather than a single value. +# (No provision is made for the function to be a +# vector function! So, second derivatives are not +# possible) +# +proc ::math::calculus::deriv {func point {scale {}} } { + + set epsilon 1.0e-12 + set eps2 [expr {sqrt($epsilon)}] + + # + # Determine a scale + # + foreach c $point { + if { $scale == {} } { + set scale [expr {abs($c)}] + } else { + if { $scale < abs($c) } { + set scale [expr {abs($c)}] + } + } + } + if { $scale == 0.0 } { + set scale 1.0 + } + + # + # Check the number of coordinates + # + if { [llength $point] == 1 } { + set v1 [$func [expr {$point+$eps2*$scale}]] + set v2 [$func [expr {$point-$eps2*$scale}]] + return [expr {($v1-$v2)/(2.0*$eps2*$scale)}] + } else { + set result {} + set idx 0 + foreach c $point { + set c1 [expr {$c+$eps2*$scale}] + set c2 [expr {$c-$eps2*$scale}] + + set v1 [eval $func [lreplace $point $idx $idx $c1]] + set v2 [eval $func [lreplace $point $idx $idx $c2]] + + lappend result [expr {($v1-$v2)/(2.0*$eps2*$scale)}] + incr idx + } + return $result + } +} + +# auxiliary functions -- +# +proc ::math::optimize::unitVector {vector} { + set length 0.0 + foreach c $vector { + set length [expr {$length+$c*$c}] + } + scaleVector $vector [expr {1.0/sqrt($length)}] +} +proc ::math::optimize::scaleVector {vector scale} { + set result {} + foreach c $vector { + lappend result [expr {$c*$scale}] + } + return $result +} +proc ::math::optimize::addVector {vector1 vector2} { + set result {} + foreach c1 $vector1 c2 $vector2 { + lappend result [expr {$c1+$c2}] + } + return $result +} + +# minimumSteepestDescent -- +# Find the minimum of a function via steepest descent +# (unconstrained!) +# Arguments: +# func Name of a procedure implementing the function +# point Coordinates of the starting point +# eps (Optional) measure for the accuracy +# maxsteps (Optional) maximum number of steps +# Result: +# Coordinates of a point near the minimum +# +proc ::math::optimize::minimumSteepestDescent {func point {eps 1.0e-5} {maxsteps 100} } { + + set factor 100 + set nosteps 0 + if { [llength $point] == 1 } { + while { $nosteps < $maxsteps } { + set fvalue [$func $point] + set gradient [::math::calculus::deriv $func $point] + if { $gradient < 0.0 } { + set gradient -1.0 + } else { + set gradient 1.0 + } + set found 0 + set substeps 0 + while { $found == 0 && $substeps < 3 } { + set newpoint [expr {$point-$factor*$gradient}] + set newfval [$func $newpoint] + + #puts "factor: $factor - point: $point" + # + # Check that the new point has a lower value for the + # function. Can we increase the factor? + # + # + if { $newfval < $fvalue } { + set point $newpoint + +# +# This failed with sin(x), x0 = 1.0 +# set newpoint2 [expr {$newpoint-$factor*$gradient}] +# set newfval2 [$func $newpoint2] +# if { $newfval2 < $newfval } { +# set factor [expr {2.0*$factor}] +# set point $newpoint2 +# } + set found 1 + } else { + set factor [expr {$factor/2.0}] + } + + incr substeps + } + + # + # Have we reached convergence? + # + if { abs($factor*$gradient) < $eps } { + break + } + incr nosteps + } + } else { + while { $nosteps < $maxsteps } { + set fvalue [eval $func $point] + set gradient [::math::calculus::deriv $func $point] + set gradient [unitVector $gradient] + + set found 0 + set substeps 0 + while { $found == 0 && $nosteps < $maxsteps } { + set newpoint [addVector $point [scaleVector $gradient -$factor]] + set newfval [eval $func $newpoint] + + #puts "factor: $factor - point: $point" + # + # Check that the new point has a lower value for the + # function. Can we increase the factor? + # + # + if { $newfval < $fvalue } { + set point $newpoint + set found 1 + } else { + set factor [expr {$factor/2.0}] + } + + incr nosteps + } + + # + # Have we reached convergence? + # + if { abs($factor) < $eps } { + break + } + incr nosteps + } + } + + return $point +} + diff --git a/tests/tcl-testbench3/tcl-testbench3.tcl b/tests/tcl-testbench3/tcl-testbench3.tcl new file mode 100644 index 000000000..8ade99d79 --- /dev/null +++ b/tests/tcl-testbench3/tcl-testbench3.tcl @@ -0,0 +1,126 @@ +#!/bin/sh +# WishFix \ + exec wish -f "$0" ${1+"$@"} + ### + +package require BLT +load ../../src/.libs/libspice.so +source differentiate.tcl +spice::codemodel ../../src/xspice/icm/spice2poly/spice2poly.cm +proc temperatures_calc {temp_inf temp_sup points} { + set tstep [ expr " ( $temp_sup - $temp_inf ) / $points " ] + set t $temp_inf + set temperatures "" + for { set i 0 } { $i < $points } { incr i } { + set t [ expr { $t + $tstep } ] + set temperatures "$temperatures $t" + } + return $temperatures +} + +proc thermistance_calc { res B points } { + set tzero 273.15 + set tref 25 + set thermistance "" + foreach t $points { + set res_temp [expr " $res * exp ( $B * ( 1 / ($tzero + $t) - 1 / ( $tzero + $tref ) ) ) " ] + set thermistance "$thermistance $res_temp" + } + return $thermistance +} + +proc tref_calc { points } { + set tref "" + foreach t $points { + set tref " $tref [ expr " 6 * (2.275-0.005*($t - 20) ) - 9 " ] " + } + return $tref +} + +proc iteration { t } { + set tzero 273.15 + spice::alter r11 = [ thermistance_calc 10000 3900 $t ] + #spice::set temp = [ expr " $tzero + $t " ] + spice::op + spice::vectoblt vref_temp tref_tmp + spice::destroy all + return [ tref_tmp range 0 0 ] +} + +proc cost_square { r10 r12 } { + tref_blt length 0 + + spice::alter r10 = $r10 + spice::alter r12 = $r12 + + foreach point [ temperatures_blt range 0 [ expr " [temperatures_blt length ] - 1" ] ] { + tref_blt append [ iteration $point ] + } + + set result [ blt::vector expr " sum(( tref_blt - expected_blt )^2 )" ] + puts "result square : r10 = $r10 r12 = $r12 gives $result" + + return $result +} + +proc cost_sup { r10 r12 } { + tref_blt length 0 + + spice::alter r10 = $r10 + spice::alter r12 = $r12 + + foreach point [ temperatures_blt range 0 [ expr " [temperatures_blt length ] - 1" ] ] { + tref_blt append [ iteration $point ] + } + + set result [ blt::vector expr " max(sqrt(( tref_blt - expected_blt )^2 ))" ] + puts "result sup : $result" + puts "result sup : r10 = $r10 r12 = $r12 gives $result" + + return $result +} + +proc disp_curve { r10 r12 } { +.g configure -title "Valeurs optimales: R10 = $r10 R12 = $r12" +} + +# +# Optimisation +# + +blt::vector create tref_tmp +blt::vector create tref_blt +blt::vector create expected_blt +blt::vector create temperatures_blt +temperatures_blt append [ temperatures_calc -25 75 30 ] +expected_blt append [ tref_calc [temperatures_blt range 0 [ expr " [ temperatures_blt length ] - 1" ] ] ] +blt::graph .g +pack .g -side top -fill both -expand true +.g element create real -pixels 4 -xdata temperatures_blt -ydata tref_blt +.g element create expected -fill red -pixels 0 -dashes dot -xdata temperatures_blt -ydata expected_blt + +spice::source FB14.cir +# point1 max iteration is the last argument +set r10r12 [ ::math::optimize::minimumSteepestDescent cost_square { 10000 10000 } 1.9 20 ] +puts "$r10r12 " +regexp {([0-9.]*) ([0-9.]*)} $r10r12 r10r12 r10 r12 +puts "result square with : r10 = $r10 r12 = $r12 " +set r10r12 [ ::math::optimize::minimumSteepestDescent cost_sup " $r10 $r12 " 0.05 20 ] +puts "$r10r12 " +regexp {([0-9.]*) ([0-9.]*)} $r10r12 r10r12 r10 r12 +puts "result sup with : r10 = $r10 r12 = $r12 " + + +# +# Results +# + + +spice::alter r10 = $r10 +spice::alter r12 = $r12 +foreach point [ temperatures_blt range 0 [ expr " [temperatures_blt length ] - 1" ] ] { + tref_blt append [ iteration $point ] +} +disp_curve $r10 $r12 + + diff --git a/tests/tcl-testbench4/bltGraph.tcl b/tests/tcl-testbench4/bltGraph.tcl new file mode 100644 index 000000000..07eb942f9 --- /dev/null +++ b/tests/tcl-testbench4/bltGraph.tcl @@ -0,0 +1,486 @@ + +proc Blt_ActiveLegend { graph } { + $graph legend bind all [list blt::ActivateLegend $graph ] + $graph legend bind all [list blt::DeactivateLegend $graph] + $graph legend bind all [list blt::HighlightLegend $graph] +} + +proc Blt_Crosshairs { graph } { + blt::Crosshairs $graph +} + +proc Blt_ZoomStack { graph } { + blt::ZoomStack $graph +} + +proc Blt_PrintKey { graph } { + blt::PrintKey $graph +} + +proc Blt_ClosestPoint { graph } { + blt::ClosestPoint $graph +} + +# +# The following procedures that reside in the "blt" namespace are +# supposed to be private. +# + +proc blt::ActivateLegend { graph } { + set elem [$graph legend get current] + $graph legend activate $elem +} +proc blt::DeactivateLegend { graph } { + set elem [$graph legend get current] + $graph legend deactivate $elem +} + +proc blt::HighlightLegend { graph } { + set elem [$graph legend get current] + set relief [$graph element cget $elem -labelrelief] + if { $relief == "flat" } { + $graph element configure $elem -labelrelief raised + $graph element activate $elem + } else { + $graph element configure $elem -labelrelief flat + $graph element deactivate $elem + } +} + +proc blt::Crosshairs { graph { event "Any-Motion" } } { + $graph crosshairs on + bind bltCrosshairs <$event> { + %W crosshairs configure -position @%x,%y + } + $graph crosshairs configure -color red + blt::AddBindTag $graph bltCrosshairs +} + +proc blt::InitStack { graph } { + global zoomInfo + set zoomInfo($graph,interval) 100 + set zoomInfo($graph,afterId) 0 + set zoomInfo($graph,A,x) {} + set zoomInfo($graph,A,y) {} + set zoomInfo($graph,B,x) {} + set zoomInfo($graph,B,y) {} + set zoomInfo($graph,stack) {} + set zoomInfo($graph,corner) A +} + +proc blt::ZoomStack { graph {start "ButtonPress-1"} {reset "ButtonPress-3"} } { + global zoomInfo zoomMod + + blt::InitStack $graph + + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "" + } + bind bltZoomGraph <${modifier}${start}> { blt::SetZoomPoint %W %x %y } + bind bltZoomGraph <${modifier}${reset}> { + if { [%W inside %x %y] } { + blt::ResetZoom %W + } + } + blt::AddBindTag $graph bltZoomGraph +} + +proc blt::PrintKey { graph {event "Shift-ButtonRelease-3"} } { + bind bltPrintGraph <$event> { Blt_PostScriptDialog %W } + blt::AddBindTag $graph bltPrintGraph +} + +proc blt::ClosestPoint { graph {event "Control-ButtonPress-2"} } { + bind bltClosestPoint <$event> { + blt::FindElement %W %x %y + } + blt::AddBindTag $graph bltClosestPoint +} + +proc blt::AddBindTag { graph name } { + set oldtags [bindtags $graph] + if { [lsearch $oldtags $name] < 0 } { + bindtags $graph [concat $name $oldtags] + } +} + +proc blt::FindElement { graph x y } { + if ![$graph element closest $x $y info -interpolate yes] { + beep + return + } + # -------------------------------------------------------------- + # find(name) - element Id + # find(index) - index of closest point + # find(x) find(y) - coordinates of closest point + # or closest point on line segment. + # find(dist) - distance from sample coordinate + # -------------------------------------------------------------- + set markerName "bltClosest_$info(name)" + catch { $graph marker delete $markerName } + $graph marker create text -coords { $info(x) $info(y) } \ + -name $markerName \ + -text "$info(name): $info(dist)\nindex $info(index)" \ + -font *lucida*-r-*-10-* \ + -anchor center -justify left \ + -yoffset 0 -bg {} + + set coords [$graph invtransform $x $y] + set nx [lindex $coords 0] + set ny [lindex $coords 1] + + $graph marker create line -coords "$nx $ny $info(x) $info(y)" \ + -name line.$markerName + + blt::FlashPoint $graph $info(name) $info(index) 10 + blt::FlashPoint $graph $info(name) [expr $info(index) + 1] 10 +} + +proc blt::FlashPoint { graph name index count } { + if { $count & 1 } { + $graph element deactivate $name + } else { + $graph element activate $name $index + } + incr count -1 + if { $count > 0 } { + after 200 blt::FlashPoint $graph $name $index $count + update + } else { + eval $graph marker delete [$graph marker names "bltClosest_*"] + } +} + +proc blt::GetCoords { graph x y index } { + global zoomInfo + if { [$graph cget -invertxy] } { + set zoomInfo($graph,$index,x) $y + set zoomInfo($graph,$index,y) $x + } else { + set zoomInfo($graph,$index,x) $x + set zoomInfo($graph,$index,y) $y + } +} + +proc blt::MarkPoint { graph index } { + global zoomInfo + set x [$graph xaxis invtransform $zoomInfo($graph,$index,x)] + set y [$graph yaxis invtransform $zoomInfo($graph,$index,y)] + set marker "zoomText_$index" + set text [format "x=%.4g\ny=%.4g" $x $y] + + if [$graph marker exists $marker] { + $graph marker configure $marker -coords { $x $y } -text $text + } else { + $graph marker create text -coords { $x $y } -name $marker \ + -font *lucida*-r-*-10-* \ + -text $text -anchor center -bg {} -justify left + } +} + +proc blt::DestroyZoomTitle { graph } { + global zoomInfo + + if { $zoomInfo($graph,corner) == "A" } { + catch { $graph marker delete "zoomTitle" } + } +} + +proc blt::PopZoom { graph } { + global zoomInfo + + set zoomStack $zoomInfo($graph,stack) + if { [llength $zoomStack] > 0 } { + set cmd [lindex $zoomStack 0] + set zoomInfo($graph,stack) [lrange $zoomStack 1 end] + eval $cmd + blt::ZoomTitleLast $graph + busy hold $graph + update + after 2000 "blt::DestroyZoomTitle $graph" + busy release $graph + } else { + catch { $graph marker delete "zoomTitle" } + } +} + +# Push the old axis limits on the stack and set the new ones + +proc blt::PushZoom { graph } { + global zoomInfo + eval $graph marker delete [$graph marker names "zoom*"] + if { [info exists zoomInfo($graph,afterId)] } { + after cancel $zoomInfo($graph,afterId) + } + set x1 $zoomInfo($graph,A,x) + set y1 $zoomInfo($graph,A,y) + set x2 $zoomInfo($graph,B,x) + set y2 $zoomInfo($graph,B,y) + + if { ($x1 == $x2) || ($y1 == $y2) } { + # No delta, revert to start + return + } + set cmd {} + foreach margin { xaxis yaxis x2axis y2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis cget $axis -min] + set max [$graph axis cget $axis -max] + set c [list $graph axis configure $axis -min $min -max $max] + append cmd "$c\n" + } + } + set zoomInfo($graph,stack) [linsert $zoomInfo($graph,stack) 0 $cmd] + + busy hold $graph + # This update lets the busy cursor take effect. + update + + foreach margin { xaxis x2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis invtransform $axis $x1] + set max [$graph axis invtransform $axis $x2] + if { $min!=$max } { + if { $min > $max } { + $graph axis configure $axis -min $max -max $min + } else { + $graph axis configure $axis -min $min -max $max + } + } + } + } + foreach margin { yaxis y2axis } { + foreach axis [$graph $margin use] { + set min [$graph axis invtransform $axis $y1] + set max [$graph axis invtransform $axis $y2] + if { $min!=$max } { + if { $min > $max } { + $graph axis configure $axis -min $max -max $min + } else { + $graph axis configure $axis -min $min -max $max + } + } + } + } + # This "update" forces the graph to be redrawn + update + + busy release $graph +} + +# +# This routine terminates either an existing zoom, or pops back to +# the previous zoom level (if no zoom is in progress). +# + +proc blt::ResetZoom { graph } { + global zoomInfo + + if { ![info exists zoomInfo($graph,corner)] } { + blt::InitStack $graph + } + eval $graph marker delete [$graph marker names "zoom*"] + + if { $zoomInfo($graph,corner) == "A" } { + # Reset the whole axis + blt::PopZoom $graph + } else { + global zoomMod + + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "Any-" + } + set zoomInfo($graph,corner) A + bind $graph <${modifier}Motion> { } + } +} + +option add *zoomTitle.font -*-helvetica-medium-R-*-*-18-*-*-*-*-*-*-* +option add *zoomTitle.shadow yellow4 +option add *zoomTitle.foreground yellow1 +option add *zoomTitle.coords "-Inf Inf" + +proc blt::ZoomTitleNext { graph } { + global zoomInfo + set level [expr [llength $zoomInfo($graph,stack)] + 1] + if { [$graph cget -invertxy] } { + set coords "-Inf -Inf" + } else { + set coords "-Inf Inf" + } + $graph marker create text -name "zoomTitle" -text "Zoom #$level" \ + -coords $coords -bindtags "" -anchor nw +} + +proc blt::ZoomTitleLast { graph } { + global zoomInfo + + set level [llength $zoomInfo($graph,stack)] + if { $level > 0 } { + $graph marker create text -name "zoomTitle" -anchor nw \ + -text "Zoom #$level" + } +} + +proc blt::SetZoomPoint { graph x y } { + global zoomInfo zoomMod + if { ![info exists zoomInfo($graph,corner)] } { + blt::InitStack $graph + } + blt::GetCoords $graph $x $y $zoomInfo($graph,corner) + if { [info exists zoomMod] } { + set modifier $zoomMod + } else { + set modifier "Any-" + } + if { $zoomInfo($graph,corner) == "A" } { + if { ![$graph inside $x $y] } { + return + } + # First corner selected, start watching motion events + + #blt::MarkPoint $graph A + blt::ZoomTitleNext $graph + + bind $graph <${modifier}Motion> { + blt::GetCoords %W %x %y B + #blt::MarkPoint $graph B + blt::Box %W + } + set zoomInfo($graph,corner) B + } else { + # Delete the modal binding + bind $graph <${modifier}Motion> { } + blt::PushZoom $graph + set zoomInfo($graph,corner) A + } +} + +option add *zoomOutline.dashes 4 +option add *zoomTitle.anchor nw +option add *zoomOutline.lineWidth 2 +option add *zoomOutline.xor yes + +proc blt::MarchingAnts { graph offset } { + global zoomInfo + + incr offset + if { [$graph marker exists zoomOutline] } { + $graph marker configure zoomOutline -dashoffset $offset + set interval $zoomInfo($graph,interval) + set id [after $interval [list blt::MarchingAnts $graph $offset]] + set zoomInfo($graph,afterId) $id + } +} + +proc blt::Box { graph } { + global zoomInfo + + if { $zoomInfo($graph,A,x) > $zoomInfo($graph,B,x) } { + set x1 [$graph xaxis invtransform $zoomInfo($graph,B,x)] + set y1 [$graph yaxis invtransform $zoomInfo($graph,B,y)] + set x2 [$graph xaxis invtransform $zoomInfo($graph,A,x)] + set y2 [$graph yaxis invtransform $zoomInfo($graph,A,y)] + } else { + set x1 [$graph xaxis invtransform $zoomInfo($graph,A,x)] + set y1 [$graph yaxis invtransform $zoomInfo($graph,A,y)] + set x2 [$graph xaxis invtransform $zoomInfo($graph,B,x)] + set y2 [$graph yaxis invtransform $zoomInfo($graph,B,y)] + } + set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 } + if { [$graph marker exists "zoomOutline"] } { + $graph marker configure "zoomOutline" -coords $coords + } else { + set X [lindex [$graph xaxis use] 0] + set Y [lindex [$graph yaxis use] 0] + $graph marker create line -coords $coords -name "zoomOutline" \ + -mapx $X -mapy $Y + set interval $zoomInfo($graph,interval) + set id [after $interval [list blt::MarchingAnts $graph 0]] + set zoomInfo($graph,afterId) $id + } +} + + +proc Blt_PostScriptDialog { graph } { + global POSTSCRIPTWINDOW + global POSTSCRIPTGRAPH + set top $graph.top + toplevel $top + wm title $top "Postscript out" + set POSTSCRIPTWINDOW $top + set POSTSCRIPTGRAPH $graph + foreach var { center landscape maxpect preview decorations padx + pady paperwidth paperheight width height colormode } { + global $graph.$var + set $graph.$var [$graph postscript cget -$var] + } + set row 1 + set col 0 + label $top.title -text "PostScript Options" + blt::table $top $top.title -cspan 7 + foreach bool { center landscape maxpect preview decorations } { + set w $top.$bool-label + label $w -text "-$bool" -font *courier*-r-*12* + blt::table $top $row,$col $w -anchor e -pady { 2 0 } -padx { 0 4 } + set w $top.$bool-yes + global $graph.$bool + radiobutton $w -text "yes" -variable $graph.$bool -value 1 + blt::table $top $row,$col+1 $w -anchor w + set w $top.$bool-no + radiobutton $w -text "no" -variable $graph.$bool -value 0 + blt::table $top $row,$col+2 $w -anchor w + incr row + } + label $top.modes -text "-colormode" -font *courier*-r-*12* + blt::table $top $row,0 $top.modes -anchor e -pady { 2 0 } -padx { 0 4 } + set col 1 + foreach m { color greyscale } { + set w $top.$m + radiobutton $w -text $m -variable $graph.colormode -value $m + blt::table $top $row,$col $w -anchor w + incr col + } + set row 1 + frame $top.sep -width 2 -bd 1 -relief sunken + blt::table $top $row,3 $top.sep -fill y -rspan 6 + set col 4 + foreach value { padx pady paperwidth paperheight width height } { + set w $top.$value-label + label $w -text "-$value" -font *courier*-r-*12* + blt::table $top $row,$col $w -anchor e -pady { 2 0 } -padx { 0 4 } + set w $top.$value-entry + global $graph.$value + entry $w -textvariable $graph.$value -width 8 + blt::table $top $row,$col+1 $w -cspan 2 -anchor w -padx 8 + incr row + } + blt::table configure $top c3 -width .125i + button $top.cancel -text "Cancel" -command "destroy $top" + blt::table $top $row,0 $top.cancel -width 1i -pady 2 -cspan 3 + button $top.reset -text "Reset" -command "destroy $top" + #blt::table $top $row,1 $top.reset -width 1i + button $top.print -text "Print" -command {blt::ResetPostScript $POSTSCRIPTGRAPH; destroy $POSTSCRIPTWINDOW } + blt::table $top $row,4 $top.print -width 1i -pady 2 -cspan 2 +} + +proc blt::ResetPostScript { graph } { + foreach var { center landscape maxpect preview decorations padx + pady paperwidth paperheight width height colormode } { + global $graph.$var + set old [$graph postscript cget -$var] + if { [catch {$graph postscript configure -$var [set $graph.$var]}] != 0 } { + $graph postscript configure -$var $old + set $graph.$var $old + } + } + set types {{"Postscript File" {.ps} } {"Encapsulated Postscript File" {.eps} }}; + set PSFILE [tk_getSaveFile -filetypes $types -parent . -initialfile Untitled -defaultextension .ps] + if {[string length $PSFILE]!=0} { + $graph postscript output $PSFILE + } +} diff --git a/tests/tcl-testbench4/example.cir b/tests/tcl-testbench4/example.cir new file mode 100644 index 000000000..4f8c41c20 --- /dev/null +++ b/tests/tcl-testbench4/example.cir @@ -0,0 +1,583 @@ +TITLE: proj1 - Rotary Traveling Wave Oscillator + + +VDD0 VDD0 VDD DC 0 +VSS0 VSS0 0 DC 0 +VDD_A0 VDD_A0 VDD0 DC 0 +VSS_A0 VSS_A0 VSS0 DC 0 +VDD_B0 VDD_B0 VDD0 DC 0 +VSS_B0 VSS_B0 VSS0 DC 0 +LA0 A0 LCA0 3.69030941553353e-11 +RA0 LCA0 A1 0.266535044422507 +LB0 B0 LCB0 3.69030941553353e-11 +RB0 LCB0 B1 0.266535044422507 +C0 A1 B1 2.50418376625721e-14 +MNA0 B0 A0 VSS_B0 VSS_B0 Nmod L=2.53696435353243e-07 W= ++4.24857778403814e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.49715556807627e-05 PS=8.49715556807627e-05 NQSMOD=1 +MPA0 B0 A0 VDD_B0 VDD_B0 Pmod L=2.55343565546106e-07 W= ++0.000101772203908557 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203544407817114 PS=0.000203544407817114 NQSMOD=1 +MNB0 A0 B0 VSS_A0 VSS_A0 Nmod L=2.53941602497219e-07 W= ++4.10652659629401e-05 AD=3.125e-11 AS=3.125e-11 PD= ++8.21305319258802e-05 PS=8.21305319258802e-05 NQSMOD=1 +MPB0 A0 B0 VDD_A0 VDD_A0 Pmod L=2.52010168145607e-07 W= ++0.000103533977891464 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207067955782928 PS=0.000207067955782928 NQSMOD=1 +LA1 A1 LCA1 3.69030941553353e-11 +RA1 LCA1 A2 0.266535044422507 +LB1 B1 LCB1 3.69030941553353e-11 +RB1 LCB1 B2 0.266535044422507 +C1 A2 B2 2.50418376625721e-14 +MNA1 B1 A1 0 0 Nmod L=2.52370578161099e-07 W=4.12246995102289e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.24493990204578e-05 PS= ++8.24493990204578e-05 NQSMOD=1 +MPA1 B1 A1 VDD VDD Pmod L=2.45709468983316e-07 W=0.000103710764679465 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207421529358929 PS= ++0.000207421529358929 NQSMOD=1 +MNB1 A1 B1 0 0 Nmod L=2.48115895523017e-07 W=4.26306134285554e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.52612268571108e-05 PS= ++8.52612268571108e-05 NQSMOD=1 +MPB1 A1 B1 VDD VDD Pmod L=2.55265156192223e-07 W=0.000102043840486507 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204087680973014 PS= ++0.000204087680973014 NQSMOD=1 +LA2 A2 LCA2 3.69030941553353e-11 +RA2 LCA2 A3 0.266535044422507 +LB2 B2 LCB2 3.69030941553353e-11 +RB2 LCB2 B3 0.266535044422507 +C2 A3 B3 2.50418376625721e-14 +MNA2 B2 A2 0 0 Nmod L=2.53484220592882e-07 W=4.16915225420459e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.33830450840917e-05 PS= ++8.33830450840917e-05 NQSMOD=1 +MPA2 B2 A2 VDD VDD Pmod L=2.44256748076514e-07 W=0.00010549295960702 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000210985919214039 PS= ++0.000210985919214039 NQSMOD=1 +MNB2 A2 B2 0 0 Nmod L=2.48805892712811e-07 W=4.15734692647458e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.31469385294916e-05 PS= ++8.31469385294916e-05 NQSMOD=1 +MPB2 A2 B2 VDD VDD Pmod L=2.54004987710956e-07 W=0.00010229621219808 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020459242439616 PS= ++0.00020459242439616 NQSMOD=1 +LA3 A3 LCA3 3.69030941553353e-11 +RA3 LCA3 A4 0.266535044422507 +LB3 B3 LCB3 3.69030941553353e-11 +RB3 LCB3 B4 0.266535044422507 +C3 A4 B4 2.50418376625721e-14 +MNA3 B3 A3 0 0 Nmod L=2.54307430347219e-07 W=4.11339076756089e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22678153512179e-05 PS= ++8.22678153512179e-05 NQSMOD=1 +MPA3 B3 A3 VDD VDD Pmod L=2.52369109463781e-07 W=0.000103371681055656 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206743362111311 PS= ++0.000206743362111311 NQSMOD=1 +MNB3 A3 B3 0 0 Nmod L=2.4960708801709e-07 W=4.21794611046917e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.43589222093833e-05 PS= ++8.43589222093833e-05 NQSMOD=1 +MPB3 A3 B3 VDD VDD Pmod L=2.53834779766428e-07 W=0.000105556314711602 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000211112629423204 PS= ++0.000211112629423204 NQSMOD=1 +LA4 A4 LCA4 3.69030941553353e-11 +RA4 LCA4 A5 0.266535044422507 +LB4 B4 LCB4 3.69030941553353e-11 +RB4 LCB4 B5 0.266535044422507 +C4 A5 B5 2.50418376625721e-14 +MNA4 B4 A4 0 0 Nmod L=2.48091656083177e-07 W=4.11207568141106e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22415136282211e-05 PS= ++8.22415136282211e-05 NQSMOD=1 +MPA4 B4 A4 VDD VDD Pmod L=2.47723605289033e-07 W=0.000103463392309261 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206926784618522 PS= ++0.000206926784618522 NQSMOD=1 +MNB4 A4 B4 0 0 Nmod L=2.49254771880382e-07 W=4.25122425012226e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50244850024452e-05 PS= ++8.50244850024452e-05 NQSMOD=1 +MPB4 A4 B4 VDD VDD Pmod L=2.49689766979065e-07 W=0.000103227993619608 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206455987239216 PS= ++0.000206455987239216 NQSMOD=1 +LA5 A5 LCA5 3.69030941553353e-11 +RA5 LCA5 A6 0.266535044422507 +LB5 B5 LCB5 3.69030941553353e-11 +RB5 LCB5 B6 0.266535044422507 +C5 A6 B6 2.50418376625721e-14 +MNA5 B5 A5 0 0 Nmod L=2.53960031106522e-07 W=4.1129961792588e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.22599235851759e-05 PS= ++8.22599235851759e-05 NQSMOD=1 +MPA5 B5 A5 VDD VDD Pmod L=2.47418707088064e-07 W=0.000101621693062467 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203243386124935 PS= ++0.000203243386124935 NQSMOD=1 +MNB5 A5 B5 0 0 Nmod L=2.49659687529522e-07 W=4.2524931640785e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.50498632815701e-05 PS= ++8.50498632815701e-05 NQSMOD=1 +MPB5 A5 B5 VDD VDD Pmod L=2.46328059754468e-07 W=0.000102061546065548 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000204123092131096 PS= ++0.000204123092131096 NQSMOD=1 +LA6 A6 LCA6 3.69030941553353e-11 +RA6 LCA6 A7 0.266535044422507 +LB6 B6 LCB6 3.69030941553353e-11 +RB6 LCB6 B7 0.266535044422507 +C6 A7 B7 2.50418376625721e-14 +MNA6 B6 A6 0 0 Nmod L=2.54326804653788e-07 W=4.17332976706085e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34665953412171e-05 PS= ++8.34665953412171e-05 NQSMOD=1 +MPA6 B6 A6 VDD VDD Pmod L=2.48727427835127e-07 W=0.000103244611103459 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000206489222206918 PS= ++0.000206489222206918 NQSMOD=1 +MNB6 A6 B6 0 0 Nmod L=2.49697035135609e-07 W=4.23570035518e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.47140071036001e-05 PS= ++8.47140071036001e-05 NQSMOD=1 +MPB6 A6 B6 VDD VDD Pmod L=2.48995485890626e-07 W=0.000103695454759978 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207390909519956 PS= ++0.000207390909519956 NQSMOD=1 +LA7 A7 LCA7 3.69030941553353e-11 +RA7 LCA7 A8 0.266535044422507 +LB7 B7 LCB7 3.69030941553353e-11 +RB7 LCB7 B8 0.266535044422507 +C7 A8 B8 2.50418376625721e-14 +MNA7 B7 A7 0 0 Nmod L=2.53418975114981e-07 W=4.06421756574473e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.12843513148946e-05 PS= ++8.12843513148946e-05 NQSMOD=1 +MPA7 B7 A7 VDD VDD Pmod L=2.4471861043622e-07 W=0.000104600862141835 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020920172428367 PS= ++0.00020920172428367 NQSMOD=1 +MNB7 A7 B7 0 0 Nmod L=2.50159056393584e-07 W=4.06845582724173e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.13691165448345e-05 PS= ++8.13691165448345e-05 NQSMOD=1 +MPB7 A7 B7 VDD VDD Pmod L=2.55032245177227e-07 W=0.000106482118141681 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000212964236283363 PS= ++0.000212964236283363 NQSMOD=1 +LA8 A8 LCA8 3.69030941553353e-11 +RA8 LCA8 A9 0.266535044422507 +LB8 B8 LCB8 3.69030941553353e-11 +RB8 LCB8 B9 0.266535044422507 +C8 A9 B9 2.50418376625721e-14 +MNA8 B8 A8 0 0 Nmod L=2.45729547191971e-07 W=4.18266198665335e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.3653239733067e-05 PS=8.3653239733067e-05 ++NQSMOD=1 +MPA8 B8 A8 VDD VDD Pmod L=2.45156004861421e-07 W=0.000101593205477244 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000203186410954489 PS= ++0.000203186410954489 NQSMOD=1 +MNB8 A8 B8 0 0 Nmod L=2.49014342219656e-07 W=4.14314219478801e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.28628438957603e-05 PS= ++8.28628438957603e-05 NQSMOD=1 +MPB8 A8 B8 VDD VDD Pmod L=2.50396673007567e-07 W=0.000103029640740115 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.00020605928148023 PS= ++0.00020605928148023 NQSMOD=1 +LA9 A9 LCA9 3.69030941553353e-11 +RA9 LCA9 A10 0.266535044422507 +LB9 B9 LCB9 3.69030941553353e-11 +RB9 LCB9 B10 0.266535044422507 +C9 A10 B10 2.50418376625721e-14 +MNA9 B9 A9 0 0 Nmod L=2.51066307645916e-07 W=4.17044186844862e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.34088373689724e-05 PS= ++8.34088373689724e-05 NQSMOD=1 +MPA9 B9 A9 VDD VDD Pmod L=2.4945438501494e-07 W=0.000104601836030031 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000209203672060063 PS= ++0.000209203672060063 NQSMOD=1 +MNB9 A9 B9 0 0 Nmod L=2.56178041422984e-07 W=4.17990098329256e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.35980196658511e-05 PS= ++8.35980196658511e-05 NQSMOD=1 +MPB9 A9 B9 VDD VDD Pmod L=2.5274010042983e-07 W=0.000103578149162769 ++AD=7.8125e-11 AS=7.8125e-11 PD=0.000207156298325537 PS= ++0.000207156298325537 NQSMOD=1 +LA10 A10 LCA10 3.69030941553353e-11 +RA10 LCA10 A11 0.266535044422507 +LB10 B10 LCB10 3.69030941553353e-11 +RB10 LCB10 B11 0.266535044422507 +C10 A11 B11 2.50418376625721e-14 +MNA10 B10 A10 0 0 Nmod L=2.45772611943267e-07 W=4.24345922952649e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.48691845905299e-05 PS= ++8.48691845905299e-05 NQSMOD=1 +MPA10 B10 A10 VDD VDD Pmod L=2.55544710347746e-07 W= ++0.000105625826497323 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211251652994645 PS=0.000211251652994645 NQSMOD=1 +MNB10 A10 B10 0 0 Nmod L=2.55886308364338e-07 W=4.0850956346516e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.17019126930321e-05 PS= ++8.17019126930321e-05 NQSMOD=1 +MPB10 A10 B10 VDD VDD Pmod L=2.44778614470725e-07 W= ++0.000105511594248206 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211023188496411 PS=0.000211023188496411 NQSMOD=1 +LA11 A11 LCA11 3.69030941553353e-11 +RA11 LCA11 A12 0.266535044422507 +LB11 B11 LCB11 3.69030941553353e-11 +RB11 LCB11 B12 0.266535044422507 +C11 A12 B12 2.50418376625721e-14 +MNA11 B11 A11 0 0 Nmod L=2.4768739676619e-07 W=4.14724461551725e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29448923103449e-05 PS= ++8.29448923103449e-05 NQSMOD=1 +MPA11 B11 A11 VDD VDD Pmod L=2.46276216123912e-07 W= ++0.000101782633723501 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203565267447002 PS=0.000203565267447002 NQSMOD=1 +MNB11 A11 B11 0 0 Nmod L=2.54985612770668e-07 W=4.24608643314108e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49217286628216e-05 PS= ++8.49217286628216e-05 NQSMOD=1 +MPB11 A11 B11 VDD VDD Pmod L=2.45772463970764e-07 W= ++0.000106109588792745 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021221917758549 PS=0.00021221917758549 NQSMOD=1 +LA12 A12 LCA12 3.69030941553353e-11 +RA12 LCA12 A13 0.266535044422507 +LB12 B12 LCB12 3.69030941553353e-11 +RB12 LCB12 B13 0.266535044422507 +C12 A13 B13 2.50418376625721e-14 +MNA12 B12 A12 0 0 Nmod L=2.45480481009462e-07 W=4.20858793029857e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41717586059714e-05 PS= ++8.41717586059714e-05 NQSMOD=1 +MPA12 B12 A12 VDD VDD Pmod L=2.48462320158069e-07 W= ++0.00010650127744954 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00021300255489908 PS=0.00021300255489908 NQSMOD=1 +MNB12 A12 B12 0 0 Nmod L=2.51992945030792e-07 W=4.17981435096244e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.35962870192489e-05 PS= ++8.35962870192489e-05 NQSMOD=1 +MPB12 A12 B12 VDD VDD Pmod L=2.49941922576661e-07 W= ++0.0001044851795426 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208970359085199 PS=0.000208970359085199 NQSMOD=1 +LA13 A13 LCA13 3.69030941553353e-11 +RA13 LCA13 A14 0.266535044422507 +LB13 B13 LCB13 3.69030941553353e-11 +RB13 LCB13 B14 0.266535044422507 +C13 A14 B14 2.50418376625721e-14 +MNA13 B13 A13 0 0 Nmod L=2.51146190542173e-07 W=4.23276196447018e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.46552392894035e-05 PS= ++8.46552392894035e-05 NQSMOD=1 +MPA13 B13 A13 VDD VDD Pmod L=2.46359362747576e-07 W= ++0.00010249565409785 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.0002049913081957 PS=0.0002049913081957 NQSMOD=1 +MNB13 A13 B13 0 0 Nmod L=2.44656485453628e-07 W=4.11044634633624e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.22089269267248e-05 PS= ++8.22089269267248e-05 NQSMOD=1 +MPB13 A13 B13 VDD VDD Pmod L=2.56119611942636e-07 W= ++0.0001064085618438 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002128171236876 ++PS=0.0002128171236876 NQSMOD=1 +LA14 A14 LCA14 3.69030941553353e-11 +RA14 LCA14 A15 0.266535044422507 +LB14 B14 LCB14 3.69030941553353e-11 +RB14 LCB14 B15 0.266535044422507 +C14 A15 B15 2.50418376625721e-14 +MNA14 B14 A14 0 0 Nmod L=2.47663439668801e-07 W=4.20889991075918e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.41779982151835e-05 PS= ++8.41779982151835e-05 NQSMOD=1 +MPA14 B14 A14 VDD VDD Pmod L=2.51252450429323e-07 W= ++0.000103622229824819 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207244459649638 PS=0.000207244459649638 NQSMOD=1 +MNB14 A14 B14 0 0 Nmod L=2.5044796612668e-07 W=4.24685059762319e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.49370119524638e-05 PS= ++8.49370119524638e-05 NQSMOD=1 +MPB14 A14 B14 VDD VDD Pmod L=2.4786360459861e-07 W= ++0.000104258615459431 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208517230918863 PS=0.000208517230918863 NQSMOD=1 +LA15 A15 LCA15 3.69030941553353e-11 +RA15 LCA15 A16 0.266535044422507 +LB15 B15 LCB15 3.69030941553353e-11 +RB15 LCB15 B16 0.266535044422507 +C15 A16 B16 2.50418376625721e-14 +MNA15 B15 A15 0 0 Nmod L=2.5213362488047e-07 W=4.26610931467994e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.53221862935989e-05 PS= ++8.53221862935989e-05 NQSMOD=1 +MPA15 B15 A15 VDD VDD Pmod L=2.44411053097269e-07 W= ++0.000104344399065411 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208688798130821 PS=0.000208688798130821 NQSMOD=1 +MNB15 A15 B15 0 0 Nmod L=2.44947739168727e-07 W=4.18061319080677e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.36122638161354e-05 PS= ++8.36122638161354e-05 NQSMOD=1 +MPB15 A15 B15 VDD VDD Pmod L=2.45133067349567e-07 W= ++0.000103673770597555 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020734754119511 PS=0.00020734754119511 NQSMOD=1 +LA16 A16 LCA16 3.69030941553353e-11 +RA16 LCA16 A17 0.266535044422507 +LB16 B16 LCB16 3.69030941553353e-11 +RB16 LCB16 B17 0.266535044422507 +C16 A17 B17 2.50418376625721e-14 +MNA16 B16 A16 0 0 Nmod L=2.5558903414348e-07 W=4.23651981762607e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.47303963525215e-05 PS= ++8.47303963525215e-05 NQSMOD=1 +MPA16 B16 A16 VDD VDD Pmod L=2.46968507923118e-07 W= ++0.000101577430536373 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203154861072746 PS=0.000203154861072746 NQSMOD=1 +MNB16 A16 B16 0 0 Nmod L=2.52441475326891e-07 W=4.0963445615255e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.192689123051e-05 PS= ++8.192689123051e-05 NQSMOD=1 +MPB16 A16 B16 VDD VDD Pmod L=2.49958772476576e-07 W= ++0.000102341104143712 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204682208287424 PS=0.000204682208287424 NQSMOD=1 +LA17 A17 LCA17 3.69030941553353e-11 +RA17 LCA17 A18 0.266535044422507 +LB17 B17 LCB17 3.69030941553353e-11 +RB17 LCB17 B18 0.266535044422507 +C17 A18 B18 2.50418376625721e-14 +MNA17 B17 A17 0 0 Nmod L=2.46623947628415e-07 W=4.07033737509309e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.14067475018618e-05 PS= ++8.14067475018618e-05 NQSMOD=1 +MPA17 B17 A17 VDD VDD Pmod L=2.52274212428759e-07 W= ++0.000105423152156798 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000210846304313596 PS=0.000210846304313596 NQSMOD=1 +MNB17 A17 B17 0 0 Nmod L=2.51233452024547e-07 W=4.12815452669714e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.25630905339429e-05 PS= ++8.25630905339429e-05 NQSMOD=1 +MPB17 A17 B17 VDD VDD Pmod L=2.49324495416238e-07 W= ++0.000104142717459091 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208285434918183 PS=0.000208285434918183 NQSMOD=1 +LA18 A18 LCA18 3.69030941553353e-11 +RA18 LCA18 A19 0.266535044422507 +LB18 B18 LCB18 3.69030941553353e-11 +RB18 LCB18 B19 0.266535044422507 +C18 A19 B19 2.50418376625721e-14 +MNA18 B18 A18 0 0 Nmod L=2.52038203439398e-07 W=4.17044670825126e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.34089341650252e-05 PS= ++8.34089341650252e-05 NQSMOD=1 +MPA18 B18 A18 VDD VDD Pmod L=2.46465042965348e-07 W= ++0.000102305682920291 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204611365840582 PS=0.000204611365840582 NQSMOD=1 +MNB18 A18 B18 0 0 Nmod L=2.45695550122768e-07 W=4.2510656912981e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.50213138259621e-05 PS= ++8.50213138259621e-05 NQSMOD=1 +MPB18 A18 B18 VDD VDD Pmod L=2.56212134001568e-07 W= ++0.000101696358889307 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000203392717778614 PS=0.000203392717778614 NQSMOD=1 +LA19 A19 LCA19 3.69030941553353e-11 +RA19 LCA19 A20 0.266535044422507 +LB19 B19 LCB19 3.69030941553353e-11 +RB19 LCB19 B20 0.266535044422507 +C19 A20 B20 2.50418376625721e-14 +MNA19 B19 A19 0 0 Nmod L=2.46298724559332e-07 W=4.26183323927543e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.52366647855085e-05 PS= ++8.52366647855085e-05 NQSMOD=1 +MPA19 B19 A19 VDD VDD Pmod L=2.53903413760174e-07 W= ++0.000103580270078538 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000207160540157077 PS=0.000207160540157077 NQSMOD=1 +MNB19 A19 B19 0 0 Nmod L=2.4541336381424e-07 W=4.1471197163819e-05 AD= ++3.125e-11 AS=3.125e-11 PD=8.2942394327638e-05 PS=8.2942394327638e-05 ++NQSMOD=1 +MPB19 A19 B19 VDD VDD Pmod L=2.51953325753565e-07 W= ++0.0001019745929959 AD=7.8125e-11 AS=7.8125e-11 PD=0.0002039491859918 ++PS=0.0002039491859918 NQSMOD=1 +LA20 A20 LCA20 3.69030941553353e-11 +RA20 LCA20 A21 0.266535044422507 +LB20 B20 LCB20 3.69030941553353e-11 +RB20 LCB20 B21 0.266535044422507 +C20 A21 B21 2.50418376625721e-14 +MNA20 B20 A20 0 0 Nmod L=2.55318350883171e-07 W=4.2257523363596e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.4515046727192e-05 PS= ++8.4515046727192e-05 NQSMOD=1 +MPA20 B20 A20 VDD VDD Pmod L=2.50733395598687e-07 W= ++0.000105848300738233 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211696601476467 PS=0.000211696601476467 NQSMOD=1 +MNB20 A20 B20 0 0 Nmod L=2.53961238224852e-07 W=4.07467605160825e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.1493521032165e-05 PS= ++8.1493521032165e-05 NQSMOD=1 +MPB20 A20 B20 VDD VDD Pmod L=2.52173406118976e-07 W= ++0.000104205251139887 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000208410502279773 PS=0.000208410502279773 NQSMOD=1 +LA21 A21 LCA21 3.69030941553353e-11 +RA21 LCA21 A22 0.266535044422507 +LB21 B21 LCB21 3.69030941553353e-11 +RB21 LCB21 B22 0.266535044422507 +C21 A22 B22 2.50418376625721e-14 +MNA21 B21 A21 0 0 Nmod L=2.46323292867561e-07 W=4.1601573531982e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.32031470639639e-05 PS= ++8.32031470639639e-05 NQSMOD=1 +MPA21 B21 A21 VDD VDD Pmod L=2.54613442115316e-07 W= ++0.000104931161465525 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.00020986232293105 PS=0.00020986232293105 NQSMOD=1 +MNB21 A21 B21 0 0 Nmod L=2.55836584454404e-07 W=4.10424160274173e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.20848320548346e-05 PS= ++8.20848320548346e-05 NQSMOD=1 +MPB21 A21 B21 VDD VDD Pmod L=2.54709741956022e-07 W= ++0.000102062091080516 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000204124182161031 PS=0.000204124182161031 NQSMOD=1 +LA22 A22 LCA22 3.69030941553353e-11 +RA22 LCA22 A23 0.266535044422507 +LB22 B22 LCB22 3.69030941553353e-11 +RB22 LCB22 B23 0.266535044422507 +C22 A23 B23 2.50418376625721e-14 +MNA22 B22 A22 0 0 Nmod L=2.54430620981417e-07 W=4.19307535657001e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.38615071314001e-05 PS= ++8.38615071314001e-05 NQSMOD=1 +MPA22 B22 A22 VDD VDD Pmod L=2.46694525572975e-07 W= ++0.000103108817734331 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000206217635468663 PS=0.000206217635468663 NQSMOD=1 +MNB22 A22 B22 0 0 Nmod L=2.4991048194413e-07 W=4.12343575509987e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.24687151019974e-05 PS= ++8.24687151019974e-05 NQSMOD=1 +MPB22 A22 B22 VDD VDD Pmod L=2.53435790976082e-07 W= ++0.000105540213369592 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000211080426739185 PS=0.000211080426739185 NQSMOD=1 +LA23 A23 LCA23 3.69030941553353e-11 +RA23 LCA23 A24 0.266535044422507 +LB23 B23 LCB23 3.69030941553353e-11 +RB23 LCB23 B24 0.266535044422507 +C23 A24 B24 2.50418376625721e-14 +MNA23 B23 A23 0 0 Nmod L=2.47985427798248e-07 W=4.14939059451511e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.29878118903023e-05 PS= ++8.29878118903023e-05 NQSMOD=1 +MPA23 B23 A23 VDD VDD Pmod L=2.50625862917368e-07 W= ++0.000104857443713713 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000209714887427425 PS=0.000209714887427425 NQSMOD=1 +MNB23 A23 B23 0 0 Nmod L=2.48906363214973e-07 W=4.09072154111792e-05 ++AD=3.125e-11 AS=3.125e-11 PD=8.18144308223583e-05 PS= ++8.18144308223583e-05 NQSMOD=1 +MPB23 A23 B23 VDD VDD Pmod L=2.544246792556e-07 W= ++0.000106667496188909 AD=7.8125e-11 AS=7.8125e-11 PD= ++0.000213334992377817 PS=0.000213334992377817 NQSMOD=1 +RCROSS1 A0 B24 0.001 +RCROSS2 B0 A24 0.001 + +.SAVE VDD0 +.SAVE VSS0 +.SAVE VDD_A0 +.SAVE VSS_A0 +.SAVE VDD_B0 +.SAVE VSS_B0 +.SAVE A0 B0 LA0#branch LB0#branch A1 B1 LA1#branch LB1#branch A2 B2 ++LA2#branch LB2#branch A3 B3 LA3#branch LB3#branch A4 B4 LA4#branch ++LB4#branch A5 B5 LA5#branch LB5#branch A6 B6 LA6#branch LB6#branch ++A7 B7 LA7#branch LB7#branch A8 B8 LA8#branch LB8#branch A9 B9 ++LA9#branch LB9#branch A10 B10 LA10#branch LB10#branch A11 B11 ++LA11#branch LB11#branch A12 B12 LA12#branch LB12#branch A13 B13 ++LA13#branch LB13#branch A14 B14 LA14#branch LB14#branch A15 B15 ++LA15#branch LB15#branch A16 B16 LA16#branch LB16#branch A17 B17 ++LA17#branch LB17#branch A18 B18 LA18#branch LB18#branch A19 B19 ++LA19#branch LB19#branch A20 B20 LA20#branch LB20#branch A21 B21 ++LA21#branch LB21#branch A22 B22 LA22#branch LB22#branch A23 B23 ++LA23#branch LB23#branch + + +** +**INCLUDING FILE: ./proj1/process.models.... +* +* Typical N Typical P - from process corners (taken from tsmc025_corners.bsim3 fron NCSU) +* +* TSMC 0.25u 5M 1P process. 2.5V transistor models + + +.MODEL Nmod NMOS LEVEL=8 ++TNOM = 25 ++VERSION = 3.2.2 TOX = 5.8e-9 ++XJ = 1E-07 NCH = 2.354946E+17 LLN = 1 ++LWN = 1 WLN = 1 WWN = 1 ++LINT = 1.76E-08 WINT = 6.75E-09 MOBMOD = 1 ++BINUNIT = 2 DWG = 0 DWB = 0 ++VTH0 = 0.4321336 LVTH0 = 2.081814E-08 WVTH0 = -5.470342E-11 ++PVTH0 = -6.721795E-16 K1 = 0.3281252 LK1 = 9.238362E-08 ++WK1 = 2.878255E-08 PK1 = -2.426481E-14 K2 = 0.0402824 ++LK2 = -3.208392E-08 WK2 = -1.154091E-08 PK2 = 9.192045E-15 ++K3 = 0 DVT0 = 0 DVT1 = 0 ++DVT2 = 0 DVT0W = 0 DVT1W = 0 ++DVT2W = 0 NLX = 0 W0 = 0 ++K3B = 0 VSAT = 7.586954E+04 LVSAT = 3.094656E-03 ++WVSAT = -1.747416E-03 PVSAT = 8.820956E-10 UA = 8.924498E-10 ++LUA = -1.511745E-16 WUA = -3.509821E-17 PUA = -3.08778E-23 ++UB = 8.928832E-21 LUB = -1.655745E-27 WUB = -2.03282E-27 ++PUB = 3.4578E-34 UC = -1.364265E-11 LUC = 1.170473E-17 ++WUC = -1.256705E-18 PUC = -6.249644E-24 RDSW = 447.8871 ++PRWB = 0 PRWG = 0 WR = 0.99 ++U0 = 0.06005258 LU0 = -6.31976E-09 WU0 = -8.819531E-09 ++PU0 = 3.57209E-15 A0 = -1.468837 LA0 = 6.419548E-07 ++WA0 = 5.512414E-07 PA0 = -9.222928E-14 KETA = -0.04922795 ++LKETA = 2.360844E-08 WKETA = 1.560385E-08 PKETA = -5.98377E-15 ++A1 = 0.02659908 LA1 = -6.511454E-09 A2 = 1 ++AGS = -4.01637 LAGS = 1.090294E-06 WAGS = 1.162021E-06 ++PAGS = -3.108579E-13 B0 = 0 B1 = 0 ++VOFF = -0.1829426 LVOFF = 9.941631E-09 WVOFF = 1.568082E-08 ++PVOFF = -2.832958E-15 NFACTOR = 0.6790636 LNFACTOR= 3.454948E-08 ++WNFACTOR= 1.501016E-07 PNFACTOR= -2.955591E-14 CIT = 2.218499E-04 ++LCIT = -1.076934E-10 WCIT = -3.286884E-10 PCIT = 1.658928E-16 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = 1.215578E-04 LETA0 = -1.037758E-11 WETA0 = -3.030225E-11 ++PETA0 = 1.529658E-17 ETAB = 3.548681E-03 LETAB = -1.791374E-09 ++WETAB = -6.897268E-10 PETAB = 3.481742E-16 DSUB = 0 ++PCLM = 3.583838 PDIBLC1 = 0 PDIBLC2 = 5.379674E-03 ++LPDIBLC2= 7.808481E-09 WPDIBLC2= 5.516945E-10 PPDIBLC2= -2.784957E-16 ++PDIBLCB = -0.1229374 LPDIBLCB= 4.956215E-08 WPDIBLCB= 3.299946E-08 ++PPDIBLCB= -9.624918E-15 DROUT = 0 PSCBE1 = 4.472639E+08 ++LPSCBE1 = 28.64041 WPSCBE1 = 15.7154 PPSCBE1 = -7.933138E-06 ++PSCBE2 = 1.842585E-06 LPSCBE2 = 2.871008E-12 WPSCBE2 = 2.579183E-12 ++PPSCBE2 = -1.301972E-18 PVAG = -2.015254E-03 LPVAG = 1.017757E-09 ++WPVAG = 3.07622E-10 PPVAG = -1.55418E-16 DELTA = -0.02862256 ++LDELTA = 1.492454E-08 WDELTA = -6.71663E-09 PDELTA = 3.407521E-15 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.2579945 ++LKT1 = -1.664895E-08 WKT1 = -1.633463E-08 PKT1 = 3.755864E-15 ++KT2 = -0.05347481 LKT2 = 8.244731E-09 WKT2 = 1.13705E-09 ++PKT2 = -1.240924E-15 AT = -1.132632E+04 LAT = 6.469047E-03 ++WAT = 6.829220E-04 PAT = -4.154249E-10 UTE = -2.309089 ++LUTE = 1.662427E-07 WUTE = 1.244801E-07 PUTE = -5.627924E-14 ++UA1 = -3.461758E-10 LUA1 = 1.747495E-16 WUA1 = -1.42065E-16 ++PUA1 = 7.171442E-23 UB1 = 0 UC1 = -2.38157E-12 ++LUC1 = -2.895726E-18 WUC1 = -1.990052E-17 PUC1 = 1.004497E-23 ++KT1L = 0 PRT = -1E-18 CJ = 2.024128E-3 ++MJ = 0.4960069 PB = 0.9173808 CJSW = 2.751528E-10 ++MJSW = 0.443145 PBSW = 0.9173808 CJSWG = 2.135064E-10 ++MJSWG = 0.443145 PBSWG = 0.9173808 ++RSH = 4.5 ++XTI = 3 ++CGDO = 3.11E-10 CGSO = 3.11E-10 CAPMOD = 2 ++XPART = 1 CF = 0 ++JS = 1E-06 ++JSW = 5E-11 + + + +.MODEL Pmod PMOS LEVEL=8 ++VERSION = 3.2.2 ++TNOM = 25 TOX = 5.8e-9 ++XJ = 1E-7 NCH = 4.1589E17 ++LLN = 1 LWN = 1 WLN = 1 ++WWN = 1 LINT = 1.2365E-8 WINT = 7.8E-9 ++MOBMOD = 1 BINUNIT = 2 DWG = 0 ++DWB = 0 VTH0 = -0.6236538 LVTH0 = 2.649834E-8 ++WVTH0 = 3.214189E-8 PVTH0 = -3.22268E-15 K1 = 0.4198155 ++LK1 = 5.770498E-8 WK1 = 5.577151E-8 PK1 = -2.81684E-14 ++K2 = 0.0429467 LK2 = -2.296405E-8 WK2 = -1.355302E-8 ++PK2 = 6.848271E-15 K3 = 0 DVT0 = 0 ++DVT1 = 0 DVT2 = 0 DVT0W = 0 ++DVT1W = 0 DVT2W = 0 NLX = 0 ++W0 = 0 K3B = 0 VSAT = 1.443912E5 ++LVSAT = -7.688012E-4 WVSAT = -6.083648E-3 PVSAT = 2.186471E-10 ++UA = 1.846811E-9 LUA = -3.27694E-16 WUA = -2.82106E-16 ++PUA = 7.180233E-23 UB = -7.84535E-19 LUB = 4.772849E-25 ++WUB = 2.599205E-25 PUB = -1.46530E-31 UC = -1.75560E-10 ++LUC = 3.360832E-17 WUC = 1.504425E-17 PUC = -1.30556E-23 ++RDSW = 1.03E3 PRWB = 0 PRWG = 0 ++WR = 1 U0 = 0.0136443 LU0 = -7.22084E-10 ++WU0 = -1.088554E-9 PU0 = 2.730854E-16 A0 = 0.1071803 ++LA0 = 4.64252E-7 WA0 = 5.383179E-7 PA0 = -1.32033E-13 ++KETA = -4.943762E-3 LKETA = -3.565304E-9 WKETA = -5.226247E-9 ++PKETA = 2.640665E-15 A1 = 0 A2 = 0.4 ++AGS = 0.1664005 LAGS = 1.19106E-7 WAGS = 5.29237E-8 ++PAGS = -2.67304E-14 B0 = 0 B1 = 0 ++VOFF = -0.0592623 LVOFF = -1.96686E-8 WVOFF = -1.486398E-8 ++PVOFF = 7.510321E-15 NFACTOR = 0.8588103 LNFACTOR= -1.158881E-7 ++WNFACTOR= 1.210664E-8 PNFACTOR= -6.11712E-15 CIT = 6.439495E-5 ++LCIT = 2.916437E-10 WCIT = -3.11284E-11 PCIT = 1.572825E-17 ++CDSC = 0 CDSCB = 0 CDSCD = 0 ++ETA0 = -3.819468E-3 LETA0 = 2.155422E-9 WETA0 = 8.235612E-10 ++PETA0 = -4.16037E-16 ETAB = 1.334637E-3 LETAB = -7.93631E-10 ++WETAB = 5.284657E-11 PETAB = -2.68353E-17 DSUB = 0 ++PCLM = 0.1098002 LPCLM = 6.874263E-7 WPCLM = 6.724724E-7 ++PPCLM = -1.97766E-13 PDIBLC1 = 0 PDIBLC2 = 5.801323E-3 ++LPDIBLC2= -1.81964E-9 WPDIBLC2= -5.853396E-9 PPDIBLC2= 2.957545E-15 ++PDIBLCB = 0.1921199 DROUT = 0 PSCBE1 = 7.19E8 ++PSCBE2 = 1E-20 PVAG = 0 DELTA = 0.01 ++ALPHA0 = 0 BETA0 = 30 KT1 = -0.3248987 ++LKT1 = -1.160393E-8 WKT1 = 4.153356E-8 PKT1 = -4.62347E-15 ++KT2 = -0.0367632 AT = 1E4 UTE = -1.04 ++UA1 = 3.992421E-10 UB1 = -9.23294E-19 LUB1 = -5.28718E-26 ++WUB1 = -6.13069E-26 PUB1 = 1.503674E-32 UC1 = -1.00699E-12 ++KT1L = 0 PRT = 0 CJ = 1.931092e-3 ++MJ = 0.4812153 PB = 0.9134669 CJSW = 2.232277e-10 ++MJSW = 0.3237595 PBSW = 0.9134669 CJSWG = 1.607088e-10 ++MJSWG = 0.3237595 PBSWG = 0.9134669 ++RSH = 3.5 ++CGDO = 2.68e-10 CGSO = 2.68e-10 ++CAPMOD = 2 ++XPART = 1 ++CF = 0 XTI = 3 ++JS = 3E-7 ++JSW = 5E-12 + +**.... FINISHED INCLUDING: ./proj1/process.models +** +.OPTIONS TEMP=25 +VSLEW_CONTROL VSLEW 0 (PULSE 0 1 0 1e-09) +EVLOGIC VRAMP 0 VSLEW 0 2.5 +VDDPOWER VDD VRAMP DC 0 +VARACTOR_V VARACTOR_V 0 DC 2.5 + +.TRAN 0.02n 3000n 0n 0.5n +.END diff --git a/tests/tcl-testbench4/selectfromlist.tcl b/tests/tcl-testbench4/selectfromlist.tcl new file mode 100644 index 000000000..9deb5c0b5 --- /dev/null +++ b/tests/tcl-testbench4/selectfromlist.tcl @@ -0,0 +1,55 @@ +namespace eval selectionwindow { + variable selectionvalue + variable selectionwindow +} + +proc selectionwindow::selectfromlist { window title selectionlist args } { + variable selectionvalue + variable selectionwindow + if { [winfo exists $window] } { + raise $window; + return [lindex $selectionlist 0] + } + set selectionwindow $window + toplevel $selectionwindow + wm geometry $selectionwindow +200+200 + focus -force $selectionwindow + wm title $selectionwindow $title + set maxstrlength [expr [string length $title]+12] + + if { [llength $selectionlist]==0 } { destroy $selectionwindow; return {} } + + foreach elem $selectionlist { + if { [string length $elem]>$maxstrlength } { + set maxstrlength [string length $elem] + } + } + + scrollbar $selectionwindow.scroll -command "$selectionwindow.listbox yview" + eval "listbox $selectionwindow.listbox -yscroll \"$selectionwindow.scroll set\" \ + -width $maxstrlength -height 10 -setgrid 1 $args" + pack $selectionwindow.listbox $selectionwindow.scroll -side left -fill y -expand 1 + foreach elem $selectionlist { + $selectionwindow.listbox insert end $elem + } + bind $selectionwindow.listbox { + namespace eval selectionwindow { + set selectionvalue [selection get] + destroy $selectionwindow + } + } + tkwait window $selectionwindow + + if { [info exists selectionvalue] } { + return $selectionvalue + } else { + if { [llength $selectionlist] != 0 } { + return [lindex $selectionlist 0] + } else { + return "" + } + } +} + +# puts [selectionwindow::selectfromlist .demo "Wähle Frucht" { Apfel Birne Zitrone dsfsdfdsfdsfdsfsdfds}] + diff --git a/tests/tcl-testbench4/tcl-testbench4.tcl b/tests/tcl-testbench4/tcl-testbench4.tcl new file mode 100644 index 000000000..da5c0fa2d --- /dev/null +++ b/tests/tcl-testbench4/tcl-testbench4.tcl @@ -0,0 +1,4 @@ +#!/bin/sh +# WishFix \ + exec wish vspicechart.tcl example.cir +### diff --git a/tests/tcl-testbench4/vspicechart.tcl b/tests/tcl-testbench4/vspicechart.tcl new file mode 100644 index 000000000..74660321d --- /dev/null +++ b/tests/tcl-testbench4/vspicechart.tcl @@ -0,0 +1,250 @@ +############ spice chart program ########### +############ programmer: stephan thiel ########### +############ thiel@mikro.ee.tu-berlin.de ########### +############ (c) 2008 Berlin, Germany ########### +############ Don't trust any version ########### +############ before 1.0 ########### + + +package require BLT +load "../../src/.libs/libspice.so" + +source selectfromlist.tcl +source bltGraph.tcl + +namespace import blt::* + +wm title . "vspicechart 0.01" +wm geometry . 800x450+40+40 +pack propagate . false + +set globals(colors) { red green blue orange yellow white gray lightblue pink darkblue \ + lightred lightgray darkgray darkblue darkgreen darkred violet salmon \ + gray100 gold SeaGreen RoyalBlue RosyBrown orchid MintCream magenta LimeGreen \ + gray33 DeepSkyBlue DarkGoldenrod chocolate gray77 aquamarine brown coral \ + DarkOliveGreen DarkOrange DarkSlateGray gray99 HotPink IndianRed LemonChiffon \ + LightSteelBlue PaleGreen peru sienna seashell SpringGreen tomato wheat WhiteSmoke} + + +proc replacechar { str pat pat1} { + set erg "" + for { set i 0 } { $i < [string length $str] } {incr i 1 } { + if { [ string index $str $i ] == $pat } { + append erg $pat1 + } else { + append erg [string index $str $i ] + } + } + return $erg +} + + +proc realtostr { r } { + set b [ expr abs($r) ] + set mul 1e-18 + set prefix a + if { $b > 9.9999999999e-16 } { + set mul 1e15 + set prefix f + } + if { $b > 9.9999999999e-13 } { + set mul 1e12 + set prefix p + } + if { $b > 9.9999999999e-10 } { + set mul 1e9 + set prefix n + } + if { $b > 9.9999999999e-7 } { + set mul 1e6 + set prefix u + } + if { $b > 9.9999999999e-4 } { + set mul 1e3 + set prefix m + } + + if { $b > 0.999999999999999 } { + set mul 1 + set prefix "" + } + + if { $b > 999 } { + set mul 1e-3 + set prefix K + } + + if { $b > 9.999999999e5 } { + set mul 1e-6 + set prefix MEG + } + if { $b > 9.9999999999e8 } { + set mul 1e-9 + set prefix G + } + if { $b > 9.99999999999e11 } { + set mul 1e-12 + set prefix T + } + set str [ format "%1.8g$prefix" [expr $r*$mul] ] + if { $str=="0a" } { set str "0" } + return $str +} + +proc realtostr1 { elem r } { + scan $r "%f" erg + return [ realtostr $erg ] +} + +set globals(signals) {}; + +proc readconfigfile { } { + global globals + global const + if { [file exists $globals(CONFIGFILE)] } { + set fid [open $globals(CONFIGFILE) r] + while { ![eof $fid] } { + gets $fid tempstring + if { [string first "PACK-PATH=" $tempstring]==0 } { + scan $tempstring "PACK-PATH=%s" globals(PACK-PATH) + } + if { [string first "SIMULATOR=" $tempstring]==0 } { + scan $tempstring "SIMULATOR=%s" globals(SIMULATOR) + } + } + close $fid + } else { + set globals(PACK-PATH) "" + set globals(SIMULATOR) "INTERNAL" + } +} + +proc select_vector { } { + global globals + set thissignals [spice::spice_data] + set signals {} + foreach sig $thissignals { + if { [lindex $sig 0] != "time" } { + lappend signals [lindex $sig 0] + } + } + set selectedsignal [selectionwindow::selectfromlist .select "Select Signal" $signals ] + if { ( [string trim $selectedsignal] != "") && ([lsearch -exact $globals(signals) $selectedsignal] == -1) } { + eval "$globals(LSELECTEDSIGNALS) insert end $selectedsignal" + vector create [replacechar $selectedsignal "\#" "_"] + } +} + + +proc start_new_sel { } { + global globals + + set elemlist [ eval "$globals(chart0) element show" ] + for { set j 0 } {$j < [llength $elemlist] } {incr j 1} { + $globals(chart0) element delete [lindex $elemlist $j ] + } + + set i 0 + foreach sig $globals(signals) { + set nsig [replacechar $sig "\#" "_"] + vector create $nsig + spice::spicetoblt $sig $nsig + + $globals(chart0) element create $sig -color [lindex $globals(colors) $i] -xdata stime -ydata $nsig -symbol none + incr i 1 + } +} + + +proc delete_selected { } { + global globals + set elem [$globals(LSELECTEDSIGNALS) curselection] + if { $elem != "" } { + $globals(LSELECTEDSIGNALS) delete $elem + } +} + + + +set filename [ lindex $argv 0] + +if { [file exists $filename ] } { + spice::source $filename + spice::bg run + +after 1000 + + + +frame .f1 +pack .f1 -side left -expand true -fill both + +listbox .f1.blistbox -listvariable globals(signals) +pack .f1.blistbox -side top -fill both -expand true + +set globals(LSELECTEDSIGNALS) .f1.blistbox + + +button .f1.baddvec -text "Select Vector" -command "select_vector" +pack .f1.baddvec -side top -fill x -expand true + +button .f1.bdelvec -text "Delete Vector" -command "delete_selected" +pack .f1.bdelvec -side top -fill x -expand true + +button .f1.bstartsel -text "Start with new selection" -command start_new_sel +pack .f1.bstartsel -side top -fill x -expand true + + +button .f1.simstop -text "Simulation Stop" -command "spice::stop" +pack .f1.simstop -side top -fill x -expand true + +button .f1.simresume -text "Simulation Resume" -command "spice::bg resume" +pack .f1.simresume -side top -fill x -expand true + + +button .f1.bexit -text "Exit" -command "exit" +pack .f1.bexit -side top -fill x -expand true + + +frame .f2 +pack .f2 -side left -expand true -fill both + +stripchart .f2.chart +pack .f2.chart -side top -fill both -expand true +.f2.chart axis configure x -title "Time in s" + + +.f2.chart grid configure -hide no +Blt_ZoomStack .f2.chart +Blt_Crosshairs .f2.chart +Blt_ClosestPoint .f2.chart +Blt_PrintKey .f2.chart +Blt_ActiveLegend .f2.chart +.f2.chart crosshairs configure -color lightblue + +.f2.chart axis configure x -command realtostr1 +.f2.chart axis configure y -command realtostr1 + +set globals(chart0) .f2.chart + + + + vector create stime + + + proc bltupdate {} { + global globals + + spice::spicetoblt time stime + foreach sig $globals(signals) { + set nsig [replacechar $sig "\#" "_"] + spice::spicetoblt $sig $nsig + } + + after 100 bltupdate + } + bltupdate + +} else { + exit; +} diff --git a/tests/tcl/diffpair.cir b/tests/tcl/diffpair.cir new file mode 100644 index 000000000..c926364f3 --- /dev/null +++ b/tests/tcl/diffpair.cir @@ -0,0 +1,29 @@ +simple differential pair - CM and DM dc sensitivity + +* Models: +.model qnl npn(bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf va=50) +.model qnr npn(bf=80 rb=100 ccs=2pf tf=0.3ns tr=6ns cje=3pf cjc=2pf va=50) + +* Circuit description: +q1 4 2 6 qnr +q2 5 3 6 qnl +rs1 11 2 1k +rs2 3 1 1k +rc1 4 8 10k +rc2 5 8 10k +q3 7 7 9 qnl +q4 6 7 9 qnr +rbias 7 8 20k + +* Inputs/Supplies: +vcm 1 0 dc 0 sin(0 0.1 5meg) ac 1 +vdm 1 11 dc 0 sin(0 0.1 5meg) ac 1 +vcc 8 0 12 +vee 9 0 -12 + +* Analysys: +.tf v(5) vcm +.tf v(5) vdm +.sens v(5,4) + +.end diff --git a/tests/tcl/test_vectoblt.tcl b/tests/tcl/test_vectoblt.tcl new file mode 100644 index 000000000..bacbffb5d --- /dev/null +++ b/tests/tcl/test_vectoblt.tcl @@ -0,0 +1,54 @@ +package require spice + +spice::source "diffpair.cir" +spice::op +spice::let Vd = V(5) - V(4) +blt::vector imag +blt::vector real + +set ok 0 +################### +puts " Vd is a real vector of length 1" +################### +#too many arguments +if {[catch {spice::vectoblt raul ibrahim ector karim} erreur] != 0} {puts "ERROR EXPECTED: TEST 1 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 1 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable argument +if {[catch {spice::vectoblt raul ibrahim ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 2 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 2 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable blt vector +if {[catch {spice::vectoblt Vd ibrahim} erreur] != 0} {puts "ERROR EXPECTED: TEST 3 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 3 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#real part affectation +if {[catch {spice::vectoblt Vd real} erreur] == 0} {puts "NO ERROR IN AFFECTATION. TEST 4 OK:\n\t (Blank line)"; set ok [expr {$ok + 1}]} else {puts "TEST 4 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable blt vector (2 vectors) +if {[catch {spice::vectoblt Vd ibrahim ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 5 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 5 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable imaginary vector +if {[catch {spice::vectoblt Vd real ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 6 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 6 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#real and imaginary part affectation +if {[catch {spice::vectoblt Vd real imag} erreur] == 0} {puts "NO ERROR IN AFFECTATION. TEST 7 OK:\n\t (Blank line)"; set ok [expr {$ok + 1}]} else {puts "TEST 7 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#all good vectors, but another argument invited himself +if {[catch {spice::vectoblt Vd real imag karim} erreur] != 0} {puts "ERROR EXPECTED: TEST 8 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 8 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} + +################### +puts " Vd is a complex vector of length 10" +################### +spice::op +spice::ac dec 10 100 1000 +spice::let Vd = V(5) - V(4) +#too many arguments +if {[catch {spice::vectoblt raul ibrahim ector karim} erreur] != 0} {puts "ERROR EXPECTED: TEST 1 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 1 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable argument +if {[catch {spice::vectoblt raul ibrahim ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 2 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 2 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable blt vector +if {[catch {spice::vectoblt Vd ibrahim} erreur] != 0} {puts "ERROR EXPECTED: TEST 3 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 3 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#real part affectation +if {[catch {spice::vectoblt Vd real} erreur] == 0} {puts "NO ERROR IN AFFECTATION. TEST 4 OK:\n\t (Blank line)"; set ok [expr {$ok + 1}]} else {puts "TEST 4 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable blt vector (2 vectors) +if {[catch {spice::vectoblt Vd ibrahim ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 5 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 5 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#no acceptable imaginary vector +if {[catch {spice::vectoblt Vd real ector} erreur] != 0} {puts "ERROR EXPECTED: TEST 6 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 6 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#real and imaginary part affectation +if {[catch {spice::vectoblt Vd real imag} erreur] == 0} {puts "NO ERROR IN AFFECTATION. TEST 7 OK:\n\t (Blank line)"; set ok [expr {$ok + 1}]} else {puts "TEST 7 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} +#all good vectors, but another argument invited himself +if {[catch {spice::vectoblt Vd real imag karim} erreur] != 0} {puts "ERROR EXPECTED: TEST 8 OK:\n\t$erreur"; set ok [expr {$ok + 1}]} else {puts "TEST 8 ERROR\n\t Test 1 should return TCL_ERROR, but it does not"} + +puts "\n\n" +if {$ok == 16} {puts "spice::vectoblt OK ($ok/16 tests ok)"} else {puts "spice::vectoblt KO:\n\t$ok/16 tests ok"}