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.
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
--with-ngshared

View File

@ -11,7 +11,7 @@ EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \
examples m4 visualc \
cross-compile.sh cross-compile-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 \
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
vgs 1 0 3.5
vds 2 0 0.1
vss 3 0 0
vbs 4 0 0
vgsn 1 0 3.5
vdsn 102 0 0.1
Rdn 102 2 1k
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
vgsp 11 0 -3.5
vdsp 22 0 -0.1
vgsp 11 0 -3.5
vdsp 222 0 -0.1
Rdp 222 22 1k
vssp 33 0 0
vbsp 44 0 0
@ -27,18 +29,18 @@ vbsp 44 0 0
.control
* various plot font sizes
dc vgs 0 1.5 0.05 vbs 0 -2.5 -0.5
plot vss#branch ylabel 'output current'
set wfont_size=18
dc vds 0 2 0.05 vgs 0 2 0.4
plot vss#branch ylabel 'output current'
set wfont_size=20
dc vgsp 0 -1.5 -0.05 vbsp 0 2.5 0.5
dc vgsn 0 1.5 0.02 vbsn 0 -2.5 -0.5
plot vssn#branch ylabel 'output current'
set wfont_size=16
dc vdsn 0 2 0.05 vgsn 0 2 0.4
plot vssn#branch vs v(2) ylabel 'output current'
set wfont_size=24
dc vgsp 0 -1.5 -0.02 vbsp 0 2.5 0.5
plot vssp#branch ylabel 'output current'
set wfont=Times
set wfont_size=18
set wfont_size=22
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
.end

View File

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

View File

@ -1215,23 +1215,25 @@ static char* get_terminal_number(char* element, char* namestr)
Called from inp.c*/
void modprobenames(INPtables* tab) {
GENinstance* GENinst;
for (GENinst = tab->defVmod->GENinstances; GENinst; GENinst = GENinst->GENnextInstance) {
char* name = GENinst->GENname;
if (prefix("vcurr_", name)) {
/* copy from char no. 6 to (and excluding) second colon */
char* endname = strchr(name, ':');
char* endname2 = strchr(endname + 1, ':');
/* two-terminal device, one colon, copy all from char no. 6 to (and excluding) colon */
if (!endname2) {
char* newname = copy_substring(name + 6, endname);
memcpy(name, newname, strlen(newname) + 1);
tfree(newname);
}
/* copy from char no. 6 to (and excluding) second colon */
else {
char* newname = copy_substring(name + 6, endname2);
memcpy(name, newname, strlen(newname) + 1);
tfree(newname);
if (tab->defVmod) {
for (GENinst = tab->defVmod->GENinstances; GENinst; GENinst = GENinst->GENnextInstance) {
char* name = GENinst->GENname;
if (prefix("vcurr_", name)) {
/* copy from char no. 6 to (and excluding) second colon */
char* endname = strchr(name, ':');
char* endname2 = strchr(endname + 1, ':');
/* two-terminal device, one colon, copy all from char no. 6 to (and excluding) colon */
if (!endname2) {
char* newname = copy_substring(name + 6, endname);
memcpy(name, newname, strlen(newname) + 1);
tfree(newname);
}
/* copy from char no. 6 to (and excluding) second colon */
else {
char* newname = copy_substring(name + 6, endname2);
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,
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
* do some tricky stuff.
@ -146,7 +146,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart)
Then everything is plotted. */
bool mono = (currentgraph->plottype != PLOT_RETLIN);
int dir = 0;
int dir = get_xdirection(xs, length, mono);
for (i = 0; i < length; i++) {
dx = isreal(xs) ? xs->v_realdata[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);
} else {
gr_point(v, dx, dy, lx, ly, i);
if (!dir)
dir = lx > dx ? -1 : lx < dx ? 1 : 0;
}
lx = dx;
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); */
}
}
/* 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_FLOOR 35
#define PTF_NINT 36
#define PTF_DDT 37
/* The following things are used by the parser -- these are the token types the
* lexer returns.

View File

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

View File

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

View File

@ -171,6 +171,7 @@ static struct func {
{ "pwr", PTF_PWR, (void(*)(void)) PTpwr},
{ "min", PTF_MIN, (void(*)(void)) PTmin},
{ "max", PTF_MAX, (void(*)(void)) PTmax},
{ "ddt", PTF_DDT, (void(*)(void)) PTddt},
} ;
#define NUM_FUNCS (int)NUMELEMS(funcs)
@ -566,6 +567,11 @@ static INPparseNode *PTdifferentiate(INPparseNode * p, int varnum)
arg1 = mkcon(0.0);
break;
case PTF_DDT:
arg1 = mkcon(0.0);
arg1->data = p->data;
break;
case PTF_MIN:
case PTF_MAX:
/* min(a,b) --> (a<b) ? a : b
@ -1080,6 +1086,20 @@ static INPparseNode *prepare_PTF_PWL(INPparseNode *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)
{
@ -1140,6 +1160,9 @@ INPparseNode *PT_mkfnode(const char *fname, INPparseNode * arg)
if(p->funcnum == PTF_PWL)
p = prepare_PTF_PWL(p);
if (p->funcnum == PTF_DDT)
p = prepare_PTF_DDT(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);
}

View File

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

View File

@ -13,12 +13,10 @@ Author: 1987 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice/fteext.h"
#include "ngspice/ifsim.h"
#include "ngspice/inpptree.h"
#include "ngspice/cktdefs.h"
#include "inpxx.h"
#include "ngspice/compatmode.h"
/* XXX These should be in math.h */
double PTfudge_factor;
#define MODULUS(NUM,LIMIT) ((NUM) - ((int) ((NUM) / (LIMIT))) * (LIMIT))
@ -414,3 +412,55 @@ PTnint(double 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;
}