Merge branch 'pre-master' into bt_dev
This commit is contained in:
commit
ee3c034b18
4
INSTALL
4
INSTALL
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
12
src/main.c
12
src/main.c
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue