diff --git a/compile_cyg_make_short_check_64.sh b/compile_cyg_make_short_check_64.sh index 54d0868d2..668fd5218 100644 --- a/compile_cyg_make_short_check_64.sh +++ b/compile_cyg_make_short_check_64.sh @@ -11,12 +11,10 @@ # './compile_cyg_auto.sh' # Options: -# --adms and --enable-adms will install extra HICUM, EKV and MEXTRAM models via the -# adms interface. -# Please see http://ngspice.sourceforge.net/admshowto.html for more info on adms. -# CIDER, XSPICE, and OpenMP may be selected at will. +# CIDER, XSPICE, OSDI, KLU, and OpenMP may be selected at will. # --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. # --enable-oldapps will make ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx in addition to ngspice +# --enable-shortcheck will provide a fast 'make check' by checking only BSIM3 and BSIM4 if [ ! -d "release64_cyg" ]; then mkdir release64_cyg @@ -27,18 +25,11 @@ fi ./autogen.sh if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi -# Alternatively, if compiling sources from CVS, and want to add adms created devices, -# you may need to uncomment the following two lines (and don't forget to add adms option -# to the ../configure statement): -#./autogen.sh --adms -#if [ $? -ne 0 ]; then echo "./autogen.sh --adms failed"; exit 1 ; fi - echo cd release64_cyg if [ $? -ne 0 ]; then echo "cd release64_cyg failed"; exit 1 ; fi echo -# You may add --enable-adms to the following command for adding adms generated devices -../configure --with-x=yes --with-readline=yes --disable-debug --enable-cider --enable-openmp --enable-xspice --enable-osdi --enable-predictor --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" +../configure --with-x=yes --with-readline=yes --disable-debug --enable-cider --enable-openmp --enable-xspice --enable-osdi --enable-klu --enable-predictor --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" #../configure --with-x=no --with-readline=yes --disable-debug --enable-xspice --enable-cider --enable-openmp if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi diff --git a/compile_linux_klu.sh b/compile_linux_klu.sh deleted file mode 100755 index cc848778b..000000000 --- a/compile_linux_klu.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash -# ngspice-klu build script for Linux, release or debug version, 64 bit -# compile_linux_klu.sh -# https://ieeexplore.ieee.org/document/6226278 - -# Procedure: -# Install gcc, bison, flex, libtool, autoconf, automake, -# libx11 and libx11-dev (headers), libXaw and libXaw-dev, libreadline and dev -# xmu, xet, xt, libxft, libxrender, libfreetype, libfontconfig -# for details please see the ngspice manual, chapt. 32.1. -# Declare 'compile_linux_klu.sh' executable and start compiling with -# './compile_linux_klu.sh' or './compile_linux_klu.sh d' from the ngspice directory. -# Options: -# XSPICE (--enable-xspice) may be selected at will. -# --disable-debug will give O2 optimization (versus O0 for debug) and removes all debugging info. -# OSDI (--enable-osdi) is not yet supported by KLU - -# ngspice as shared library: -# Replace --with-x by --with-ngshared in line ../configure ... . -# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. -# It might be necessary to uncomment and run ./autogen.sh . - -SECONDS=0 - -# We need to remove all remnants of a previous compile -if test "$1" = "d"; then - rm -f -r debug - mkdir debug - if [ $? -ne 0 ]; then echo "mkdir debug failed"; exit 1 ; fi -else - rm -f -r release - mkdir release - if [ $? -ne 0 ]; then echo "mkdir release failed"; exit 1 ; fi -fi - -# If compiling sources from tarball, you may comment out the following two lines: -./autogen.sh -if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi - -echo -if test "$1" = "d"; then - cd debug - if [ $? -ne 0 ]; then echo "cd debug failed"; exit 1 ; fi - echo "configuring for 64 bit debug" - echo - ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu --enable-predictor --enable-osdi CFLAGS="-g -m64 -O0 -Wall -Wno-unused-but-set-variable" LDFLAGS="-m64 -g" -else - cd release - if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi - echo "configuring for 64 bit release" - echo - ../configure --with-x --enable-cider --with-readline=yes --enable-openmp --enable-xspice --enable-klu --enable-predictor --enable-osdi --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" -fi -if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi - -echo -# make clean is required for properly making the code models -echo "cleaning (see make_clean.log)" -make clean 2>&1 -j8 | tee make_clean.log -exitcode=${PIPESTATUS[0]} -if [ $exitcode -ne 0 ]; then echo "make clean failed"; exit 1 ; fi -echo "compiling (see make.log)" -make 2>&1 -j8 | tee make.log -exitcode=${PIPESTATUS[0]} -if [ $exitcode -ne 0 ]; then echo "make failed"; exit 1 ; fi -# Install to /usr/local -echo "installing (see make_install.log)" -make install 2>&1 | tee make_install.log -exitcode=${PIPESTATUS[0]} -if [ $exitcode -ne 0 ]; then echo "make install failed"; exit 1 ; fi - -ELAPSED="Elapsed compile time: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec" -echo -echo $ELAPSED -echo "success" -exit 0 diff --git a/configure.ac b/configure.ac index 0cda21fc6..48b776c4c 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ # problem to the user. AC_PREREQ([2.59]) -m4_define([ngspice_major_version], [42]) +m4_define([ngspice_major_version], [42+]) m4_define([ngspice_minor_version], [0]) m4_define([ngspice_version], [ngspice_major_version]) @@ -154,9 +154,9 @@ AC_ARG_ENABLE([osdi], AC_ARG_ENABLE([cider], [AS_HELP_STRING([--enable-cider], [Enable CIDER enhancements])]) -# --enable-adms: define ADMS in the code. This is for the adms Verilog-A compiler support +# --enable-adms: ADMS is no longer supported AC_ARG_ENABLE([adms], - [AS_HELP_STRING([--enable-adms], [Enable ADMS code models, (experimental)])]) + [AS_HELP_STRING([--enable-adms], [ADMS is no longer supported])]) # --enable-pss: enable PSS Analysis AC_ARG_ENABLE([pss], @@ -1227,58 +1227,6 @@ AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes]) AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes]) AM_CONDITIONAL([SENSE2_WANTED], [test "x$enable_sense2" = xyes]) -# adms option -if test "x$enable_adms" = xyes ; then - AC_MSG_RESULT([********************************** -* ADMS support is experimental * -**********************************]) - AC_CHECK_PROGS([ADMSXML], [admsXml admsXml.exe]) - - if test "x$ADMSXML" = x; then - AC_MSG_ERROR([If you want Verilog-A models you should install admsXml]) - fi - AC_DEFINE([ADMS], [1], [Support for Verilog-A models]) - - VLADEVDIR=" adms/bsimbulk \ - adms/bsimcmg \ - adms/ekv \ - adms/hicum0 \ - adms/mextram \ - adms/psp102 \ - adms/psp103 \ - adms/r2_cmc " - -# The makefiles for adms (to be added to AC_CONFIG_FILES by ./autogen.sh --adms) -#VLAMKF src/spicelib/devices/adms/bsimbulk/Makefile -#VLAMKF src/spicelib/devices/adms/bsimcmg/Makefile -#VLAMKF src/spicelib/devices/adms/ekv/Makefile -#VLAMKF src/spicelib/devices/adms/hicum0/Makefile -#VLAMKF src/spicelib/devices/adms/mextram/Makefile -#VLAMKF src/spicelib/devices/adms/psp102/Makefile -#VLAMKF src/spicelib/devices/adms/psp103/Makefile -#VLAMKF src/spicelib/devices/adms/r2_cmc/Makefile - - NOTVLADEVDIR="" - - VLADEV=" spicelib/devices/adms/bsimbulk/libbsimbulk.la \ - spicelib/devices/adms/bsimcmg/libbsimcmg.la \ - spicelib/devices/adms/ekv/libekv.la \ - spicelib/devices/adms/hicum0/libhicum0.la \ - spicelib/devices/adms/mextram/libbjt504t.la \ - spicelib/devices/adms/psp102/libpsp102.la \ - spicelib/devices/adms/psp103/libpsp103.la \ - spicelib/devices/adms/r2_cmc/libr2_cmc.la " - -else - - VLADEVDIR="" - NOTVLADEVDIR="adms/admst" - -fi - -AC_SUBST([VLADEVDIR]) -AC_SUBST([VLADEV]) -AC_SUBST([NOTVLADEVDIR]) # NDEV option if test "x$enable_ndev" = xyes; then diff --git a/examples/various/v-i-sources-am-ffm.cir b/examples/various/v-i-sources-am-ffm.cir new file mode 100644 index 000000000..855b4da80 --- /dev/null +++ b/examples/various/v-i-sources-am-ffm.cir @@ -0,0 +1,65 @@ +* FFM and AM, independen voltage or current source + +* select 1 for current source, or 0 for voltage source +.param is = 0 + +* AM(VO, VMO, VMA, FM, FC, TD, PHASEM, PHASEC) + +* am modulation, modulation depth 0.9 (MD=VMA/VMO) +.if (is) +I1 0 1 AM 0.5 2 1.8 1k 100k 1m 0 0 +RI 1 0 1 +.else +V1 1 0 AM 0.5 2 1.8 1k 100k 1m 0 0 +.endif + +*Double side band suppressed carrier +.if (is) +I3 0 20 AM 0 0 1 1k 100k 1m 0 0 +RI3 20 0 1 +.else +V3 20 0 AM 0 0 1 1k 100k 1m 0 0 +.endif + +* SFFM(VO, VA, FM, MDI, FC, TD, PHASEM, PHASEC) +.if (is) +I2 0 10 SFFM 0.1 2 200 45 10k 1m 0 0 +RI2 0 10 1 +.else +V2 10 0 SFFM 0.1 2 200 45 10k 1m 0 0 ; MDI=FC/FM*0.9 +.endif + +*** diode detector for AM +D1 1 2 DMOD +.model DMOD D + +C1 2 0 5n +R1 2 0 10k +C2 2 3 2n +R2 3 0 1Meg +*** + +* Do we know a simple detector for FM ? + +.tran 500n 64m + +.control +run +rusage +set xbrushwidth=2 +plot v(1) title 'AM modulation 1kHz in 100kHz, mdepth=0.9' +plot v(1) xlimit 45m 50m title 'AM modulation 1kHz in 100kHz, mdepth=0.9' +plot v(2) v(3) title 'AM modulation, output of diode detector' +plot v(2) v(3) xlimit 45m 50m title 'AM modulation, output of diode detector' +plot v(10) title 'Frequency modulation' +plot v(10) xlimit 36m 41m title 'Frequency modulation' +plot v(20) xlimit 36m 41m title 'Double side band suppressed carrier modulation' +linearize +fft v(1) v(3) v(10) v(20) +plot mag(v(1)) xlimit 90k 110k title 'AM modulation 1kHz in 100kHz, mdepth=0.9' +plot mag(v(3)) xlimit 0k 5k title 'AM modulation, output of diode detector' +plot mag(v(10)) xlimit 0k 25k title 'Frequency modulation' +plot mag(v(20)) xlimit 90k 110k title 'Double side band suppressed carrier modulation' +.endc + +.end diff --git a/src/Makefile.am b/src/Makefile.am index 55cf63a35..62a3536a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -97,8 +97,7 @@ DYNAMIC_DEVICELIBS = \ spicelib/devices/vccs/libvccs.la \ spicelib/devices/vcvs/libvcvs.la \ spicelib/devices/vdmos/libvdmos.la \ - spicelib/devices/vsrc/libvsrc.la \ - @VLADEV@ + spicelib/devices/vsrc/libvsrc.la diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 026d43661..922393c5c 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -4853,6 +4853,10 @@ int get_number_terminals(char *c) return 2; break; case 'd': + /* PS: D <(+) node> <(-) node> [area value], + but still allow self heating diode with ngspice syntax. */ + if (newcompat.ps && !search_plain_identifier(c, "thermal")) + return 2; i = 0; /* find the first token with "off" or "=" in the line*/ while ((i < 10) && (*c != '\0')) { @@ -8004,13 +8008,19 @@ static int inp_vdmos_model(struct card *deck) if (cut_line) { wl_append_word(&wl, &wl, copy_substring(curr_line, cut_line)); wlb = wl; - if (strstr(cut_line, "pchan")) { + if (search_plain_identifier(cut_line, "pchan")) { wl_append_word(NULL, &wl, copy("vdmosp (")); } + else if (search_plain_identifier(cut_line, "nchan")) { + wl_append_word(NULL, &wl, copy("vdmosn (")); + } else { wl_append_word(NULL, &wl, copy("vdmosn (")); } - cut_line = cut_line + 5; + cut_line = cut_line + 6; /* skip VDMOS */ + + if (ciprefix("nchan", cut_line) || ciprefix("pchan", cut_line)) + cut_line = cut_line + 5; /* old VDMOS model, skip nchan, pchan */ cut_line = skip_ws(cut_line); if (*cut_line == '(') @@ -8018,13 +8028,16 @@ static int inp_vdmos_model(struct card *deck) new_line = NULL; while (cut_line && *cut_line) { token = gettok_model(&cut_line); - if (!ciprefix("pchan", token) && !ciprefix("ron=", token) && + if (token && *token != '\0' && + !ciprefix("pchan", token) && !ciprefix("ron=", token) && !ciprefix("vds=", token) && !ciprefix("qg=", token) && !ciprefix("mfg=", token) && !ciprefix("nchan", token)) wl_append_word(NULL, &wl, token); - else + else { tfree(token); - if (*cut_line == ')') { + break; + } + if (*cut_line == ')' || *cut_line == '\0') { wl_append_word(NULL, &wl, copy(")")); break; } diff --git a/src/frontend/trannoise/FastNorm3.c b/src/frontend/trannoise/FastNorm3.c index 28c97fca2..6ad414f5a 100644 --- a/src/frontend/trannoise/FastNorm3.c +++ b/src/frontend/trannoise/FastNorm3.c @@ -92,7 +92,7 @@ c but avoids most of the well-known defects of this type of generator c by, in effect, generating x[n+k] from x[n] as defined by the c sequence above, where k is chosen randomly in 1 ... 128 with the c help of a subsidiary Tauseworth-type generator. -c For the positve integer generator irandm, the less +c For the positive integer generator irandm, the less c significant digits are more random than is usual for a Lehmer c generator. The last n<31 digits do not repeat with a period of 2^n. c This is also true of the unsigned integer generator urandm, but less diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 5bc2c1f93..205ea969b 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -861,6 +861,10 @@ wordlist *cp_variablesubst(wordlist *wlist) while ((s_dollar = strchr(wl->wl_word + i, '$')) != NULL) { + /* Prevent vectors carrying the E POLY source current from being disaggregated */ + if (ciprefix("a$poly$", wl->wl_word)) + break; + int prefix_len = (int) (s_dollar - wl->wl_word); char *tail = span_var_expr(s_dollar + 1); diff --git a/src/include/ngspice/sharedspice.h b/src/include/ngspice/sharedspice.h index 3f37f6be2..2b9ac5b5f 100644 --- a/src/include/ngspice/sharedspice.h +++ b/src/include/ngspice/sharedspice.h @@ -107,7 +107,7 @@ are of type bool if sharedspice.h is used externally. */ #ifndef NGSPICE_PACKAGE_VERSION -#define NGSPICE_PACKAGE_VERSION "42" +#define NGSPICE_PACKAGE_VERSION "42+" #endif /* we have NG_BOOL instead of BOOL */ #ifndef HAS_NG_BOOL diff --git a/src/osdi/osdiinit.c b/src/osdi/osdiinit.c index cbfa5cf31..b647de25e 100644 --- a/src/osdi/osdiinit.c +++ b/src/osdi/osdiinit.c @@ -54,7 +54,7 @@ static int write_param_info(IFparm **dst, const OsdiDescriptor *descr, break; default: errRtn = "get_osdi_info"; - errMsg = tprintf("Unkown OSDI type %d for parameter %s!", + errMsg = tprintf("Unknown OSDI type %d for parameter %s!", para->flags & PARA_TY_MASK, para->name[0]); return -1; } diff --git a/src/osdi/osdisetup.c b/src/osdi/osdisetup.c index 4614292a3..77860e21f 100644 --- a/src/osdi/osdisetup.c +++ b/src/osdi/osdisetup.c @@ -43,11 +43,11 @@ static int handle_init_info(OsdiInitInfo info, const OsdiDescriptor *descr) { break; } default: - printf("Unkown OSDO init error code %d!\n", err->code); + printf("Unknown OSDO init error code %d!\n", err->code); } } free(info.errors); - errMsg = tprintf("%i errors occurred during initalization", info.num_errors); + errMsg = tprintf("%i errors occurred during initialization", info.num_errors); return (E_PRIVATE); } diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index bc6674611..a97f7c26c 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -51,8 +51,7 @@ SUBDIRS = \ vccs \ vcvs \ vdmos \ - vsrc \ - @VLADEVDIR@ + vsrc if NDEV_WANTED SUBDIRS += ndev diff --git a/src/spicelib/devices/isrc/isrcload.c b/src/spicelib/devices/isrc/isrcload.c index f947686c9..d88cc4072 100644 --- a/src/spicelib/devices/isrc/isrcload.c +++ b/src/spicelib/devices/isrc/isrcload.c @@ -205,72 +205,85 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt) case SFFM: { - double VO, VA, FC, MDI, FS; - double PHASEC, PHASES; + double VO, VA, FM, MDI, FC, TD, PHASEM, PHASEC; double phasec; - double phases; - - PHASEC = here->ISRCfunctionOrder > 5 - ? here->ISRCcoeffs[5] : 0.0; - PHASES = here->ISRCfunctionOrder > 6 - ? here->ISRCcoeffs[6] : 0.0; - - /* compute phases in radians */ - phasec = PHASEC * M_PI / 180.0; - phases = PHASES * M_PI / 180.0; + double phasem; + static bool warn1 = FALSE, warn2 = FALSE; VO = here->ISRCcoeffs[0]; VA = here->ISRCcoeffs[1]; - FC = here->ISRCfunctionOrder > 2 - && here->ISRCcoeffs[2] - ? here->ISRCcoeffs[2] : (1/ckt->CKTfinalTime); + FM = here->ISRCfunctionOrder > 2 + ? here->ISRCcoeffs[2] : (5./ckt->CKTfinalTime); MDI = here->ISRCfunctionOrder > 3 - ? here->ISRCcoeffs[3] : 0.0; - FS = here->ISRCfunctionOrder > 4 + ? here->ISRCcoeffs[3] : 90.0; + FC = here->ISRCfunctionOrder > 4 && here->ISRCcoeffs[4] - ? here->ISRCcoeffs[4] : (1/ckt->CKTfinalTime); + ? here->ISRCcoeffs[4] : (500./ckt->CKTfinalTime); + TD = here->ISRCfunctionOrder > 5 + ? here->ISRCcoeffs[5] : 0; + PHASEM = here->ISRCfunctionOrder > 5 + ? here->ISRCcoeffs[5] : 0.0; + PHASEC = here->ISRCfunctionOrder > 6 + ? here->ISRCcoeffs[6] : 0.0; + + /* limit the modulation index */ + if (MDI > FC / FM) { + MDI = FC / FM; + if (!warn1){ + fprintf(stderr, "Warning: MDI in %s limited to FC/FM\n", here->gen.GENname); + warn1 = TRUE; + } + } + else if (MDI < 0) { + MDI = 0; + if (!warn2) { + fprintf(stderr, "Warning: MDI in %s set to 0\n", here->gen.GENname); + warn2 = TRUE; + } + } + + /* compute phases in radians */ + phasec = PHASEC * M_PI / 180.0; + phasem = PHASEM * M_PI / 180.0; /* compute waveform value */ value = VO + VA * sin((2.0 * M_PI * FC * time + phasec) + - MDI * sin(2.0 * M_PI * FS * time + phases)); + MDI * sin(2.0 * M_PI * FM * time + phasem)); } break; case AM: { - double VA, FC, MF, VO, TD; - double PHASEC, PHASES; - double phasec; - double phases; + double VO, VMO, VMA, FM, FC, TD, PHASEM, PHASEC; + double phasec, phasem; - PHASEC = here->ISRCfunctionOrder > 5 + VO = here->ISRCcoeffs[0]; + VMO = here->ISRCcoeffs[1]; + VMA = here->ISRCfunctionOrder > 2 + ? here->ISRCcoeffs[2] : 1.; + FM = here->ISRCfunctionOrder > 3 + ? here->ISRCcoeffs[3] : (5. / ckt->CKTfinalTime); + FC = here->ISRCfunctionOrder > 4 + ? here->ISRCcoeffs[4] : (500. / ckt->CKTfinalTime); + TD = here->ISRCfunctionOrder > 5 ? here->ISRCcoeffs[5] : 0.0; - PHASES = here->ISRCfunctionOrder > 6 + PHASEM = here->ISRCfunctionOrder > 6 ? here->ISRCcoeffs[6] : 0.0; + PHASEC = here->ISRCfunctionOrder > 7 + ? here->ISRCcoeffs[7] : 0.0; /* compute phases in radians */ phasec = PHASEC * M_PI / 180.0; - phases = PHASES * M_PI / 180.0; - - VA = here->ISRCcoeffs[0]; - VO = here->ISRCcoeffs[1]; - MF = here->ISRCfunctionOrder > 2 - && here->ISRCcoeffs[2] - ? here->ISRCcoeffs[2] : (1/ckt->CKTfinalTime); - FC = here->ISRCfunctionOrder > 3 - ? here->ISRCcoeffs[3] : 0.0; - TD = here->ISRCfunctionOrder > 4 - && here->ISRCcoeffs[4] - ? here->ISRCcoeffs[4] : 0.0; + phasem = PHASEM * M_PI / 180.0; time -= TD; if (time <= 0) { value = 0; } else { /* compute waveform value */ - value = VA * (VO + sin(2.0 * M_PI * MF * time + phases )) * - sin(2.0 * M_PI * FC * time + phases); + value = VO + (VMO + VMA * sin(2.0 * M_PI * FM * time + phasem)) * + sin(2.0 * M_PI * FC * time + phasec); } } break; diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index a93687087..54183aaa5 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -227,72 +227,90 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) case SFFM: { - double VO, VA, FC, MDI, FS; - double PHASEC, PHASES; + double VO, VA, FM, MDI, FC, TD, PHASEM, PHASEC; double phasec; - double phases; - - PHASEC = here->VSRCfunctionOrder > 5 - ? here->VSRCcoeffs[5] : 0.0; - PHASES = here->VSRCfunctionOrder > 6 - ? here->VSRCcoeffs[6] : 0.0; - - /* compute phases in radians */ - phasec = PHASEC * M_PI / 180.0; - phases = PHASES * M_PI / 180.0; + double phasem; + static bool warn1 = FALSE, warn2 = FALSE; VO = here->VSRCcoeffs[0]; VA = here->VSRCcoeffs[1]; - FC = here->VSRCfunctionOrder > 2 - && here->VSRCcoeffs[2] - ? here->VSRCcoeffs[2] : (1/ckt->CKTfinalTime); + FM = here->VSRCfunctionOrder > 2 + ? here->VSRCcoeffs[2] : (5./ckt->CKTfinalTime); MDI = here->VSRCfunctionOrder > 3 - ? here->VSRCcoeffs[3] : 0.0; - FS = here->VSRCfunctionOrder > 4 - && here->VSRCcoeffs[4] - ? here->VSRCcoeffs[4] : (1/ckt->CKTfinalTime); - - /* compute waveform value */ - value = VO + VA * - sin((2.0 * M_PI * FC * time + phasec) + - MDI * sin(2.0 * M_PI * FS * time + phases)); - } - break; - - case AM: { - - double VA, FC, MF, VO, TD; - double PHASEC, PHASES; - double phasec; - double phases; - - PHASEC = here->VSRCfunctionOrder > 5 - ? here->VSRCcoeffs[5] : 0.0; - PHASES = here->VSRCfunctionOrder > 6 + ? here->VSRCcoeffs[3] : 90.0; /* 0.9 * FC / FM */ + FC = here->VSRCfunctionOrder > 4 + && here->VSRCcoeffs[4] /* test if not 0 */ + ? here->VSRCcoeffs[4] : (500./ckt->CKTfinalTime); + TD = here->VSRCfunctionOrder > 5 + ? here->VSRCcoeffs[5] : 0; + PHASEM = here->VSRCfunctionOrder > 6 ? here->VSRCcoeffs[6] : 0.0; + PHASEC = here->VSRCfunctionOrder > 7 + ? here->VSRCcoeffs[7] : 0.0; /* compute phases in radians */ phasec = PHASEC * M_PI / 180.0; - phases = PHASES * M_PI / 180.0; + phasem = PHASEM * M_PI / 180.0; - VA = here->VSRCcoeffs[0]; - VO = here->VSRCcoeffs[1]; - MF = here->VSRCfunctionOrder > 2 - && here->VSRCcoeffs[2] - ? here->VSRCcoeffs[2] : (1/ckt->CKTfinalTime); - FC = here->VSRCfunctionOrder > 3 - ? here->VSRCcoeffs[3] : 0.0; - TD = here->VSRCfunctionOrder > 4 - && here->VSRCcoeffs[4] - ? here->VSRCcoeffs[4] : 0.0; + /* limit the modulation index */ + if (MDI > FC / FM) { + MDI = FC / FM; + if (!warn1){ + fprintf(stderr, "Warning: MDI in %s limited to FC/FM\n", here->gen.GENname); + warn1 = TRUE; + } + } + else if (MDI < 0) { + MDI = 0; + if (!warn2) { + fprintf(stderr, "Warning: MDI in %s set to 0\n", here->gen.GENname); + warn2 = TRUE; + } + } + + time -= TD; + if (time <= 0) { + value = 0; + } + else { + /* compute waveform value */ + value = VO + VA * + sin((2.0 * M_PI * FC * time + phasec) + + MDI * sin(2.0 * M_PI * FM * time + phasem)); + } + } + break; + case AM: { + + double VO, VMO, VMA, FM, FC, TD, PHASEM, PHASEC; + double phasem, phasec; + + VO = here->VSRCcoeffs[0]; + VMO = here->VSRCcoeffs[1]; + VMA = here->VSRCfunctionOrder > 2 + ? here->VSRCcoeffs[2] : 1.; + FM = here->VSRCfunctionOrder > 3 + ? here->VSRCcoeffs[3] : (5. / ckt->CKTfinalTime); + FC = here->VSRCfunctionOrder > 4 + ? here->VSRCcoeffs[4] : (500. / ckt->CKTfinalTime); + TD = here->VSRCfunctionOrder > 5 + ? here->VSRCcoeffs[5] : 0.0; + PHASEM = here->VSRCfunctionOrder > 6 + ? here->VSRCcoeffs[6] : 0.0; + PHASEC = here->VSRCfunctionOrder > 7 + ? here->VSRCcoeffs[7] : 0.0; + + /* compute phases in radians */ + phasec = PHASEC * M_PI / 180.0; + phasem = PHASEM * M_PI / 180.0; time -= TD; if (time <= 0) { value = 0; } else { /* compute waveform value */ - value = VA * (VO + sin(2.0 * M_PI * MF * time + phases )) * - sin(2.0 * M_PI * FC * time + phases); + value = VO + (VMO + VMA * sin(2.0 * M_PI * FM * time + phasem)) * + sin(2.0 * M_PI * FC * time + phasec); } } break; diff --git a/src/spicelib/parser/sperror.c b/src/spicelib/parser/sperror.c index 915afc79c..d669260d6 100644 --- a/src/spicelib/parser/sperror.c +++ b/src/spicelib/parser/sperror.c @@ -42,7 +42,7 @@ const char *SPerror(int type) msg = "no such terminal on this device"; break; case E_BADPARM: - msg = "no such parameter on this device"; + msg = "no such parameter on this device or parameter is missing"; break; case E_NOMEM: msg = "out of memory"; diff --git a/src/xspice/icm/digital/d_cosim/cfunc.mod b/src/xspice/icm/digital/d_cosim/cfunc.mod index fb653a47d..e85d9e5f7 100644 --- a/src/xspice/icm/digital/d_cosim/cfunc.mod +++ b/src/xspice/icm/digital/d_cosim/cfunc.mod @@ -39,7 +39,7 @@ char *dlerror(void) // Lifted from dev.c. if (rc == 0) { /* FormatMessage failed */ (void) sprintf(errstr, errstr_fmt, (unsigned long) GetLastError()); } else { - snprintf(errstr, sizeof errstr, lpMsgBuf); + snprintf(errstr, sizeof errstr, errstr_fmt, lpMsgBuf); LocalFree(lpMsgBuf); } return errstr; diff --git a/src/xspice/icm/digital/d_osc/cfunc.mod b/src/xspice/icm/digital/d_osc/cfunc.mod index e4361e783..8a598bd89 100644 --- a/src/xspice/icm/digital/d_osc/cfunc.mod +++ b/src/xspice/icm/digital/d_osc/cfunc.mod @@ -99,7 +99,7 @@ void cm_d_osc(ARGS) table[i].ctl = PARAM(cntl_array[i]); table[i].freq = PARAM(freq_array[i]); if (table[i].freq <= 0) { - cm_message_printf("Error: frequency %g is not positve, " + cm_message_printf("Error: frequency %g is not positive, " "value replaced by 1e-16.", table[i].freq); table[i].freq = 1.0e-16; diff --git a/src/xspice/icm/digital/d_pwm/cfunc.mod b/src/xspice/icm/digital/d_pwm/cfunc.mod index 908a2b5b3..b3e47fb61 100644 --- a/src/xspice/icm/digital/d_pwm/cfunc.mod +++ b/src/xspice/icm/digital/d_pwm/cfunc.mod @@ -106,7 +106,7 @@ void cm_d_pwm(ARGS) table[i].ctl = PARAM(cntl_array[i]); table[i].dc = PARAM(dc_array[i]); if (table[i].dc <= 0) { - cm_message_printf("Error: duty cycle %g is not positve, " + cm_message_printf("Error: duty cycle %g is not positive, " "value replaced by 0.01.", table[i].dc); table[i].dc = 0.01; diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index 43e4aa7ad..98da3ab21 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -15,7 +15,7 @@ #define PACKAGE "ngspice" /* Version number of package */ -#define VERSION "42" +#define VERSION "42+" /* Define the directory for executables */ #define NGSPICEBINDIR "../bin" diff --git a/visualc/xspice/digital.vcxproj b/visualc/xspice/digital.vcxproj index bd4d42487..53616fa1d 100644 --- a/visualc/xspice/digital.vcxproj +++ b/visualc/xspice/digital.vcxproj @@ -339,6 +339,8 @@ + + @@ -398,4 +400,4 @@ - + \ No newline at end of file