Merge branch 'pre-master' into bt_dev

This commit is contained in:
Brian Taylor 2023-06-24 17:34:02 -07:00
commit 56362529ba
17 changed files with 156 additions and 60 deletions

View File

@ -69,7 +69,7 @@ save cont s1 s2 u1 d1
set xbrushwidth=2
let isbmode = $?batchmode
if isbmode = 0
iplot -w $&simtime cont
iplot -w $&simtime -d 4000 cont
endif
* calculate breakpoint for switching frequency
let t1_3 = simtime/3

View File

@ -64,7 +64,7 @@ abridge-w1 [d_divout d_ref d_Un d_D] [s1 s2 u1n d1] dac1 ; change to d_u or d_Un
.control
save cont s1 s2 u1n d1 v.xlf.vdd#branch; to save memory
iplot cont
iplot -d 4000 cont
tran 0.1n $&simtime uic
rusage
plot cont s1 s2+1.2 u1n+2.4 d1+3.6 xlimit 4u 5u

View File

@ -205,36 +205,50 @@ com_iplot(wordlist *wl)
/* settrace(wl, VF_PLOT); */
struct dbcomm *d, *td, *currentdb = NULL;
double window;
double window = 0.0;
int initial_steps = IPOINTMIN;
char *s;
/* Look for "-w window-size" at the front, indicating a windowed iplot. */
/* Look for "-w window-size" at the front, indicating a windowed iplot
* or "-d steps" to set the initial delay before the window appears.
*/
if (wl->wl_next && !strcmp("-w", wl->wl_word)) {
char *cp;
int error;
while (wl && wl->wl_word[0] == '-') {
if (wl->wl_word[1] == 'w' && !wl->wl_word[2]) {
wl = wl->wl_next;
if (wl) {
char *cp;
int error;
wl = wl->wl_next;
cp = wl->wl_word;
window = INPevaluate(&cp, &error, 0);
if (error || window <= 0) {
fprintf(cp_err, "Incremental plot width must be positive.\n");
return;
cp = wl->wl_word;
window = INPevaluate(&cp, &error, 0);
if (error || window <= 0) {
fprintf(cp_err,
"Incremental plot width must be positive.\n");
return;
}
}
} else if (wl->wl_word[1] == 'd' && !wl->wl_word[2]) {
wl = wl->wl_next;
if (wl)
initial_steps = atoi(wl->wl_word);
} else {
break;
}
wl = wl->wl_next;
} else {
window = 0.0;
}
/* We use a modified ad-hoc algorithm here where db_also denotes
vectors on the same command line and db_next denotes
separate iplot commands. */
while (wl) {
s = cp_unquote(wl->wl_word);
d = TMALLOC(struct dbcomm, 1);
d->db_analysis = NULL;
d->db_number = debugnumber++;
d->db_value1 = window; // Field re-use
d->db_op = initial_steps; // Field re-use
d->db_value1 = window; // Field re-use
if (eq(s, "all")) {
d->db_type = DB_IPLOTALL;
} else {

View File

@ -11,6 +11,7 @@
#include "ngspice/fteext.h"
#include "ngspice/cpextern.h"
#include "ngspice/randnumb.h"
#include "ngspice/evtproto.h"
#include "com_compose.h"
#include "completion.h"
@ -225,9 +226,26 @@ com_compose(wordlist *wl)
}
length *= blocksize;
}
else {
#ifdef XSPICE
} else if (eq(wl->wl_word, "xspice")) {
/* Make vectors from an event node. */
result = EVTfindvec(resname);
if (result == NULL) {
fprintf(cp_err, "There is no event node %s or it has no data\n",
resname);
goto done;
}
result->v_flags |= VF_PERMANENT;
result->v_scale->v_flags |= VF_PERMANENT;
vec_new(result->v_scale);
cp_addkword(CT_VECTOR, result->v_scale->v_name);
txfree(resname); // It was copied
goto finished;
#endif
} else {
/* Parse the line... */
while (wl) {
char *s, *var, *val;
if ((s = strchr(wl->wl_word, '=')) != NULL && s[1]) {
@ -600,6 +618,7 @@ com_compose(wordlist *wl)
/* The allocation for resname has been assigned to the result vector, so
* set to NULL so that it is not freed */
finished:
resname = NULL;
/* Set dimension info */

View File

@ -9,30 +9,64 @@
#include "plotting/pvec.h"
#include "ngspice/fteext.h"
static struct dvec *find_vec(wordlist *wl)
{
struct dvec *d;
char *s;
s = cp_unquote(wl->wl_word);
if (s) {
d = vec_get(s);
tfree(s); /*DG to avoid the cp_unquote memory leak */
} else {
d = NULL;
}
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word);
return d;
}
/* Set the default scale to the named vector. If no vector named,
* find and print the default scale. */
void
com_setscale(wordlist *wl)
{
struct dvec *d;
char *s;
struct dvec *d, *ds;
if (plot_cur) {
if (wl) {
s = cp_unquote(wl->wl_word);
d = vec_get(s);
if (s)
tfree(s);/*DG to avoid the cp_unquote memory leak */
if (d == NULL)
fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word);
else
plot_cur->pl_scale = d;
} else if (plot_cur->pl_scale) {
pvec(plot_cur->pl_scale);
}
} else {
if (!plot_cur) {
fprintf(cp_err, "Error: no current plot.\n");
return;
}
if (!wl) {
if (plot_cur->pl_scale)
pvec(plot_cur->pl_scale);
return;
}
d = find_vec(wl);
if (d == NULL)
return;
/* Two-word form for altering the scale of a specific vector?
* Keyword "none" clears the scale so that the plot's default scale
* will be used.
*/
wl = wl->wl_next;
if (wl) {
if (!strcmp(wl->wl_word, "none")) {
d->v_scale = NULL;
return;
}
ds = find_vec(wl);
if (ds == NULL)
return;
d->v_scale = ds;
} else {
plot_cur->pl_scale = d;
}
}

View File

@ -14,13 +14,14 @@
#ifdef _WIN32
#define SHELL "cmd /k"
#else
#define SHELL "/bin/csh"
#define SHELL "/bin/sh"
#endif
/* Fork a shell. */
void
com_shell(wordlist *wl)
{
int status;
char *shell = NULL;
shell = getenv("SHELL");
@ -61,16 +62,20 @@ com_shell(wordlist *wl)
/* Easier to forget about changing the io descriptors. */
if (wl) {
char * const com = wl_flatten(wl);
if (system(com) == -1) {
status = system(com);
if (status == -1) {
(void) fprintf(cp_err, "Unable to execute \"%s\".\n", com);
}
txfree(com);
}
else {
if (system(shell) == -1) {
status = system(shell);
if (status == -1) {
(void) fprintf(cp_err, "Unable to execute \"%s\".\n", shell);
}
}
cp_vset("shellstatus", CP_NUM, &status);
#endif
} /* end of function com_shell */

View File

@ -195,9 +195,10 @@ struct comm spcp_coms[] = {
NULL,
"[circuit name] : Change the current circuit." } ,
{ "setscale", com_setscale, FALSE, FALSE,
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1,
{ 040000, 0, 0, 0 }, E_DEFHMASK, 0, 2,
NULL,
"[vecname] : Change default scale of current working plot." } ,
"[vecname [vecname]] : Change default scale of current working plot"
"\n or set/clear the scale for a single vector." } ,
{ "setseed", com_sseed, FALSE, FALSE,
{ 04, 0, 0, 0 }, E_DEFHMASK, 0, 1,
NULL,
@ -426,7 +427,7 @@ struct comm spcp_coms[] = {
{ "iplot", com_iplot, TRUE, TRUE,
{ 0200, 0200, 0200, 0200 }, E_DEFHMASK, 0, LOTS,
NULL,
"[-w width] [all] [node ...] : Incrementally plot nodes." } ,
"[-w width] [-s initial_steps] [all] [node ...] : Incrementally plot nodes." } ,
{ "status", com_sttus, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
NULL,

View File

@ -1340,6 +1340,7 @@ inp_dodeck(
g_ipc.syntax_error = IPC_TRUE;
#endif
p = dd->error;
fflush(stdout);
do {
q = strchr(p, '\n');
if (q)
@ -1348,7 +1349,7 @@ inp_dodeck(
if (p == dd->error) {
if (strstr(dd->line, ".model"))
fprintf(stderr, "Warning: Model issue on line %d :\n %.*s ...\n%s\n",
dd->linenum_orig, 72, dd->line, dd->error);
dd->linenum_orig, 72, dd->line, dd->error);
else if (dd->linenum_orig == 0) {
fprintf(stderr, "Error on line:\n %s\n%s\n",
dd->line, dd->error);
@ -1364,13 +1365,13 @@ inp_dodeck(
if (ft_stricterror)
controlled_exit(EXIT_BAD);
} else {
out_printf("%s\n", p);
fprintf(stderr, "%s\n", p);
}
if (q)
*q++ = '\n';
p = q;
} while (p && *p);
fprintf(stderr, "\n");
} /* end if (dd->error) */
} /* for (dd = deck; dd; dd = dd->nextcard) */

View File

@ -629,6 +629,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stdout, " Reference value : % 12.5e\r",
refValue->cValue.real);
fflush(stdout);
lastclock = currclock;
}
}
@ -642,6 +643,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stdout, " Reference value : % 12.5e\r",
refValue->rValue);
fflush(stdout);
lastclock = currclock;
}
}
@ -741,6 +743,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
fprintf(stdout, " Reference value : % 12.5e\r",
refValue ? refValue->rValue : NAN);
}
fflush(stdout);
lastclock = currclock;
}
}
@ -1508,6 +1511,7 @@ InterpFileAdd(runDesc *run, IFvalue *refValue, IFvalue *valuePtr)
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stdout, " Reference value : % 12.5e\r",
refValue->rValue);
fflush(stdout);
lastclock = currclock;
}
}
@ -1672,6 +1676,7 @@ InterpPlotAdd(runDesc *run, IFvalue *refValue, IFvalue *valuePtr)
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
fprintf(stdout, " Reference value : % 12.5e\r",
refValue->rValue);
fflush(stdout);
lastclock = currclock;
}
}

View File

@ -855,7 +855,7 @@ static int iplot(struct plot *pl, struct dbcomm *db)
/* Do simple check for exit first */
window = db->db_value1;
if (len < 2 || (window == 0.0 && len < IPOINTMIN)) { /* Nothing yet */
if (len < 2 || db->db_op > len) { /* Nothing yet */
return 0;
}

View File

@ -859,7 +859,11 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
int ii = 0, jj = 0;
for (d = vecs; d; d = d->v_link2) {
if (d->v_scale && eq(d->v_scale->v_name, "step") && (d->v_scale->v_type == SV_TIME) && (d->v_type == SV_VOLTAGE) && (d->v_length > 1)) {
if ((d->v_flags & VF_EVENT_NODE) &&
!(d->v_flags & VF_PERMANENT) &&
d->v_scale && (d->v_scale->v_flags & VF_EVENT_NODE) &&
(d->v_scale->v_type == SV_TIME) && (d->v_type == SV_VOLTAGE) &&
(d->v_length > 1)) {
for (ii = 0; ii < d->v_length; ii++) {
d->v_realdata[ii] += nn;
}

View File

@ -449,17 +449,24 @@ X11_NewViewport(GRAPH *graph)
static Arg formargs[ ] = {
{ XtNleft, (XtArgVal) XtChainLeft },
{ XtNresizable, (XtArgVal) TRUE }
{ XtNresizable, (XtArgVal) TRUE },
{ XtNbackground, (XtArgVal) 0x191942} // MidnightBlue
};
static Arg bboxargs[ ] = {
{ XtNfromHoriz, (XtArgVal) NULL },
{ XtNbottom, (XtArgVal) XtChainTop },
{ XtNtop, (XtArgVal) XtChainTop },
{ XtNleft, (XtArgVal) XtChainRight },
{ XtNright, (XtArgVal) XtChainRight }
{ XtNright, (XtArgVal) XtChainRight },
{ XtNbackground, (XtArgVal) 0xbebebe}
};
static Arg quitbuttonargs[ ] = {
{ XtNlabel, (XtArgVal) "Quit" },
{ XtNbackground, (XtArgVal) 0xff4500} // OrangeRed
};
static Arg buttonargs[ ] = {
{ XtNlabel, (XtArgVal) NULL }
{ XtNlabel, (XtArgVal) NULL },
{ XtNbackground, (XtArgVal) 0x87cefa} // LightSkyBlue
};
static Arg viewargs[] = {
{ XtNresizable, (XtArgVal) TRUE },
@ -500,21 +507,18 @@ X11_NewViewport(GRAPH *graph)
("buttonbox", boxWidgetClass, DEVDEP(graph).form, bboxargs, XtNumber(bboxargs));
/* set up buttons */
XtSetArg(buttonargs[0], XtNlabel, "Quit");
XtSetArg(bboxargs[1], XtNfromVert, NULL);
DEVDEP(graph).buttons[0] = XtCreateManagedWidget
("quit", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1);
("quit", commandWidgetClass, DEVDEP(graph).buttonbox, quitbuttonargs, 2);
XtAddCallback(DEVDEP(graph).buttons[0], XtNcallback, killwin, graph);
XtSetArg(buttonargs[0], XtNlabel, "PostScript");
XtSetArg(bboxargs[1], XtNfromVert, DEVDEP(graph).buttons[0]);
DEVDEP(graph).buttons[1] = XtCreateManagedWidget
("hardcopy", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1);
("hardcopy", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 2);
XtAddCallback(DEVDEP(graph).buttons[1], XtNcallback, hardcopy, graph);
XtSetArg(buttonargs[0], XtNlabel, "SVG");
DEVDEP(graph).buttons[2] = XtCreateManagedWidget(
"SVG", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 1);
"SVG", commandWidgetClass, DEVDEP(graph).buttonbox, buttonargs, 2);
XtAddCallback(DEVDEP(graph).buttons[2], XtNcallback, hardcopySVG, graph);
/* set up fonts */

View File

@ -16,7 +16,8 @@ enum dvec_flags {
VF_PRINT = (1 << 4), /* writedata should print this vector. */
VF_MINGIVEN = (1 << 5), /* The v_minsignal value is valid. */
VF_MAXGIVEN = (1 << 6), /* The v_maxsignal value is valid. */
VF_PERMANENT = (1 << 7) /* Don't garbage collect this vector. */
VF_PERMANENT = (1 << 7), /* Don't garbage collect this vector. */
VF_EVENT_NODE = (1 << 8) /* Derived from and XSPICE event node. */
};

View File

@ -34,6 +34,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#define DBC_GTE 5 /* >= (ge) */
#define DBC_LTE 6 /* <= (le) */
/* Below, members db_op and db_value1 are re-purposed by iplot options. */
struct dbcomm {
int db_number; /* The number of this debugging command. */
char db_type; /* One of the above. */
@ -41,7 +43,7 @@ struct dbcomm {
char *db_nodename2; /* What node. */
char *db_analysis; /* for a specific analysis. */
int db_iteration; /* For the DB_STOPAFTER command. */
char db_op; /* For DB_STOPWHEN. */
int db_op; /* For DB_STOPWHEN. */
double db_value1; /* If this is DB_STOPWHEN. */
double db_value2; /* If this is DB_STOPWHEN. */
int db_graphid; /* If iplot, id of graph. */

View File

@ -172,7 +172,11 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
period = end -
here->VSRCcoeffs[here->VSRCrBreakpt];
time -=
here->VSRCcoeffs[here->VSRCrBreakpt];
time -= period * floor(time / period);
time +=
here->VSRCcoeffs[here->VSRCrBreakpt];
} else {
here->VSRCbreak_time = ckt->CKTfinalTime;
break;

View File

@ -318,6 +318,7 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
period = end_time -
here->VSRCcoeffs[here->VSRCrBreakpt];
time -= here->VSRCcoeffs[here->VSRCrBreakpt];
time -= period * floor(time / period);
time += here->VSRCcoeffs[here->VSRCrBreakpt];
} else {

View File

@ -206,14 +206,15 @@ struct dvec *EVTfindvec(
/* Allocate dvec structures and assign the vectors into them. */
/* See FTE/OUTinterface.c:plotInit() for initialization example. */
scale = dvec_alloc(MIFcopy("step"),
ptr = tprintf("%s_steps", name);
scale = dvec_alloc(ptr,
SV_TIME,
VF_REAL & ~VF_PERMANENT,
(VF_REAL | VF_EVENT_NODE) & ~VF_PERMANENT,
i, anal_point_vec);
d = dvec_alloc(name,
SV_VOLTAGE,
VF_REAL & ~VF_PERMANENT,
(VF_REAL | VF_EVENT_NODE) & ~VF_PERMANENT,
i, value_vec);
d->v_scale = scale;