Merge branch 'pre-master' into bt_dev

This commit is contained in:
Brian Taylor 2022-12-07 08:52:58 -08:00
commit ee3c034b18
16 changed files with 300 additions and 41 deletions

View File

@ -242,6 +242,10 @@ This file describes the procedures to install ngspice from sources.
of readline. of readline.
See http://www.thrysoee.dk/editline/ See http://www.thrysoee.dk/editline/
--enable-shortcheck
Enables a 'make check' with strongly reduced runtime. Besides some
regression tests only BSIM3 and BSM4 devices are checked.
1.5.2 Options Specific to Enable Ngspice as a shared library 1.5.2 Options Specific to Enable Ngspice as a shared library
--with-ngshared --with-ngshared

View File

@ -11,7 +11,7 @@ EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \
examples m4 visualc \ examples m4 visualc \
cross-compile.sh cross-compile-shared.sh \ cross-compile.sh cross-compile-shared.sh \
compile_min.sh compile_linux.sh compile_min_shared.sh \ compile_min.sh compile_linux.sh compile_min_shared.sh \
compile_linux_shared.sh \ compile_linux_shared.sh compile_cyg_make_short_check_64.sh \
compile_macos_clang.sh compile_macos_gcc.sh \ compile_macos_clang.sh compile_macos_gcc.sh \
ngspice.pc.in .gitignore ngspice.pc.in .gitignore

View File

@ -0,0 +1,70 @@
#!/bin/bash
# ngspice build script for CYGWIN console (X11), release version, 64 bit
# compile_cyg_make_check.sh
# short version, cd into release64_cyg, then call make, make install, make check
#Procedure:
# Install CYGWIN, plus bison, flex, auto tools, perl, libiconv, libintl
# Install gcc, activate OpenMP support
# start compiling with
# './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.
# --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
if [ ! -d "release64_cyg" ]; then
mkdir release64_cyg
if [ $? -ne 0 ]; then echo "mkdir release64_cyg failed"; exit 1 ; fi
fi
# If compiling sources from CVS, you may need to uncomment the following two lines:
./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-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
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
echo "installing (see make_install.log)"
make install 2>&1 -j8 | tee make_install.log
exitcode=${PIPESTATUS[0]}
if [ $exitcode -ne 0 ]; then echo "make install failed"; exit 1 ; fi
echo "run make check"
make check 2>&1 -j8 | tee make_check.log
exitcode=${PIPESTATUS[0]}
if [ $exitcode -ne 0 ]; then
echo "make check failed";
echo "Did you consider setting 'set ngbehavior=mc' in .spiceinit?";
exit 1 ;
fi
echo "success"
exit 0

View File

@ -0,0 +1,14 @@
dd test
V1 1 0 dc 0 pulse 0 2 0 1 1 1 4
B2 2 0 v = ddt(V(1))
.tran 1m 8
.control
run
plot v(1) v(2)
.endc
.end

View File

@ -0,0 +1,18 @@
ddt test 2 with .func
V1 1 0 dc 0 pulse 0 2 0 1 1 1 4
B2 2 0 v = ddt(V(1))
B3 3 0 v = border(v(1))
.func border(x) if (ddt(x) > 0, 1, 0)
.tran 1m 8
.control
run
plot v(1) v(2) v(3)
.endc
.end

View File

@ -0,0 +1,17 @@
ddt test 3 with RC
V1 1 0 dc 0 pulse 0 2 1u 1n 1n 100u 200u
R1 1 2 1k
C1 2 0 1u
B2 22 0 v = ddt(V(2))/1000
.tran 100n 3m
.control
run
plot v(2) v(22)
*print v(22)
.endc
.end

View File

@ -1,14 +1,16 @@
*****Single NMOS and PMOS Transistor For BSIM3 threshold voltage check (Id-Vgs) (Id-Vds) *** ** Single NMOS and PMOS, BSIM3, (Id-Vgs) (Id-Vds) **
M1 2 1 3 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p M1 2 1 3 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p
vgs 1 0 3.5 vgsn 1 0 3.5
vds 2 0 0.1 vdsn 102 0 0.1
vss 3 0 0 Rdn 102 2 1k
vbs 4 0 0 vssn 3 0 0
vbsn 4 0 0
M2 22 11 33 44 p1 W=2.5u L=0.35u Pd=3u Ps=3u ad=2.5p as=2.5p M2 22 11 33 44 p1 W=2.5u L=0.35u Pd=3u Ps=3u ad=2.5p as=2.5p
vgsp 11 0 -3.5 vgsp 11 0 -3.5
vdsp 22 0 -0.1 vdsp 222 0 -0.1
Rdp 222 22 1k
vssp 33 0 0 vssp 33 0 0
vbsp 44 0 0 vbsp 44 0 0
@ -27,18 +29,18 @@ vbsp 44 0 0
.control .control
* various plot font sizes * various plot font sizes
dc vgs 0 1.5 0.05 vbs 0 -2.5 -0.5 dc vgsn 0 1.5 0.02 vbsn 0 -2.5 -0.5
plot vss#branch ylabel 'output current' plot vssn#branch ylabel 'output current'
set wfont_size=18 set wfont_size=16
dc vds 0 2 0.05 vgs 0 2 0.4 dc vdsn 0 2 0.05 vgsn 0 2 0.4
plot vss#branch ylabel 'output current' plot vssn#branch vs v(2) ylabel 'output current'
set wfont_size=20 set wfont_size=24
dc vgsp 0 -1.5 -0.05 vbsp 0 2.5 0.5 dc vgsp 0 -1.5 -0.02 vbsp 0 2.5 0.5
plot vssp#branch ylabel 'output current' plot vssp#branch ylabel 'output current'
set wfont=Times set wfont=Times
set wfont_size=18 set wfont_size=22
dc vdsp 0 -2 -0.05 vgsp 0 -2 -0.4 dc vdsp 0 -2 -0.05 vgsp 0 -2 -0.4
plot vssp#branch ylabel 'output current' plot vssp#branch vs v(22) ylabel 'output current'
.endc .endc
.end .end

View File

@ -9,6 +9,7 @@ r2 c vp 1k
.control .control
op op
tran 50p 100n tran 50p 100n
set xbrushwidth=2
plot v(in) v(b) v(c) v(vp) plot v(in) v(b) v(c) v(vp)
settype temperature v(t) settype temperature v(t)
plot v(t) plot v(t)

View File

@ -1215,23 +1215,25 @@ static char* get_terminal_number(char* element, char* namestr)
Called from inp.c*/ Called from inp.c*/
void modprobenames(INPtables* tab) { void modprobenames(INPtables* tab) {
GENinstance* GENinst; GENinstance* GENinst;
for (GENinst = tab->defVmod->GENinstances; GENinst; GENinst = GENinst->GENnextInstance) { if (tab->defVmod) {
char* name = GENinst->GENname; for (GENinst = tab->defVmod->GENinstances; GENinst; GENinst = GENinst->GENnextInstance) {
if (prefix("vcurr_", name)) { char* name = GENinst->GENname;
/* copy from char no. 6 to (and excluding) second colon */ if (prefix("vcurr_", name)) {
char* endname = strchr(name, ':'); /* copy from char no. 6 to (and excluding) second colon */
char* endname2 = strchr(endname + 1, ':'); char* endname = strchr(name, ':');
/* two-terminal device, one colon, copy all from char no. 6 to (and excluding) colon */ char* endname2 = strchr(endname + 1, ':');
if (!endname2) { /* two-terminal device, one colon, copy all from char no. 6 to (and excluding) colon */
char* newname = copy_substring(name + 6, endname); if (!endname2) {
memcpy(name, newname, strlen(newname) + 1); char* newname = copy_substring(name + 6, endname);
tfree(newname); memcpy(name, newname, strlen(newname) + 1);
} tfree(newname);
/* copy from char no. 6 to (and excluding) second colon */ }
else { /* copy from char no. 6 to (and excluding) second colon */
char* newname = copy_substring(name + 6, endname2); else {
memcpy(name, newname, strlen(newname) + 1); char* newname = copy_substring(name + 6, endname2);
tfree(newname); memcpy(name, newname, strlen(newname) + 1);
tfree(newname);
}
} }
} }
} }

View File

@ -20,7 +20,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
static void plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, static void plotinterval(struct dvec *v, double lo, double hi, register double *coeffs,
int degree, bool rotated); int degree, bool rotated);
static int get_xdirection(struct dvec *xs, int len, bool mn);
/* Plot the vector v, with scale xs. If we are doing curve-fitting, then /* Plot the vector v, with scale xs. If we are doing curve-fitting, then
* do some tricky stuff. * do some tricky stuff.
@ -146,7 +146,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
Then everything is plotted. */ Then everything is plotted. */
bool mono = (currentgraph->plottype != PLOT_RETLIN); bool mono = (currentgraph->plottype != PLOT_RETLIN);
int dir = 0; int dir = get_xdirection(xs, length, mono);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
dx = isreal(xs) ? xs->v_realdata[i] : dx = isreal(xs) ? xs->v_realdata[i] :
realpart(xs->v_compdata[i]); realpart(xs->v_compdata[i]);
@ -158,8 +158,6 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
gr_point(v, dx, dy, lx, ly, 0); gr_point(v, dx, dy, lx, ly, 0);
} else { } else {
gr_point(v, dx, dy, lx, ly, i); gr_point(v, dx, dy, lx, ly, i);
if (!dir)
dir = lx > dx ? -1 : lx < dx ? 1 : 0;
} }
lx = dx; lx = dx;
ly = dy; ly = dy;
@ -358,3 +356,40 @@ plotinterval(struct dvec *v, double lo, double hi, register double *coeffs, int
/* fprintf(cp_err, "plot (%G, %G)\n\r", dx, dy); */ /* fprintf(cp_err, "plot (%G, %G)\n\r", dx, dy); */
} }
} }
/* Check if the majority of the x-axis data points are increasing or decreasing.
If more than 10% of the data points deviate from the majority direction, issue a warning,
if 'retraceplot' is not set.
*/
static int get_xdirection(struct dvec* xs, int len, bool mn) {
int i, dir = 1, inc = 0, dec = 0;
double dx, lx;
static bool msgsent = FALSE;
lx = isreal(xs) ? xs->v_realdata[0] :
realpart(xs->v_compdata[0]);
for (i = 1; i < len; i++) {
dx = isreal(xs) ? xs->v_realdata[i] :
realpart(xs->v_compdata[i]);
if (dx > lx)
inc++;
else if (dx < lx)
dec++;
lx = dx;
}
if (inc < 2 && dec < 2)
fprintf(stderr, "Warning, (new) x axis seems to have one data point only\n");
if (mn && !msgsent && (((double)inc / len > 0.1 && inc < dec) || ((double)dec / len > 0.1 && inc > dec))) {
fprintf(stderr, "Warning, more than 10%% of scale vector %s data points are not monotonic.\n", xs->v_name);
fprintf(stderr, " Please consider using the 'retraceplot' flag to the plot command to plot all data.\n");
msgsent = TRUE;
}
if (inc < dec)
dir = -1;
return dir;
}

View File

@ -129,6 +129,7 @@ void INPptPrint(char *str, IFparseTree * ptree);
#define PTF_CEIL 34 #define PTF_CEIL 34
#define PTF_FLOOR 35 #define PTF_FLOOR 35
#define PTF_NINT 36 #define PTF_NINT 36
#define PTF_DDT 37
/* The following things are used by the parser -- these are the token types the /* The following things are used by the parser -- these are the token types the
* lexer returns. * lexer returns.

View File

@ -365,6 +365,12 @@ com_snsave(wordlist *wl)
NG_IGNORE(wl); NG_IGNORE(wl);
} }
void
com_optran(wordlist *wl)
{
NG_IGNORE(wl);
}
void void
SMPprint(SMPmatrix *n1, char *n2) SMPprint(SMPmatrix *n1, char *n2)
{ {
@ -428,6 +434,12 @@ EVTswitch_plot(CKTcircuit* ckt, const char* plottypename)
return 1; return 1;
}; };
void
EVTsave(wordlist* wl)
{
NG_IGNORE(wl);
}
int int
load_opus(const char *name) load_opus(const char *name)
{ {

View File

@ -38,6 +38,7 @@ struct plot *plot_cur = NULL;
int cp_maxhistlength = 0; int cp_maxhistlength = 0;
bool cp_no_histsubst = FALSE; bool cp_no_histsubst = FALSE;
struct compat newcompat; struct compat newcompat;
bool cx_degrees = FALSE;
char *cp_program = "sconvert"; char *cp_program = "sconvert";

View File

@ -171,6 +171,7 @@ static struct func {
{ "pwr", PTF_PWR, (void(*)(void)) PTpwr}, { "pwr", PTF_PWR, (void(*)(void)) PTpwr},
{ "min", PTF_MIN, (void(*)(void)) PTmin}, { "min", PTF_MIN, (void(*)(void)) PTmin},
{ "max", PTF_MAX, (void(*)(void)) PTmax}, { "max", PTF_MAX, (void(*)(void)) PTmax},
{ "ddt", PTF_DDT, (void(*)(void)) PTddt},
} ; } ;
#define NUM_FUNCS (int)NUMELEMS(funcs) #define NUM_FUNCS (int)NUMELEMS(funcs)
@ -566,6 +567,11 @@ static INPparseNode *PTdifferentiate(INPparseNode * p, int varnum)
arg1 = mkcon(0.0); arg1 = mkcon(0.0);
break; break;
case PTF_DDT:
arg1 = mkcon(0.0);
arg1->data = p->data;
break;
case PTF_MIN: case PTF_MIN:
case PTF_MAX: case PTF_MAX:
/* min(a,b) --> (a<b) ? a : b /* min(a,b) --> (a<b) ? a : b
@ -1080,6 +1086,20 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *p)
return (p); return (p);
} }
static INPparseNode* prepare_PTF_DDT(INPparseNode* p)
{
struct ddtdata { int n; double* vals; } *data;
int i, ii;
/* store 3 recent times and 3 recent values in pairs t0, v0, t1, v1, t2, v2 */
i = 0;
data = TMALLOC(struct ddtdata, 1);
data->vals = TMALLOC(double, 7);
for (ii = 0; ii < 7; ii++) {
data->vals[ii] = 0;
}
p->data = (void*)data;
return (p);
}
INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg) INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg)
{ {
@ -1140,6 +1160,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg)
if(p->funcnum == PTF_PWL) if(p->funcnum == PTF_PWL)
p = prepare_PTF_PWL(p); p = prepare_PTF_PWL(p);
if (p->funcnum == PTF_DDT)
p = prepare_PTF_DDT(p);
return (p); return (p);
} }
@ -1573,6 +1596,14 @@ void free_tree(INPparseNode *pt)
} }
} }
if (pt->type == PT_FUNCTION && (pt->funcnum == PTF_DDT)) {
struct ddtdata { int n; double* vals; } *data = (struct ddtdata*)(pt->data);
if (data) {
txfree(data->vals);
txfree(data);
}
}
txfree(pt); txfree(pt);
} }

View File

@ -78,5 +78,6 @@ double PTle0(double arg);
double PTceil(double arg); double PTceil(double arg);
double PTfloor(double arg); double PTfloor(double arg);
double PTnint(double arg); double PTnint(double arg);
double PTddt(double arg, void* data);
#endif #endif

View File

@ -13,12 +13,10 @@ Author: 1987 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice/fteext.h" #include "ngspice/fteext.h"
#include "ngspice/ifsim.h" #include "ngspice/ifsim.h"
#include "ngspice/inpptree.h" #include "ngspice/inpptree.h"
#include "ngspice/cktdefs.h"
#include "inpxx.h" #include "inpxx.h"
#include "ngspice/compatmode.h" #include "ngspice/compatmode.h"
/* XXX These should be in math.h */
double PTfudge_factor; double PTfudge_factor;
#define MODULUS(NUM,LIMIT) ((NUM) - ((int) ((NUM) / (LIMIT))) * (LIMIT)) #define MODULUS(NUM,LIMIT) ((NUM) - ((int) ((NUM) / (LIMIT))) * (LIMIT))
@ -414,3 +412,55 @@ PTnint(double arg1)
*/ */
return nearbyint(arg1); return nearbyint(arg1);
} }
/* Calculate the derivative during a transient simulation.
If time == 0, return 0.
If not transient sim, return 0.
The derivative is then (y2-y1)/(t2-t1).
*/
double
PTddt(double arg, void* data)
{
struct ddtdata { int n; double* vals; } *thing = (struct ddtdata*)data;
double y, time;
CKTcircuit* ckt = ft_curckt->ci_ckt;
time = ckt->CKTtime;
if (time == 0) {
thing->vals[3] = arg;
return 0;
}
if (!(ckt->CKTmode & MODETRAN))
return 0;
if (time > thing->vals[0]) {
thing->vals[4] = thing->vals[2];
thing->vals[5] = thing->vals[3];
thing->vals[2] = thing->vals[0];
thing->vals[3] = thing->vals[1];
thing->vals[0] = time;
thing->vals[1] = arg;
/* // Some less effective smoothing option
if (thing->vals[2] > 0) {
thing->vals[6] = 0.5 * ((arg - thing->vals[3]) / (time - thing->vals[2]) + thing->vals[6]);
}
*/
if (thing->n > 1) {
thing->vals[6] = (thing->vals[1] - thing->vals[3]) / (thing->vals[2] - thing->vals[4]);
}
else {
thing->vals[6] = 0;
thing->vals[3] = arg;
}
thing->n += 1;
}
y = thing->vals[6];
return y;
}