fix BadDrawable regression in free_rawfile(): after deleting data a draw() was called, but since this function is called also in exit handler all windows are already closed. Added digital waveforms and bussed signal display
This commit is contained in:
parent
a0e057a52d
commit
d6c197d108
|
|
@ -277,7 +277,7 @@ set to_pdf {gswin64c -sDEVICE=pdfwrite -o}
|
|||
# set editor { xterm -geometry 100x40 -e pico }
|
||||
|
||||
#### For Windows
|
||||
# set editor {notepad.exe}
|
||||
set editor {notepad.exe}
|
||||
|
||||
###########################################################################
|
||||
#### SHOW ERC INFO WINDOW (erc errors, warnings etc)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
void here(double i)
|
||||
{
|
||||
fprintf(stderr, "here %g\n", i);
|
||||
dbg(0, "here %g\n", i);
|
||||
}
|
||||
|
||||
/* super simple 32 bit hashing function for files
|
||||
|
|
@ -70,7 +70,7 @@ unsigned int hash_file(const char *f, int skip_path_lines)
|
|||
fclose(fd);
|
||||
return h;
|
||||
} else {
|
||||
fprintf(stderr, "Can not open file %s\n", f);
|
||||
dbg(0, "Can not open file %s\n", f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
129
src/callback.c
129
src/callback.c
|
|
@ -35,10 +35,11 @@ static int waves_selected(int state)
|
|||
if(xctx->sel_array[i].type == xRECT && c == GRIDLAYER) {
|
||||
n = xctx->sel_array[i].n;
|
||||
r = &xctx->rect[c][n];
|
||||
if( (xctx->ui_state & GRAPHPAN) || POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2) ) {
|
||||
if(r->flags != 1) return 0;
|
||||
if( (xctx->ui_state & GRAPHPAN) ||
|
||||
POINTINSIDE(xctx->mousex, xctx->mousey, r->x1, r->y1, r->x2, r->y2) ) {
|
||||
is_inside = 1;
|
||||
}
|
||||
if(r->flags != 1) return 0;
|
||||
} else return 0;
|
||||
}
|
||||
return is_inside;
|
||||
|
|
@ -213,7 +214,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
if(val[0]) wx2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"y2",0);
|
||||
if(val[0]) wy2 = atof(val);
|
||||
calc_graph_area(GRIDLAYER, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
val = get_tok_value(r->prop_ptr,"digital",0);
|
||||
if(val[0]) digital = atof(val);
|
||||
calc_graph_area(GRIDLAYER, n, digital, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
cx = (x2 - x1) / (wx2 - wx1);
|
||||
dx = x1 - wx1 * cx;
|
||||
cy = (y1 - y2) / (wy2 - wy1);
|
||||
|
|
@ -229,23 +232,24 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
xctx->graph_bottom = 0;
|
||||
}
|
||||
xctx->graph_master = n;
|
||||
if(state & ControlMask) xctx->graph_flags |= 1;
|
||||
else xctx->graph_flags &= ~1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* lock x-axis to working graph when movint/zooming multiple graphs */
|
||||
/* lock x-axis to working graph when moving/zooming multiple graphs */
|
||||
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x1",0);
|
||||
if(val[0]) wx1 = atof(val);
|
||||
val = get_tok_value(xctx->rect[GRIDLAYER][xctx->graph_master].prop_ptr,"x2",0);
|
||||
if(val[0]) wx2 = atof(val);
|
||||
for(i=0; i<xctx->lastsel; i++) {
|
||||
c = xctx->sel_array[i].col;
|
||||
for(i=0; i< ((xctx->graph_flags & 1) ? xctx->rects[GRIDLAYER] : xctx->lastsel); i++) {
|
||||
c = (xctx->graph_flags & 1) ? GRIDLAYER : xctx->sel_array[i].col;
|
||||
/* process only graph boxes */
|
||||
if(xctx->sel_array[i].type == xRECT && c == GRIDLAYER) {
|
||||
if( (xctx->graph_flags & 1) || (xctx->sel_array[i].type == xRECT && c == GRIDLAYER) ) {
|
||||
xRect *r;
|
||||
n = xctx->sel_array[i].n;
|
||||
n = (xctx->graph_flags & 1) ? i : xctx->sel_array[i].n;
|
||||
r = &xctx->rect[GRIDLAYER][n];
|
||||
if(r->flags != 1) continue;
|
||||
val = get_tok_value(r->prop_ptr,"divx",0);
|
||||
|
|
@ -258,10 +262,10 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
if(val[0]) wy2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"dataset",0);
|
||||
if(val[0]) dataset = atoi(val);
|
||||
if(dataset >= xctx->datasets) dataset = xctx->datasets - 1;
|
||||
if(dataset >= xctx->graph_datasets) dataset = xctx->graph_datasets - 1;
|
||||
val = get_tok_value(r->prop_ptr,"digital",0);
|
||||
if(val[0]) digital = atof(val);
|
||||
calc_graph_area(GRIDLAYER, n, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
calc_graph_area(GRIDLAYER, n, digital, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
/* cache coefficients for faster graph coord transformations */
|
||||
cx = (x2 - x1) / (wx2 - wx1);
|
||||
dx = x1 - wx1 * cx;
|
||||
|
|
@ -271,9 +275,9 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
if(event == MotionNotify && (state & Button1Mask) && !xctx->graph_bottom) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
if(!digital && n == xctx->graph_master) {
|
||||
if(n == xctx->graph_master) {
|
||||
delta = (wy2 - wy1) / divy;
|
||||
delta_threshold = 0.05;
|
||||
delta_threshold = 0.01;
|
||||
if(fabs(xctx->my_double_save - xctx->mousey_snap) > fabs(cy * delta) * delta_threshold) {
|
||||
yy1 = wy1 + (xctx->my_double_save - xctx->mousey_snap) / cy;
|
||||
yy2 = wy2 + (xctx->my_double_save - xctx->mousey_snap) / cy;
|
||||
|
|
@ -281,6 +285,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
my_strdup(1424, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
||||
my_snprintf(s, S(s), "%g", yy2);
|
||||
my_strdup(1425, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
||||
xctx->my_double_save = xctx->mousey_snap;
|
||||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -294,15 +299,16 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
my_strdup(1410, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
||||
my_snprintf(s, S(s), "%g", xx2);
|
||||
my_strdup(1411, &r->prop_ptr, subst_token(r->prop_ptr, "x2", s));
|
||||
/* update saved mouse position after processing all graphs */
|
||||
if(i >= ((xctx->graph_flags & 1) ? xctx->rects[GRIDLAYER] : xctx->lastsel) - 1) {
|
||||
xctx->mx_double_save = xctx->mousex_snap;
|
||||
xctx->my_double_save = xctx->mousey_snap;
|
||||
}
|
||||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
if(i >= xctx->lastsel -1) { /* update saved mouse position after processing all graphs */
|
||||
xctx->mx_double_save = xctx->mousex_snap;
|
||||
xctx->my_double_save = xctx->mousey_snap;
|
||||
}
|
||||
}
|
||||
else if((button == Button5 && state == 0)) {
|
||||
else if((button == Button5 && !(state & ShiftMask))) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
if(!digital && n == xctx->graph_master) {
|
||||
|
|
@ -328,7 +334,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if(key == XK_Left) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
|
|
@ -337,7 +342,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wy1;
|
||||
double b = wy2 -m;
|
||||
double delta = (wy2 - wy1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
yy2 = wy2 + var * b / delta;
|
||||
yy1 = wy1 - var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", yy1);
|
||||
|
|
@ -358,8 +363,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if(button == Button4 && state == 0) {
|
||||
else if(button == Button4 && !(state & ShiftMask)) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
if(!digital && n == xctx->graph_master) {
|
||||
|
|
@ -385,7 +389,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if(key == XK_Right) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
|
|
@ -394,7 +397,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wy1;
|
||||
double b = wy2 -m;
|
||||
double delta = (wy2 - wy1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
yy2 = wy2 - var * b / delta;
|
||||
yy1 = wy1 + var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", yy1);
|
||||
|
|
@ -415,14 +418,14 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
else if(button == Button5 && state == ShiftMask) {
|
||||
else if(button == Button5 && (state & ShiftMask)) {
|
||||
if(xctx->graph_left) {
|
||||
if(!digital && n == xctx->graph_master) {
|
||||
double m = G_Y(xctx->mousey);
|
||||
double a = m - wy1;
|
||||
double b = wy2 -m;
|
||||
double delta = (wy2 - wy1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
yy2 = wy2 + var * b / delta;
|
||||
yy1 = wy1 - var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", yy1);
|
||||
|
|
@ -436,7 +439,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wx1;
|
||||
double b = wx2 -m;
|
||||
double delta = (wx2 - wx1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
xx2 = wx2 + var * b / delta;
|
||||
xx1 = wx1 - var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", xx1);
|
||||
|
|
@ -446,7 +449,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if(key == XK_Down) {
|
||||
double delta;
|
||||
if(xctx->graph_left) {
|
||||
|
|
@ -466,7 +468,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wx1;
|
||||
double b = wx2 -m;
|
||||
double delta = (wx2 - wx1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
xx2 = wx2 + var * b / delta;
|
||||
xx1 = wx1 - var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", xx1);
|
||||
|
|
@ -476,14 +478,14 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
need_redraw = 1;
|
||||
}
|
||||
}
|
||||
else if(button == Button4 && state == ShiftMask) {
|
||||
else if(button == Button4 && (state & ShiftMask)) {
|
||||
if(xctx->graph_left) {
|
||||
if(!digital && n == xctx->graph_master) {
|
||||
double m = G_Y(xctx->mousey);
|
||||
double a = m - wy1;
|
||||
double b = wy2 -m;
|
||||
double delta = (wy2 - wy1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
yy2 = wy2 - var * b / delta;
|
||||
yy1 = wy1 + var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", yy1);
|
||||
|
|
@ -497,7 +499,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wx1;
|
||||
double b = wx2 -m;
|
||||
double delta = (wx2 - wx1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
xx2 = wx2 - var * b / delta;
|
||||
xx1 = wx1 + var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", xx1);
|
||||
|
|
@ -527,7 +529,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
double a = m - wx1;
|
||||
double b = wx2 -m;
|
||||
double delta = (wx2 - wx1);
|
||||
double var = delta * 0.1;
|
||||
double var = delta * 0.2;
|
||||
xx2 = wx2 - var * b / delta;
|
||||
xx1 = wx1 + var * a / delta;
|
||||
my_snprintf(s, S(s), "%g", xx1);
|
||||
|
|
@ -538,40 +540,38 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
}
|
||||
}
|
||||
else if(key == 'f') {
|
||||
if(xctx->values) {
|
||||
if(xctx->graph_values) {
|
||||
if(xctx->graph_left) {
|
||||
if(!digital) {
|
||||
int i, j;
|
||||
double v;
|
||||
double min=0.0, max=0.0;
|
||||
int first = 1;
|
||||
char *saven, *nptr, *ntok, *node = NULL;;
|
||||
my_strdup2(1426, &node, get_tok_value(r->prop_ptr,"node",0));
|
||||
nptr = node;
|
||||
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
|
||||
nptr = NULL;
|
||||
j = get_raw_index(ntok);
|
||||
if(j >= 0) {
|
||||
for(i = 0; i < xctx->npoints[dataset]; i++) {
|
||||
v = get_raw_value(dataset, j, i);
|
||||
if(first || v < min) {min = v; first = 0;}
|
||||
if(first || v > max) {max = v; first = 0;}
|
||||
}
|
||||
}
|
||||
int i, j;
|
||||
double v;
|
||||
double min=0.0, max=0.0;
|
||||
int first = 1;
|
||||
char *saven, *nptr, *ntok, *node = NULL;;
|
||||
my_strdup2(1426, &node, get_tok_value(r->prop_ptr,"node",0));
|
||||
nptr = node;
|
||||
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
|
||||
nptr = NULL;
|
||||
j = get_raw_index(ntok);
|
||||
if(j >= 0) {
|
||||
for(i = 0; i < xctx->graph_npoints[dataset]; i++) {
|
||||
v = get_raw_value(dataset, j, i);
|
||||
if(first || v < min) {min = v; first = 0;}
|
||||
if(first || v > max) {max = v; first = 0;}
|
||||
}
|
||||
}
|
||||
if(max == min) max += 0.01;
|
||||
min = floor_to_n_digits(min, 2);
|
||||
max = ceil_to_n_digits(max, 2);
|
||||
my_free(1427, &node);
|
||||
my_snprintf(s, S(s), "%g", min);
|
||||
my_strdup(1422, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
||||
my_snprintf(s, S(s), "%g", max);
|
||||
my_strdup(1423, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
||||
need_redraw = 1;
|
||||
}
|
||||
if(max == min) max += 0.01;
|
||||
min = floor_to_n_digits(min, 2);
|
||||
max = ceil_to_n_digits(max, 2);
|
||||
my_free(1427, &node);
|
||||
my_snprintf(s, S(s), "%g", min);
|
||||
my_strdup(1422, &r->prop_ptr, subst_token(r->prop_ptr, "y1", s));
|
||||
my_snprintf(s, S(s), "%g", max);
|
||||
my_strdup(1423, &r->prop_ptr, subst_token(r->prop_ptr, "y2", s));
|
||||
need_redraw = 1;
|
||||
} else {
|
||||
xx1 = get_raw_value(dataset, 0, 0);
|
||||
xx2 = get_raw_value(dataset, 0, xctx->npoints[dataset] -1);
|
||||
xx2 = get_raw_value(dataset, 0, xctx->graph_npoints[dataset] -1);
|
||||
my_snprintf(s, S(s), "%g", xx1);
|
||||
my_strdup(1409, &r->prop_ptr, subst_token(r->prop_ptr, "x1", s));
|
||||
my_snprintf(s, S(s), "%g", xx2);
|
||||
|
|
@ -583,10 +583,10 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
else if( event == MotionNotify && (state & Button1Mask) && xctx->graph_bottom ) {
|
||||
double wwx1, wwx2, p, delta, ccx, ddx;
|
||||
|
||||
if(xctx->values) {
|
||||
if(xctx->graph_values) {
|
||||
delta = wx2 - wx1;
|
||||
wwx1 = get_raw_value(dataset, 0, 0);
|
||||
wwx2 = get_raw_value(dataset, 0, xctx->npoints[dataset] - 1);
|
||||
wwx2 = get_raw_value(dataset, 0, xctx->graph_npoints[dataset] - 1);
|
||||
ccx = (x2 - x1) / (wwx2 - wwx1);
|
||||
ddx = x1 - wwx1 * ccx;
|
||||
p = (xctx->mousex_snap - ddx) / ccx;
|
||||
|
|
@ -623,7 +623,6 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
|
|||
cairo_restore(xctx->cairo_ctx);
|
||||
cairo_restore(xctx->cairo_save_ctx);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
547
src/draw.c
547
src/draw.c
|
|
@ -1491,26 +1491,26 @@ void read_binary_block(FILE *fd)
|
|||
int offset = 0;
|
||||
|
||||
|
||||
for(p = 0 ; p < xctx->datasets; p++) {
|
||||
size += xctx->nvars * xctx->npoints[p];
|
||||
offset += xctx->npoints[p];
|
||||
for(p = 0 ; p < xctx->graph_datasets; p++) {
|
||||
size += xctx->graph_nvars * xctx->graph_npoints[p];
|
||||
offset += xctx->graph_npoints[p];
|
||||
}
|
||||
|
||||
/* read buffer */
|
||||
tmp = my_calloc(1405, xctx->nvars, sizeof(double *));
|
||||
tmp = my_calloc(1405, xctx->graph_nvars, sizeof(double *));
|
||||
/* allocate storage for binary block */
|
||||
if(!xctx->values) xctx->values = my_calloc(118, xctx->nvars, sizeof(SPICE_DATA *));
|
||||
for(p = 0 ; p < xctx->nvars; p++) {
|
||||
my_realloc(372, &xctx->values[p], (size + xctx->npoints[xctx->datasets]) * sizeof(double));
|
||||
if(!xctx->graph_values) xctx->graph_values = my_calloc(118, xctx->graph_nvars, sizeof(SPICE_DATA *));
|
||||
for(p = 0 ; p < xctx->graph_nvars; p++) {
|
||||
my_realloc(372, &xctx->graph_values[p], (size + xctx->graph_npoints[xctx->graph_datasets]) * sizeof(double));
|
||||
}
|
||||
/* read binary block */
|
||||
for(p = 0; p < xctx->npoints[xctx->datasets]; p++) {
|
||||
if(fread(tmp, sizeof(double), xctx->nvars, fd) != xctx->nvars) {
|
||||
for(p = 0; p < xctx->graph_npoints[xctx->graph_datasets]; p++) {
|
||||
if(fread(tmp, sizeof(double), xctx->graph_nvars, fd) != xctx->graph_nvars) {
|
||||
dbg(0, "Warning: binary block is not of correct size\n");
|
||||
}
|
||||
/* assign to xschem struct, memory aligned per variable, for cache locality */
|
||||
for(v = 0; v < xctx->nvars; v++) {
|
||||
xctx->values[v][offset + p] = tmp[v];
|
||||
for(v = 0; v < xctx->graph_nvars; v++) {
|
||||
xctx->graph_values[v][offset + p] = tmp[v];
|
||||
}
|
||||
}
|
||||
my_free(1406, &tmp);
|
||||
|
|
@ -1550,16 +1550,16 @@ int read_dataset(FILE *fd)
|
|||
while((ptr = fgets(line, sizeof(line), fd)) ) {
|
||||
/* after this line comes the binary blob made of nvars * npoints * sizeof(double) bytes */
|
||||
if(!strcmp(line, "Binary:\n")) {
|
||||
int npoints = xctx->npoints[xctx->datasets];
|
||||
int npoints = xctx->graph_npoints[xctx->graph_datasets];
|
||||
if(sim_type) {
|
||||
done_header = 1;
|
||||
read_binary_block(fd);
|
||||
dbg(1, "read_dataset(): read binary block, nvars=%d npoints=%d\n", xctx->nvars, npoints);
|
||||
xctx->datasets++;
|
||||
dbg(1, "read_dataset(): read binary block, nvars=%d npoints=%d\n", xctx->graph_nvars, npoints);
|
||||
xctx->graph_datasets++;
|
||||
exit_status = 1;
|
||||
} else {
|
||||
dbg(1, "read_dataset(): skip binary block, nvars=%d npoints=%d\n", xctx->nvars, npoints);
|
||||
fseek(fd, xctx->nvars * npoints * sizeof(double), SEEK_CUR); /* skip binary block */
|
||||
dbg(1, "read_dataset(): skip binary block, nvars=%d npoints=%d\n", xctx->graph_nvars, npoints);
|
||||
fseek(fd, xctx->graph_nvars * npoints * sizeof(double), SEEK_CUR); /* skip binary block */
|
||||
}
|
||||
done_points = 0;
|
||||
}
|
||||
|
|
@ -1575,26 +1575,26 @@ int read_dataset(FILE *fd)
|
|||
* to skip binary blobs */
|
||||
else if(!strncmp(line, "No. of Data Rows :", 18)) {
|
||||
/* array of number of points of datasets (they are of varialbe length) */
|
||||
my_realloc(1414, &xctx->npoints, (xctx->datasets+1) * sizeof(int));
|
||||
sscanf(line, "No. of Data Rows : %d", &xctx->npoints[xctx->datasets]);
|
||||
my_realloc(1414, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int));
|
||||
sscanf(line, "No. of Data Rows : %d", &xctx->graph_npoints[xctx->graph_datasets]);
|
||||
done_points = 1;
|
||||
}
|
||||
else if(!strncmp(line, "No. Variables:", 14)) {
|
||||
sscanf(line, "No. Variables: %d", &xctx->nvars);
|
||||
sscanf(line, "No. Variables: %d", &xctx->graph_nvars);
|
||||
}
|
||||
else if(!done_points && !strncmp(line, "No. Points:", 11)) {
|
||||
my_realloc(1415, &xctx->npoints, (xctx->datasets+1) * sizeof(int));
|
||||
sscanf(line, "No. Points: %d", &xctx->npoints[xctx->datasets]);
|
||||
my_realloc(1415, &xctx->graph_npoints, (xctx->graph_datasets+1) * sizeof(int));
|
||||
sscanf(line, "No. Points: %d", &xctx->graph_npoints[xctx->graph_datasets]);
|
||||
}
|
||||
if(!done_header && variables) {
|
||||
/* get the list of lines with index and node name */
|
||||
if(!xctx->names) xctx->names = my_calloc(426, xctx->nvars, sizeof(char *));
|
||||
if(!xctx->graph_names) xctx->graph_names = my_calloc(426, xctx->graph_nvars, sizeof(char *));
|
||||
sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */
|
||||
xctx->names[i] = my_malloc(415, strlen(varname) + 1);
|
||||
strcpy(xctx->names[i], varname);
|
||||
xctx->graph_names[i] = my_malloc(415, strlen(varname) + 1);
|
||||
strcpy(xctx->graph_names[i], varname);
|
||||
/* use hash table to store index number of variables */
|
||||
int_hash_lookup(xctx->raw_table, xctx->names[i], i, XINSERT_NOREPLACE);
|
||||
dbg(1, "read_dataset(): get node list -> names[%d] = %s\n", i, xctx->names[i]);
|
||||
int_hash_lookup(xctx->raw_table, xctx->graph_names[i], i, XINSERT_NOREPLACE);
|
||||
dbg(1, "read_dataset(): get node list -> names[%d] = %s\n", i, xctx->graph_names[i]);
|
||||
}
|
||||
/* after this line comes the list of indexes and associated nodes */
|
||||
if(sim_type && !strncmp(line, "Variables:", 10)) {
|
||||
|
|
@ -1602,32 +1602,35 @@ int read_dataset(FILE *fd)
|
|||
}
|
||||
}
|
||||
dbg(1, "read_dataset(): datasets=%d, last npoints=%d, nvars=%d\n",
|
||||
xctx->datasets, xctx->npoints[xctx->datasets-1], xctx->nvars);
|
||||
xctx->graph_datasets, xctx->graph_npoints[xctx->graph_datasets-1], xctx->graph_nvars);
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
void free_rawfile(void)
|
||||
void free_rawfile(int dr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(xctx->names) {
|
||||
for(i = 0 ; i < xctx->nvars; i++) {
|
||||
my_free(510, &xctx->names[i]);
|
||||
int deleted = 0;
|
||||
if(xctx->graph_names) {
|
||||
deleted = 1;
|
||||
for(i = 0 ; i < xctx->graph_nvars; i++) {
|
||||
my_free(510, &xctx->graph_names[i]);
|
||||
}
|
||||
my_free(968, &xctx->names);
|
||||
my_free(968, &xctx->graph_names);
|
||||
}
|
||||
if(xctx->values) {
|
||||
for(i = 0 ; i < xctx->nvars; i++) {
|
||||
my_free(512, &xctx->values[i]);
|
||||
if(xctx->graph_values) {
|
||||
deleted = 1;
|
||||
for(i = 0 ; i < xctx->graph_nvars; i++) {
|
||||
my_free(512, &xctx->graph_values[i]);
|
||||
}
|
||||
my_free(528, &xctx->values);
|
||||
my_free(528, &xctx->graph_values);
|
||||
}
|
||||
if(xctx->npoints) my_free(1413, &xctx->npoints);
|
||||
if(xctx->graph_npoints) my_free(1413, &xctx->graph_npoints);
|
||||
if(xctx->raw_schname) my_free(1393, &xctx->raw_schname);
|
||||
xctx->datasets = 0;
|
||||
xctx->nvars = 0;
|
||||
xctx->graph_datasets = 0;
|
||||
xctx->graph_nvars = 0;
|
||||
int_hash_free(xctx->raw_table);
|
||||
draw();
|
||||
if(deleted && dr) draw();
|
||||
}
|
||||
|
||||
/* read a ngspice raw file (with data portion in binary format) */
|
||||
|
|
@ -1635,7 +1638,7 @@ int read_rawfile(const char *f)
|
|||
{
|
||||
int res = 0;
|
||||
FILE *fd;
|
||||
if(xctx->values || xctx->npoints || xctx->nvars || xctx->datasets) {
|
||||
if(xctx->graph_values || xctx->graph_npoints || xctx->graph_nvars || xctx->graph_datasets) {
|
||||
dbg(0, "read_rawfile(): must clear current raw file before loading new\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1658,7 +1661,7 @@ int read_rawfile(const char *f)
|
|||
int get_raw_index(const char *node)
|
||||
{
|
||||
Int_hashentry *entry;
|
||||
if(xctx->values) {
|
||||
if(xctx->graph_values) {
|
||||
entry = int_hash_lookup(xctx->raw_table, node, 0, XLOOKUP);
|
||||
if(entry) return entry->value;
|
||||
}
|
||||
|
|
@ -1669,15 +1672,15 @@ double get_raw_value(int dataset, int idx, int point)
|
|||
{
|
||||
int i, ofs;
|
||||
ofs = 0;
|
||||
if(xctx->values) {
|
||||
if(xctx->graph_values) {
|
||||
for(i = 0; i < dataset; i++) {
|
||||
ofs += xctx->npoints[i];
|
||||
ofs += xctx->graph_npoints[i];
|
||||
}
|
||||
return xctx->values[idx][ofs + point];
|
||||
return xctx->graph_values[idx][ofs + point];
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
|
||||
void calc_graph_area(int c, int i, int digital, double *x1, double *y1,double *x2,double *y2,
|
||||
double *marginx, double *marginy)
|
||||
{
|
||||
double rx1, rx2, ry1, ry2, rw, rh, tmp;
|
||||
|
|
@ -1688,18 +1691,18 @@ void calc_graph_area(int c, int i, double *x1, double *y1,double *x2,double *y2,
|
|||
rw = (rx2 - rx1);
|
||||
rh = (ry2 - ry1);
|
||||
/* set margins */
|
||||
tmp = rw * 0.05;
|
||||
*marginx = tmp < 80 ? 80 : tmp;
|
||||
tmp = rh * 0.1;
|
||||
*marginy = tmp < 20 ? 20 : tmp;
|
||||
tmp = rw * 0.1;
|
||||
*marginx = tmp < 30 ? 30 : tmp;
|
||||
tmp = rh * 0.15;
|
||||
*marginy = tmp < 15 ? 15 : tmp;
|
||||
|
||||
/* calculate graph bounding box (container - margin)
|
||||
* This is the box where plot is done */
|
||||
*x1 = rx1 + *marginx + 40;
|
||||
*x2 = rx2 - *marginx/1.8;
|
||||
*y1 = ry1 + *marginy;
|
||||
tmp = *marginy < 30 ? 30 : *marginy;
|
||||
*y2 = ry2 - tmp; /* some more space to accomodate x-axis label */
|
||||
*x1 = rx1 + *marginx;
|
||||
*x2 = rx2 - *marginx / 2.4; /* less space for right margin */
|
||||
if(digital) *y1 = ry1 + *marginy * 0.4;
|
||||
else *y1 = ry1 + *marginy;
|
||||
*y2 = ry2 - *marginy;
|
||||
}
|
||||
|
||||
/* round to closest 1e-ee. 2e-ee, 5e-ee
|
||||
|
|
@ -1735,7 +1738,7 @@ static double axis_increment(double a, double b, int div)
|
|||
return scaled_delta * scale * sign;
|
||||
}
|
||||
|
||||
double axis_start(double n, double delta, int div)
|
||||
static double axis_start(double n, double delta, int div)
|
||||
{
|
||||
if(delta == 0.0) return n;
|
||||
/* if user wants only one division, just do what user asks */
|
||||
|
|
@ -1744,14 +1747,14 @@ double axis_start(double n, double delta, int div)
|
|||
return ceil(n / delta) * delta;
|
||||
}
|
||||
|
||||
int axis_end(double x, double delta, double b)
|
||||
static int axis_end(double x, double delta, double b)
|
||||
{
|
||||
if(delta == 0.0) return 1; /* guard against infinite loops */
|
||||
if(delta > 0) return x > b + delta / 100000.0;
|
||||
return x < b + delta / 100000.0;
|
||||
}
|
||||
|
||||
int axis_within_range(double x, double a, double b)
|
||||
static int axis_within_range(double x, double a, double b)
|
||||
{
|
||||
if(a < b) return x >= a;
|
||||
return x <= a;
|
||||
|
|
@ -1773,7 +1776,7 @@ static double get_unit(const char *val)
|
|||
int schematic_waves_loaded(void)
|
||||
{
|
||||
int i;
|
||||
if(xctx->values && xctx->raw_schname) {
|
||||
if(xctx->graph_values && xctx->raw_schname) {
|
||||
for(i = xctx->currsch; i >= 0; i--) {
|
||||
if( !strcmp(xctx->raw_schname, xctx->sch[i]) ) return 1;
|
||||
}
|
||||
|
|
@ -1787,112 +1790,150 @@ int schematic_waves_loaded(void)
|
|||
#define W_X(x) (cx * (x) + dx)
|
||||
#define W_Y(y) (cy * (y) + dy)
|
||||
|
||||
static void get_y_points(int v, int first, int last, double cy, double dy, double *yarr,
|
||||
int digital, int wcnt, int n_nodes, double ydelta)
|
||||
/* draw bussed signals: ntok is a comma separated list of items, first item is bus name,
|
||||
* following are bits that are bundled together:
|
||||
LDA,LDA[3],LDA[2],LDA1],LDA[0]
|
||||
*/
|
||||
static void draw_graph_bus_points(const char *ntok, int first, int last,
|
||||
double cx, double dx, double cy, double dy,
|
||||
int wave_col, int sweep_idx,
|
||||
int digital, int dig_max_waves, int wcnt, int n_nodes, double wy1, double wy2)
|
||||
{
|
||||
int p, i;
|
||||
int n = dig_max_waves;
|
||||
double s1 = 1.0 / n;
|
||||
double s2 = s1 * .66;
|
||||
double c = (wy2 - wy1) * wcnt * s1;
|
||||
double x1 = W_X(xctx->graph_values[sweep_idx][first]);
|
||||
double x2 = W_X(xctx->graph_values[sweep_idx][last-1]);
|
||||
double ylow = W_Y(c + wy2 * s2); /* swapped as xschem Y coordinates are top-bottom */
|
||||
double yhigh = W_Y(c + wy1 * s2);
|
||||
const char *bit_name;
|
||||
int n_bits = count_items(ntok, ",") - 1;
|
||||
int *idx_arr = NULL;
|
||||
Int_hashentry *entry;
|
||||
unsigned long val, busval, old_busval;
|
||||
double vth = (wy1 + wy2) / 2.0; /* A to D threshold */
|
||||
double xval, xval_old;
|
||||
double ydelta = fabs(yhigh - ylow);
|
||||
double labsize = 0.015 * ydelta;
|
||||
double charwidth = labsize * 38.0;
|
||||
char str[100];
|
||||
int hex_digits = (n_bits - 1) / 4 + 1;
|
||||
|
||||
idx_arr = my_malloc(1454, (n_bits) * sizeof(int));
|
||||
p = 0;
|
||||
dbg(1, "n_bits = %d\n", n_bits);
|
||||
while( (bit_name = find_nth(ntok, ',', p + 2))[0] ) {
|
||||
dbg(1, "draw_graph_bus_points(): bit %d : %s: ", p, bit_name);
|
||||
entry = int_hash_lookup(xctx->raw_table, bit_name, 0, XLOOKUP);
|
||||
if(entry) {
|
||||
dbg(1, "%d\n", entry->value);
|
||||
idx_arr[p] = entry->value;
|
||||
} else {
|
||||
dbg(1, "\n");
|
||||
}
|
||||
p++;
|
||||
}
|
||||
drawline(wave_col, NOW, x1, ylow, x2, ylow, 0);
|
||||
drawline(wave_col, NOW, x1, yhigh, x2, yhigh, 0);
|
||||
for(p = first ; p < last; p++) {
|
||||
/* calculate value of bus by adding all binary bits */
|
||||
busval = 0;
|
||||
for(i = 0; i < n_bits; i++) {
|
||||
val = xctx->graph_values[idx_arr[i]][p];
|
||||
busval = (busval << 1) + (val > vth);
|
||||
}
|
||||
|
||||
xval = W_X(xctx->graph_values[sweep_idx][p]);
|
||||
|
||||
/* used to draw bus value before 1st transition */
|
||||
if(p == first) {
|
||||
old_busval = busval;
|
||||
xval_old = xval;
|
||||
}
|
||||
if(p > first && busval != old_busval) {
|
||||
/* draw transition ('X') */
|
||||
drawline(BACKLAYER, NOW, xval-1, yhigh, xval+1, yhigh, 0);
|
||||
drawline(BACKLAYER, NOW, xval-1, ylow, xval+1, ylow, 0);
|
||||
drawline(wave_col, NOW, xval-1, ylow, xval+1, yhigh, 0);
|
||||
drawline(wave_col, NOW, xval-1, yhigh, xval+1, ylow, 0);
|
||||
/* build hex string for bus value */
|
||||
sprintf(str, "%0*lX", hex_digits, old_busval);
|
||||
/* draw hex bus value if there is enough room */
|
||||
if( fabs(xval - xval_old) > strlen(str) * charwidth) {
|
||||
draw_string(wave_col, NOW, str, 2, 0, 1, 0, (xval + xval_old) / 2.0,
|
||||
yhigh, labsize, labsize);
|
||||
|
||||
}
|
||||
old_busval = busval;
|
||||
xval_old = xval;
|
||||
} /* if(p > first && busval != old_busval) */
|
||||
} /* for(p = first ; p < last; p++) */
|
||||
/* draw hex bus value after last transition */
|
||||
sprintf(str, "%0*lX", hex_digits, busval);
|
||||
if( fabs(xval - xval_old) > strlen(str) * charwidth) {
|
||||
draw_string(wave_col, NOW, str, 2, 0, 1, 0, (xval + xval_old) / 2.0,
|
||||
yhigh, labsize, labsize);
|
||||
}
|
||||
my_free(1455, &idx_arr);
|
||||
}
|
||||
|
||||
static void draw_graph_points(int v, int first, int last, double cy, double dy,
|
||||
double *xarr, double *yarr, int wave_col,
|
||||
int digital, int dig_max_waves, int wcnt, int n_nodes, double wy1, double wy2)
|
||||
{
|
||||
int p;
|
||||
double yy;
|
||||
double ydelta = wy2 - wy1;
|
||||
int poly_npoints = 0;
|
||||
double s1 = 1.0 / n_nodes;
|
||||
int n = dig_max_waves;
|
||||
double s1 = 1.0 / n;
|
||||
double s2 = s1 * .66;
|
||||
for(p = first ; p < last; p++) {
|
||||
yy = xctx->values[v][p];
|
||||
if(digital) {
|
||||
yy = ydelta * wcnt * s1 + yy *s2;
|
||||
double c = ydelta * wcnt * s1;
|
||||
|
||||
if( !digital || (c >= wy1 && c <= wy2) ) {
|
||||
for(p = first ; p < last; p++) {
|
||||
yy = xctx->graph_values[v][p];
|
||||
if(digital) {
|
||||
yy = c + yy *s2;
|
||||
}
|
||||
/* Build poly y array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
|
||||
yarr[poly_npoints] = W_Y(yy);
|
||||
poly_npoints++;
|
||||
}
|
||||
/* Build poly y array. Translate from graph coordinates to {x1,y1} - {x2, y2} world. */
|
||||
yarr[poly_npoints] = W_Y(yy);
|
||||
poly_npoints++;
|
||||
}
|
||||
/* plot data */
|
||||
drawpolygon(wave_col, 0, xarr, yarr, poly_npoints, 0, 0);
|
||||
} else dbg(1, "skipping wave: %s\n", xctx->graph_names[v]);
|
||||
}
|
||||
|
||||
void draw_graph(int c, int i, int flags)
|
||||
static void draw_graph_grid(
|
||||
double rx1, double ry1, double rx2, double ry2, /* container box */
|
||||
double x1, double y1, double x2, double y2, /* graph area */
|
||||
double marginx, double marginy,
|
||||
double wx1, double wy1, double wx2, double wy2, /* graph coordinate system */
|
||||
double cx, double cy, double dx, double dy, /* graph to xschem matrix transform */
|
||||
int divx, int divy, int subdivx, int subdivy, /* axis major/minor grids */
|
||||
double unitx, double unity, /* unit conversion (p, u, m, k, M, G) */
|
||||
int digital) /* set to 1 for digital plot */
|
||||
{
|
||||
/* container box */
|
||||
double rx1, ry1, rx2, ry2, rw/*, rh */;
|
||||
/* graph box (smaller due to margins) */
|
||||
double x1, y1, x2, y2, w, h;
|
||||
/* graph coordinate, some defaults */
|
||||
double digital = 0;
|
||||
double wx1 = -2e-6;
|
||||
double wy1 = -1;
|
||||
double wx2 = 8e-6;
|
||||
double wy2 = 4;
|
||||
double marginx = 20; /* will be recalculated later */
|
||||
double marginy = 20; /* will be recalculated later */
|
||||
double wx, wy; /* point coordinates in graph */
|
||||
/* coefficients for graph to container coordinate transformations W_X() and W_Y()*/
|
||||
double cx, dx, cy, dy;
|
||||
double dash_sizex, dash_sizey;
|
||||
int divx = 10;
|
||||
int divy = 5;
|
||||
int subdivx = 0;
|
||||
int subdivy = 0;
|
||||
double unitx = 1.0;
|
||||
double unity = 1.0;
|
||||
int unitx_suffix = ' '; /* 'n' or 'u' or 'M' or 'k' ... */
|
||||
int unity_suffix = ' ';
|
||||
/* label start and increments calculated in order to give 'nice' numbers */
|
||||
double deltax, deltay;
|
||||
double startx, starty;
|
||||
int j, k, wave_color = 5;
|
||||
double deltax, startx, deltay, starty, wx,wy, dash_sizex, dash_sizey, w, h;
|
||||
int j, k;
|
||||
char lab[30];
|
||||
const char *val;
|
||||
char *node = NULL, *color = NULL, *sweep = NULL;
|
||||
double txtsizelab, txtsizey, txtsizex, tmp;
|
||||
Int_hashentry *entry;
|
||||
int sweep_idx = 0;
|
||||
int n_nodes; /* number of variables to display in a single graph */
|
||||
xRect *r = &xctx->rect[c][i];
|
||||
char tmpstr[200];
|
||||
char *saven, *savec, *saves, *nptr, *cptr, *sptr, *ntok, *ctok, *stok;
|
||||
int wcnt = 0;
|
||||
int dataset = -1;
|
||||
/* container (embedding rectangle) coordinates */
|
||||
rx1 = r->x1;
|
||||
ry1 = r->y1;
|
||||
rx2 = r->x2;
|
||||
ry2 = r->y2;
|
||||
rw = (rx2 - rx1);
|
||||
/* rh = (ry2 -ry1); */
|
||||
/* get variables to plot, x/y range, grid info etc */
|
||||
val = get_tok_value(r->prop_ptr,"unitx",0);
|
||||
unitx_suffix = val[0];
|
||||
unitx = get_unit(val);;
|
||||
val = get_tok_value(r->prop_ptr,"unity",0);
|
||||
unity_suffix = val[0];
|
||||
unity = get_unit(val);;
|
||||
val = get_tok_value(r->prop_ptr,"subdivx",0);
|
||||
if(val[0]) subdivx = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"subdivy",0);
|
||||
if(val[0]) subdivy = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"divx",0);
|
||||
if(val[0]) divx = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"divy",0);
|
||||
if(val[0]) divy = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"x1",0);
|
||||
if(val[0]) wx1 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"y1",0);
|
||||
if(val[0]) wy1 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"x2",0);
|
||||
if(val[0]) wx2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"y2",0);
|
||||
if(val[0]) wy2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"digital",0);
|
||||
if(val[0]) digital = atoi(val);
|
||||
/* plot single dataset */
|
||||
val = get_tok_value(r->prop_ptr,"dataset",0);
|
||||
if(val[0]) dataset = atoi(val);
|
||||
if(dataset >= xctx->datasets) dataset = xctx->datasets - 1;
|
||||
/* set margins */
|
||||
calc_graph_area(c, i, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
double tmp, txtsizex, txtsizey;
|
||||
|
||||
w = (x2 - x1);
|
||||
h = (y2 - y1);
|
||||
/* cache coefficients for faster graph coord transformations */
|
||||
cx = (x2 - x1) / (wx2 - wx1);
|
||||
dx = x1 - wx1 * cx;
|
||||
cy = (y1 - y2) / (wy2 - wy1);
|
||||
dy = y2 - wy1 * cy;
|
||||
/* x axis, y axis label text sizes */
|
||||
txtsizey = h / divy * 0.009;
|
||||
tmp = marginx * 0.005;
|
||||
if(tmp < txtsizey) txtsizey = tmp;
|
||||
tmp = marginy * 0.02;
|
||||
if(tmp < txtsizey) txtsizey = tmp;
|
||||
|
||||
txtsizex = w / divx * 0.0033;
|
||||
tmp = marginy * 0.0083;
|
||||
if(tmp < txtsizex) txtsizex = tmp;
|
||||
|
||||
/* calculate dash length for grid lines */
|
||||
dash_sizex = 1.5 * xctx->mooz;
|
||||
|
|
@ -1902,22 +1943,10 @@ void draw_graph(int c, int i, int flags)
|
|||
dash_sizey = dash_sizey > 2.0 ? 2.0 : dash_sizey;
|
||||
if(dash_sizey <= 1.0) dash_sizey = 1.0;
|
||||
|
||||
/* x axis, y axis, label text sizes */
|
||||
txtsizey = h / divy / 90 ;
|
||||
tmp = marginx / 200;
|
||||
if(tmp < txtsizey) txtsizey = tmp;
|
||||
|
||||
txtsizex = w / divx / 300;
|
||||
tmp = marginy / 110;
|
||||
if(tmp < txtsizex) txtsizex = tmp;
|
||||
|
||||
txtsizelab = marginy / 110;
|
||||
if(digital) txtsizelab /= 1.3;
|
||||
|
||||
/* background */
|
||||
filledrect(0, NOW, rx1, ry1, rx2, ry2);
|
||||
/* graph bounding box */
|
||||
drawrect(c, NOW, rx1, ry1, rx2, ry2, 2);
|
||||
drawrect(GRIDLAYER, NOW, rx1, ry1, rx2, ry2, 2);
|
||||
|
||||
/* vertical grid lines */
|
||||
deltax = axis_increment(wx1, wx2, divx);
|
||||
|
|
@ -1960,18 +1989,117 @@ void draw_graph(int c, int i, int flags)
|
|||
drawline(GRIDLAYER, ADD, W_X(wx1)-4, W_Y(wy), W_X(wx1), W_Y(wy), 0); /* axis marks */
|
||||
/* Y-axis labels */
|
||||
my_snprintf(lab, S(lab), "%g", wy * unity);
|
||||
draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - 2 - 30 * txtsizey, W_Y(wy), txtsizey, txtsizey);
|
||||
draw_string(3, NOW, lab, 0, 1, 0, 1, x1 - 4 - 30 * txtsizey, W_Y(wy), txtsizey, txtsizey);
|
||||
}
|
||||
}
|
||||
/* first and last horizontal box delimiters */
|
||||
drawline(GRIDLAYER, ADD, W_X(wx1), W_Y(wy1), W_X(wx2), W_Y(wy1), 0);
|
||||
drawline(GRIDLAYER, ADD, W_X(wx1), W_Y(wy2), W_X(wx2), W_Y(wy2), 0);
|
||||
/* Horizontal axis (if in viewport) */
|
||||
if(wy1 <= 0 && wy2 >= 0) drawline(GRIDLAYER, ADD, W_X(wx1), W_Y(0), W_X(wx2), W_Y(0), 0);
|
||||
if(!digital && wy1 <= 0 && wy2 >= 0) drawline(GRIDLAYER, ADD, W_X(wx1), W_Y(0), W_X(wx2), W_Y(0), 0);
|
||||
/* Vertical axis (if in viewport)
|
||||
* swap order of wy1 and wy2 since grap y orientation is opposite to xorg orientation */
|
||||
if(wx1 <= 0 && wx2 >= 0) drawline(GRIDLAYER, ADD, W_X(0), W_Y(wy2), W_X(0), W_Y(wy1), 0);
|
||||
drawline(GRIDLAYER, END, 0.0, 0.0, 0.0, 0.0, 0);
|
||||
}
|
||||
|
||||
void draw_graph(int c, int i, int flags)
|
||||
{
|
||||
/* container box */
|
||||
double rx1, ry1, rx2, ry2, rw/*, rh */;
|
||||
/* graph box (smaller due to margins) */
|
||||
double x1, y1, x2, y2;
|
||||
/* graph coordinate, some defaults */
|
||||
int digital = 0;
|
||||
int dig_max_waves = 10; /* max waves that can be stacked, then vertical pan can be used to view more */
|
||||
double wx1 = -2e-6;
|
||||
double wy1 = -1;
|
||||
double wx2 = 8e-6;
|
||||
double wy2 = 4;
|
||||
double marginx = 20; /* will be recalculated later */
|
||||
double marginy = 20; /* will be recalculated later */
|
||||
/* coefficients for graph to container coordinate transformations W_X() and W_Y()*/
|
||||
double cx, dx, cy, dy;
|
||||
int divx = 10;
|
||||
int divy = 5;
|
||||
int subdivx = 0;
|
||||
int subdivy = 0;
|
||||
double unitx = 1.0;
|
||||
double unity = 1.0;
|
||||
int unitx_suffix = ' '; /* 'n' or 'u' or 'M' or 'k' ... */
|
||||
int unity_suffix = ' ';
|
||||
int wave_color = 5;
|
||||
const char *val;
|
||||
char *node = NULL, *color = NULL, *sweep = NULL;
|
||||
double txtsizelab, digtxtsizelab, tmp;
|
||||
Int_hashentry *entry;
|
||||
int sweep_idx = 0;
|
||||
int n_nodes; /* number of variables to display in a single graph */
|
||||
xRect *r = &xctx->rect[c][i];
|
||||
char tmpstr[200];
|
||||
char *saven, *savec, *saves, *nptr, *cptr, *sptr;
|
||||
const char *ntok, *ctok, *stok;
|
||||
char *bus_msb = NULL;
|
||||
int wcnt = 0;
|
||||
int dataset = -1;
|
||||
/* container (embedding rectangle) coordinates */
|
||||
rx1 = r->x1;
|
||||
ry1 = r->y1;
|
||||
rx2 = r->x2;
|
||||
ry2 = r->y2;
|
||||
rw = (rx2 - rx1);
|
||||
/* rh = (ry2 -ry1); */
|
||||
/* get variables to plot, x/y range, grid info etc */
|
||||
val = get_tok_value(r->prop_ptr,"unitx",0);
|
||||
unitx_suffix = val[0];
|
||||
unitx = get_unit(val);;
|
||||
val = get_tok_value(r->prop_ptr,"unity",0);
|
||||
unity_suffix = val[0];
|
||||
unity = get_unit(val);;
|
||||
val = get_tok_value(r->prop_ptr,"subdivx",0);
|
||||
if(val[0]) subdivx = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"subdivy",0);
|
||||
if(val[0]) subdivy = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"divx",0);
|
||||
if(val[0]) divx = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"divy",0);
|
||||
if(val[0]) divy = atoi(val);
|
||||
val = get_tok_value(r->prop_ptr,"x1",0);
|
||||
if(val[0]) wx1 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"y1",0);
|
||||
if(val[0]) wy1 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"x2",0);
|
||||
if(val[0]) wx2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"y2",0);
|
||||
if(val[0]) wy2 = atof(val);
|
||||
val = get_tok_value(r->prop_ptr,"digital",0);
|
||||
if(val[0]) digital = atoi(val);
|
||||
if(digital) {
|
||||
val = get_tok_value(r->prop_ptr,"dig_max_waves",0);
|
||||
if(val[0]) dig_max_waves = atoi(val);
|
||||
}
|
||||
/* plot single dataset */
|
||||
val = get_tok_value(r->prop_ptr,"dataset",0);
|
||||
if(val[0]) dataset = atoi(val);
|
||||
if(dataset >= xctx->graph_datasets) dataset = xctx->graph_datasets - 1;
|
||||
/* set margins */
|
||||
calc_graph_area(c, i, digital, &x1, &y1, &x2, &y2, &marginx, &marginy);
|
||||
|
||||
txtsizelab = marginy * 0.011;
|
||||
tmp = (x2 - x1) / divx * 0.0033;
|
||||
if(tmp < txtsizelab) txtsizelab = tmp;
|
||||
digtxtsizelab = txtsizelab * 0.7;
|
||||
/* cache coefficients for faster graph coord transformations */
|
||||
cx = (x2 - x1) / (wx2 - wx1);
|
||||
dx = x1 - wx1 * cx;
|
||||
cy = (y1 - y2) / (wy2 - wy1);
|
||||
dy = y2 - wy1 * cy;
|
||||
|
||||
/* graph box, gridlines and axes */
|
||||
draw_graph_grid(rx1, ry1, rx2, ry2, x1, y1, x2, y2, marginx, marginy,
|
||||
wx1, wy1, wx2, wy2, cx, cy, dx, dy,
|
||||
divx, divy, subdivx, subdivy, unitx, unity, digital);
|
||||
|
||||
/* get data to plot */
|
||||
my_strdup2(1389, &node, get_tok_value(r->prop_ptr,"node",0));
|
||||
my_strdup2(1390, &color, get_tok_value(r->prop_ptr,"color",0));
|
||||
|
|
@ -1980,8 +2108,11 @@ void draw_graph(int c, int i, int flags)
|
|||
cptr = color;
|
||||
sptr = sweep;
|
||||
n_nodes = count_items(node, " \t\n");
|
||||
/* process each node given in "node" attribute, get also associated color if any*/
|
||||
/* process each node given in "node" attribute, get also associated color/sweep var if any*/
|
||||
while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) {
|
||||
if(strstr(ntok, ",")) {
|
||||
my_strdup2(1452, &bus_msb, find_nth(ntok, ',', 2));
|
||||
}
|
||||
ctok = my_strtok_r(cptr, " ", &savec);
|
||||
stok = my_strtok_r(sptr, " ", &saves);
|
||||
nptr = cptr = sptr = NULL;
|
||||
|
|
@ -1993,28 +2124,43 @@ void draw_graph(int c, int i, int flags)
|
|||
sweep_idx = 0;
|
||||
}
|
||||
}
|
||||
/* clipping everything outside container area */
|
||||
bbox(START, 0.0, 0.0, 0.0, 0.0);
|
||||
bbox(ADD, rx1, ry1, rx2, ry2);
|
||||
bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
|
||||
/* draw sweep variable(s) on x-axis */
|
||||
if(wcnt == 0 || (stok && stok[0])) {
|
||||
if(xctx->values) stok = xctx->names[sweep_idx];
|
||||
if(xctx->graph_values) stok = xctx->graph_names[sweep_idx];
|
||||
if(unitx != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", stok ? stok : "" , unitx_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), "%s", stok ? stok : "");
|
||||
draw_string(wave_color, NOW, tmpstr, 2, 1, 0, 0,
|
||||
rx1 + 2 + rw / n_nodes * wcnt, ry2-1, txtsizelab, txtsizelab);
|
||||
}
|
||||
/* draw node labels in graph */
|
||||
if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", ntok, unity_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), "%s", ntok);
|
||||
if(bus_msb) {
|
||||
if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", find_nth(ntok, ',', 1), unity_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), "%s",find_nth(ntok, ',', 1));
|
||||
} else {
|
||||
if(unity != 1.0) my_snprintf(tmpstr, S(tmpstr), "%s[%c]", ntok, unity_suffix);
|
||||
else my_snprintf(tmpstr, S(tmpstr), "%s", ntok);
|
||||
}
|
||||
if(digital) {
|
||||
draw_string(wave_color, NOW, tmpstr, 0, 1, 0, 1,
|
||||
x1 - 2 - 30 * txtsizelab,
|
||||
W_Y((wy2 - wy1) * ((double)wcnt + 0.5) / n_nodes ),
|
||||
txtsizelab, txtsizelab);
|
||||
/* int n = n_nodes > dig_max_waves ? dig_max_waves : n_nodes; */
|
||||
int n = dig_max_waves;
|
||||
double xt = x1 - 4 - 30 * txtsizelab;
|
||||
double delta_div_n = (wy2 - wy1) / n;
|
||||
double yt = delta_div_n * (double)wcnt;
|
||||
|
||||
if(yt <= wy2 && yt >= wy1) {
|
||||
draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0, xt, W_Y(yt), digtxtsizelab, digtxtsizelab);
|
||||
}
|
||||
} else {
|
||||
draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0, rx1 + rw / n_nodes * wcnt, ry1, txtsizelab, txtsizelab);
|
||||
}
|
||||
bbox(END, 0.0, 0.0, 0.0, 0.0);
|
||||
/* quickly find index number of ntok variable to be plotted */
|
||||
entry = int_hash_lookup(xctx->raw_table, ntok, 0, XLOOKUP);
|
||||
if(xctx->values && entry) {
|
||||
entry = int_hash_lookup(xctx->raw_table, bus_msb ? bus_msb : ntok, 0, XLOOKUP);
|
||||
if(xctx->graph_values && entry) {
|
||||
int p, dset, ofs;
|
||||
int poly_npoints;
|
||||
int v;
|
||||
|
|
@ -2034,23 +2180,29 @@ void draw_graph(int c, int i, int flags)
|
|||
start = (wx1 <= wx2) ? wx1 : wx2;
|
||||
end = (wx1 <= wx2) ? wx2 : wx1;
|
||||
/* loop through all datasets found in raw file */
|
||||
for(dset = 0 ; dset < xctx->datasets; dset++) {
|
||||
for(dset = 0 ; dset < xctx->graph_datasets; dset++) {
|
||||
if(dataset == -1 || dset == dataset) {
|
||||
double prev_x;
|
||||
first = -1;
|
||||
poly_npoints = 0;
|
||||
my_realloc(1401, &xarr, xctx->npoints[dset] * sizeof(double));
|
||||
my_realloc(1402, &yarr, xctx->npoints[dset] * sizeof(double));
|
||||
my_realloc(1401, &xarr, xctx->graph_npoints[dset] * sizeof(double));
|
||||
my_realloc(1402, &yarr, xctx->graph_npoints[dset] * sizeof(double));
|
||||
/* Process "npoints" simulation items
|
||||
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
|
||||
for(p = ofs ; p < ofs + xctx->npoints[dset]; p++) {
|
||||
xx = xctx->values[sweep_idx][p];
|
||||
for(p = ofs ; p < ofs + xctx->graph_npoints[dset]; p++) {
|
||||
xx = xctx->graph_values[sweep_idx][p];
|
||||
if(xx > end || (sweep_idx == 0 && (p > ofs && fabs(xx) < fabs(prev_x))) ) {
|
||||
if(first != -1) {
|
||||
/* get y-axis points */
|
||||
get_y_points(v, first, p, cy, dy, yarr, digital, wcnt, n_nodes, wy2 - wy1);
|
||||
/* plot data */
|
||||
drawpolygon(wave_color, 0, xarr, yarr, poly_npoints, 0, 0);
|
||||
if(bus_msb) {
|
||||
if(digital) {
|
||||
draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color,
|
||||
sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2);
|
||||
}
|
||||
} else {
|
||||
draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color,
|
||||
digital, dig_max_waves, wcnt, n_nodes, wy1, wy2);
|
||||
}
|
||||
poly_npoints = 0;
|
||||
first = -1;
|
||||
}
|
||||
|
|
@ -2065,20 +2217,27 @@ void draw_graph(int c, int i, int flags)
|
|||
}
|
||||
if(first != -1) {
|
||||
/* get y-axis points */
|
||||
get_y_points(v, first, p, cy, dy, yarr, digital, wcnt, n_nodes, wy2 - wy1);
|
||||
/* plot data */
|
||||
drawpolygon(wave_color, 0, xarr, yarr, poly_npoints, 0, 0);
|
||||
if(bus_msb) {
|
||||
if(digital) {
|
||||
draw_graph_bus_points(ntok, first, p, cx, dx, cy, dy, wave_color,
|
||||
sweep_idx, digital, dig_max_waves, wcnt, n_nodes, wy1, wy2);
|
||||
}
|
||||
} else {
|
||||
draw_graph_points(v, first, p, cy, dy, xarr, yarr, wave_color,
|
||||
digital, dig_max_waves, wcnt, n_nodes, wy1, wy2);
|
||||
}
|
||||
}
|
||||
} /* if(dataset == -1 || dset == dataset) */
|
||||
|
||||
/* offset pointing to next dataset */
|
||||
ofs += xctx->npoints[dset];
|
||||
ofs += xctx->graph_npoints[dset];
|
||||
} /* for(dset...) */
|
||||
my_free(1403, &xarr);
|
||||
my_free(1404, &yarr);
|
||||
bbox(END, 0.0, 0.0, 0.0, 0.0);
|
||||
}/* if(entry) */
|
||||
wcnt++;
|
||||
if(bus_msb) my_free(1453, &bus_msb);
|
||||
} /* while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) */
|
||||
if(flags & 1) {
|
||||
bbox(START, 0.0, 0.0, 0.0, 0.0);
|
||||
|
|
@ -2098,16 +2257,16 @@ void draw_graph(int c, int i, int flags)
|
|||
/* fill graph boxes with data from ngspice simulations */
|
||||
/* flags:
|
||||
* 1: do final XCopyArea (copy 2nd buffer areas to screen)
|
||||
* If draw_waves() is called from draw() no need to do XCopyArea, as draw() does it already.
|
||||
* If draw_graph_all() is called from draw() no need to do XCopyArea, as draw() does it already.
|
||||
* This makes drawing faster and removes a 'tearing' effect when moving around.
|
||||
*/
|
||||
void draw_waves(int flags)
|
||||
void draw_graph_all(int flags)
|
||||
{
|
||||
int c, i, sch_loaded, hide_graphs;
|
||||
int bbox_set = 0;
|
||||
const char *tmp;
|
||||
int save_bbx1, save_bby1, save_bbx2, save_bby2;
|
||||
/* save bbox data, since draw_waves() is called from draw() which may be called after a bbox(SET) */
|
||||
/* save bbox data, since draw_graph_all() is called from draw() which may be called after a bbox(SET) */
|
||||
sch_loaded = schematic_waves_loaded();
|
||||
tmp = tclgetvar("hide_empty_graphs");
|
||||
hide_graphs = (tmp && tmp[0] == '1') ? 1 : 0;
|
||||
|
|
@ -2176,7 +2335,7 @@ void draw(void)
|
|||
xctx->areaw, xctx->areah);
|
||||
dbg(1, "draw(): window: %d %d %d %d\n",xctx->areax1, xctx->areay1, xctx->areax2, xctx->areay2);
|
||||
drawgrid();
|
||||
draw_waves(0);
|
||||
draw_graph_all(0);
|
||||
x1 = X_TO_XSCHEM(xctx->areax1);
|
||||
y1 = Y_TO_XSCHEM(xctx->areay1);
|
||||
x2 = X_TO_XSCHEM(xctx->areax2);
|
||||
|
|
|
|||
|
|
@ -1964,7 +1964,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
{
|
||||
cmd_found = 1;
|
||||
tclsetvar("rawfile_loaded", "0");
|
||||
free_rawfile();
|
||||
free_rawfile(1);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
|
|
@ -1977,7 +1977,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_ResetResult(interp);
|
||||
if(argc > 2 && !strcmp(argv[2], "loaded")) {
|
||||
Tcl_AppendResult(interp, schematic_waves_loaded() ? "1" : "0", NULL);
|
||||
} else if(xctx->values) {
|
||||
} else if(xctx->graph_values) {
|
||||
if(argc > 5) dataset = atoi(argv[5]);
|
||||
if(argc > 4) {
|
||||
/* xschem rawfile_query value v(ldcp) 123 */
|
||||
|
|
@ -1985,10 +1985,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
int point = atoi(argv[4]);
|
||||
const char *node = argv[3];
|
||||
int idx = -1;
|
||||
if(point >= 0 && point < xctx->npoints[dataset]) {
|
||||
if(point >= 0 && point < xctx->graph_npoints[dataset]) {
|
||||
if(isonlydigit(node)) {
|
||||
int i = atoi(node);
|
||||
if(i >= 0 && i < xctx->nvars) {
|
||||
if(i >= 0 && i < xctx->graph_nvars) {
|
||||
idx = i;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2013,14 +2013,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
}
|
||||
} else if(argc > 2) {
|
||||
if(!strcmp(argv[2], "points")) {
|
||||
my_snprintf(s, S(s), "%d", xctx->npoints[0]);
|
||||
my_snprintf(s, S(s), "%d", xctx->graph_npoints[0]);
|
||||
Tcl_AppendResult(interp, s, NULL);
|
||||
} else if(!strcmp(argv[2], "vars")) {
|
||||
my_snprintf(s, S(s), "%d", xctx->nvars);
|
||||
my_snprintf(s, S(s), "%d", xctx->graph_nvars);
|
||||
Tcl_AppendResult(interp, s, NULL);
|
||||
} else if(!strcmp(argv[2], "list")) {
|
||||
for(i = 0 ; i < xctx->nvars; i++) {
|
||||
Tcl_AppendResult(interp, xctx->names[i], "\n", NULL);
|
||||
for(i = 0 ; i < xctx->graph_nvars; i++) {
|
||||
Tcl_AppendResult(interp, xctx->graph_names[i], "\n", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2031,9 +2031,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
{
|
||||
cmd_found = 1;
|
||||
if(schematic_waves_loaded()) {
|
||||
free_rawfile();
|
||||
free_rawfile(1);
|
||||
} else if(argc > 2) {
|
||||
free_rawfile();
|
||||
free_rawfile(0);
|
||||
read_rawfile(argv[2]);
|
||||
if(schematic_waves_loaded()) tclsetvar("rawfile_loaded", "1");
|
||||
else tclsetvar("rawfile_loaded", "0");
|
||||
|
|
|
|||
27
src/select.c
27
src/select.c
|
|
@ -545,6 +545,33 @@ void bbox(int what,double x1,double y1, double x2, double y2)
|
|||
xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case SET_INSIDE: /* do not add line widths to clip rectangle so everything remains inside */
|
||||
if(xctx->sem==0) {
|
||||
fprintf(errfp, "ERROR: bbox(SET_INSIDE) call before bbox(START)\n");
|
||||
tcleval("alert_ {ERROR: bbox(SET_INSIDE) call before bbox(START)} {}");
|
||||
}
|
||||
xctx->areax1 = xctx->bbx1-2*INT_WIDTH(xctx->lw);
|
||||
xctx->areax2 = xctx->bbx2+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay1 = xctx->bby1-2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay2 = xctx->bby2+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areaw = (xctx->areax2-xctx->areax1);
|
||||
xctx->areah = (xctx->areay2-xctx->areay1);
|
||||
|
||||
xctx->xrect[0].x = xctx->bbx1+INT_WIDTH(xctx->lw);
|
||||
xctx->xrect[0].y = xctx->bby1+INT_WIDTH(xctx->lw);
|
||||
xctx->xrect[0].width = xctx->bbx2-xctx->bbx1-2*INT_WIDTH(xctx->lw);
|
||||
xctx->xrect[0].height = xctx->bby2-xctx->bby1-2*INT_WIDTH(xctx->lw);
|
||||
if(has_x) {
|
||||
set_clip_mask(SET);
|
||||
dbg(2, "bbox(SET): setting clip area: %d %d %d %d\n",
|
||||
xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
14
src/xinit.c
14
src/xinit.c
|
|
@ -422,12 +422,13 @@ void alloc_xschem_data(const char *top_path)
|
|||
xctx->mooz=1/CADINITIALZOOM;
|
||||
xctx->xorigin=CADINITIALX;
|
||||
xctx->yorigin=CADINITIALY;
|
||||
xctx->names = NULL;
|
||||
xctx->values = NULL;
|
||||
xctx->nvars = 0;
|
||||
xctx->npoints = NULL;
|
||||
xctx->datasets = 0;
|
||||
xctx->graph_names = NULL;
|
||||
xctx->graph_values = NULL;
|
||||
xctx->graph_nvars = 0;
|
||||
xctx->graph_npoints = NULL;
|
||||
xctx->graph_datasets = 0;
|
||||
xctx->graph_master = 0;
|
||||
xctx->graph_flags = 0;
|
||||
xctx->graph_bottom = 0;
|
||||
xctx->graph_left = 0;
|
||||
xctx->raw_schname = NULL;
|
||||
|
|
@ -621,7 +622,7 @@ void delete_schematic_data(void)
|
|||
* inst & wire .node fields, instance name hash */
|
||||
clear_drawing();
|
||||
remove_symbols();
|
||||
free_rawfile();
|
||||
free_rawfile(0);
|
||||
free_xschem_data(); /* delete the xctx struct */
|
||||
}
|
||||
|
||||
|
|
@ -1264,6 +1265,7 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h)
|
|||
}
|
||||
}
|
||||
if(xctx->pending_fullzoom) {
|
||||
dbg(1, "resetwin(): pending_fulzoom: doing zoom_full()\n");
|
||||
zoom_full(0, 0, 1, 0.97);
|
||||
xctx->pending_fullzoom=0;
|
||||
}
|
||||
|
|
|
|||
44
src/xschem.h
44
src/xschem.h
|
|
@ -248,6 +248,7 @@ extern char win_temp_dir[PATH_MAX];
|
|||
#define THICK 1024 /* used to draw thick lines (buses) */
|
||||
#define ROTATELOCAL 2048 /* rotate each selected object around its own anchor point 20171208 */
|
||||
#define CLEAR 4096 /* used in new_wire to clear previous rubber when switching xctx->manhattan_lines */
|
||||
#define SET_INSIDE 8192 /* used in bbox() to set clipping rectangle inside, not adding line width */
|
||||
/* #define DRAW 8192 */ /* was used in bbox() to draw things by using XCopyArea after setting clip rectangle */
|
||||
#define HILIGHT 8192 /* used when calling draw_*symbol_outline() for hilighting instead of normal draw */
|
||||
#define FONTWIDTH 20
|
||||
|
|
@ -635,6 +636,32 @@ typedef struct
|
|||
unsigned short *wireflag;
|
||||
} Iterator_ctx;
|
||||
|
||||
|
||||
/* will be used some day? <<<< */
|
||||
typedef struct {
|
||||
/* container box */
|
||||
/* graph box (smaller tha rect container due to margins) */
|
||||
double x1, y1, x2, y2, w, h;
|
||||
/* graph coordinate, some defaults */
|
||||
double digital;
|
||||
double wx1, wy1, wx2, wy2;
|
||||
double marginx; /* will be recalculated later */
|
||||
double marginy; /* will be recalculated later */
|
||||
/* coefficients for graph to container coordinate transformations W_X() and W_Y()*/
|
||||
double cx, dx, cy, dy;
|
||||
double dash_sizex, dash_sizey;
|
||||
int divx;
|
||||
int divy;
|
||||
int subdivx;
|
||||
int subdivy;
|
||||
double unitx;
|
||||
double unity;
|
||||
int unitx_suffix; /* 'n' or 'u' or 'M' or 'k' ... */
|
||||
int unity_suffix;
|
||||
double txtsizelab, txtsizey, txtsizex;
|
||||
int dataset;
|
||||
} Graph_ctx;
|
||||
|
||||
typedef struct {
|
||||
xWire *wire;
|
||||
xText *text;
|
||||
|
|
@ -795,11 +822,12 @@ typedef struct {
|
|||
Undo_slot uslot[MAX_UNDO];
|
||||
int undo_initialized;
|
||||
/* read raw files (draw.c) */
|
||||
char **names;
|
||||
SPICE_DATA **values;
|
||||
int nvars;
|
||||
int *npoints;
|
||||
int datasets;
|
||||
char **graph_names;
|
||||
SPICE_DATA **graph_values;
|
||||
int graph_nvars;
|
||||
int *graph_npoints;
|
||||
int graph_datasets;
|
||||
int graph_flags; /* 1: zoom / pan all graphs even if only one selected */
|
||||
int graph_master; /* graph where mouse operations are started, used to lock x-axis */
|
||||
int graph_bottom; /* graph where mouse operations are started, used to lock x-axis */
|
||||
int graph_left; /* graph where mouse operations are started, used to lock x-axis */
|
||||
|
|
@ -922,11 +950,11 @@ extern Xschem_ctx *xctx;
|
|||
extern int get_raw_index(const char *node);
|
||||
extern double get_raw_value(int dataset, int idx, int point);
|
||||
extern int schematic_waves_loaded(void);
|
||||
extern void calc_graph_area(int c, int i, double *x1, double *y1,double *x2, double *y2,
|
||||
extern void calc_graph_area(int c, int i, int digital, double *x1, double *y1,double *x2, double *y2,
|
||||
double *marginx,double *marginy);
|
||||
extern void draw_graph(int c, int i, int flags);
|
||||
extern void draw_waves(int flags);
|
||||
extern void free_rawfile(void);
|
||||
extern void draw_graph_all(int flags);
|
||||
extern void free_rawfile(int dr);
|
||||
extern int read_rawfile(const char *f);
|
||||
extern double timer(int start);
|
||||
extern void enable_layers(void);
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ proc inutile_translate {f} {
|
|||
set p $XSCHEM_SHAREDIR/utile
|
||||
set savedir [pwd]
|
||||
cd $netlist_dir
|
||||
eval exec $p/preprocess.awk \"$f\" | $p/expand_alias.awk | $p/param.awk | $p/clock.awk | $p/stimuli.awk
|
||||
eval exec awk -f $p/preprocess.awk \"$f\" | awk -f $p/expand_alias.awk | awk -f $p/param.awk | awk -f $p/clock.awk | awk -f $p/stimuli.awk
|
||||
cd $savedir
|
||||
}
|
||||
|
||||
|
|
@ -1146,7 +1146,11 @@ proc simulate {{callback {}}} {
|
|||
set cmd [subst $sim($tool,$def,cmd)]
|
||||
if {$OS == "Windows"} {
|
||||
# $cmd cannot be surrounded by {} as exec will change forward slash to backward slash
|
||||
eval exec $cmd
|
||||
if { $callback ne {} } {
|
||||
eval $callback
|
||||
}
|
||||
#eval exec {cmd /V /C "cd $netlist_dir&&$cmd}
|
||||
eval exec $cmd &
|
||||
} else {
|
||||
set execute(callback) $callback
|
||||
$fg $st sh -c "cd $netlist_dir; $cmd"
|
||||
|
|
@ -1298,21 +1302,21 @@ proc edit_netlist {schname } {
|
|||
} elseif { $netlist_type=="spice" } {
|
||||
if {$OS == "Windows"} {
|
||||
set cmd "$editor \"$netlist_dir/${tmpname}.spice\""
|
||||
eval exec $cmd
|
||||
eval exec $cmd &
|
||||
} else {
|
||||
execute 0 sh -c "cd $netlist_dir && $editor $ftype \"${tmpname}.spice\""
|
||||
}
|
||||
} elseif { $netlist_type=="tedax" } {
|
||||
if {$OS == "Windows"} {
|
||||
set cmd "$editor \"$netlist_dir/${tmpname}.tdx\""
|
||||
eval exec $cmd
|
||||
eval exec $cmd &
|
||||
} else {
|
||||
execute 0 sh -c "cd $netlist_dir && $editor $ftype \"${tmpname}.tdx\""
|
||||
}
|
||||
} elseif { $netlist_type=="vhdl" } {
|
||||
if {$OS == "Windows"} {
|
||||
set cmd "$editor \"$netlist_dir/${tmpname}.vhdl\""
|
||||
eval exec $cmd
|
||||
eval exec $cmd &
|
||||
} else {
|
||||
execute 0 sh -c "cd $netlist_dir && $editor $ftype \"${tmpname}.vhdl\""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,26 +27,27 @@ L 8 1150 -160 1180 -160 {}
|
|||
L 8 1180 -160 1180 -120 {}
|
||||
L 8 1180 -120 1300 -120 {}
|
||||
L 8 820 -120 950 -120 {}
|
||||
B 2 1840 -360 2890 -280 {flags=1
|
||||
y1 = -0.0039
|
||||
y2 = 0.87
|
||||
B 2 1840 -400 2890 -280 {flags=1
|
||||
y1 = 0
|
||||
y2 = 0.9
|
||||
divy = 1
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07 divx=10
|
||||
subdivy=2
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07 divx=10
|
||||
node="
|
||||
v(ldbl[0]) v(ldbl[16]) v(ldbl[32])
|
||||
v(ldbl[1]) v(ldbl[17]) v(ldbl[33])
|
||||
v(ldbl[2]) v(ldbl[18]) v(ldbl[34])
|
||||
"
|
||||
color="8 9 10 11 12 13 14 15 16 17 18" unitx=n}
|
||||
B 2 1840 -920 2890 -710 {flags=1
|
||||
B 2 1840 -1090 2890 -880 {flags=1
|
||||
digital=0
|
||||
y1 = -0.00091
|
||||
y2 = 1.5
|
||||
subdivy=4
|
||||
y1 = -0.0120424
|
||||
y2 = 1.50796
|
||||
subdivy=1
|
||||
divy = 4
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07
|
||||
divx=10
|
||||
subdivx=4
|
||||
node="v(ldcp) v(ldyms[4]) v(ldyms[5]) v(ldyms[6]) v(ldyms[7])"
|
||||
|
|
@ -56,10 +57,10 @@ B 2 1840 -280 2890 -120 {flags=1
|
|||
y1 = -0.0072
|
||||
y2 = 1.6
|
||||
divy = 3
|
||||
subdivy=1
|
||||
subdivx = 4
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07 divx=10
|
||||
subdivy=0
|
||||
subdivx = 1
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07 divx=10
|
||||
node="
|
||||
v(ldcp)
|
||||
v(ldwl[0]) v(ldwl[1]) v(ldwl[2]) v(ldwl[3])
|
||||
|
|
@ -70,85 +71,48 @@ color="4 5"
|
|||
unitx=n
|
||||
}
|
||||
B 2 1840 -120 2890 -40 {flags=1
|
||||
y1 = -0.021
|
||||
y1 = 0
|
||||
y2 = 0.9
|
||||
divy = 1
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07 divx=10
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07 divx=10
|
||||
node="v(ldymsref)"
|
||||
color=3 unitx=n subdivy=4}
|
||||
B 2 1840 -710 2890 -360 {flags=1
|
||||
B 2 1840 -880 2890 -400 {flags=1
|
||||
digital=1
|
||||
y1 = 0
|
||||
y2 = 1.5
|
||||
dig_max_waves=12
|
||||
y1 = -0.0811982
|
||||
y2 = 1.4188
|
||||
divy = 1
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07 divx=10
|
||||
node="v(ldcp) v(lden) v(ldprech)
|
||||
---
|
||||
v(ldl1x[0]) v(ldl1x[1]) v(ldl1x[2]) v(ldl1x[3])
|
||||
v(ldl1x[4]) v(ldl1x[5]) v(ldl1x[6]) v(ldl1x[7])
|
||||
---
|
||||
v(ldy1[0]) v(ldy1[1]) v(ldy1[2]) v(ldy1[3])
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07
|
||||
divx=10
|
||||
subdivx=4
|
||||
node="
|
||||
v(lden) v(ldprech)
|
||||
---Timing---
|
||||
LDL3X,v(ldl3x[7]),v(ldl3x[6]),v(ldl3x[5]),v(ldl3x[4]),v(ldl3x[3]),v(ldl3x[2]),v(ldl3x[1]),v(ldl3x[0])
|
||||
LDL2X,v(ldl2x[3]),v(ldl2x[2]),v(ldl2x[1]),v(ldl2x[0])
|
||||
LDL1X,v(ldl1x[15]),v(ldl1x[14]),v(ldl1x[13]),v(ldl1x[12]),v(ldl1x[11]),v(ldl1x[10]),v(ldl1x[9]),v(ldl1x[8]),v(ldl1x[7]),v(ldl1x[6]),v(ldl1x[5]),v(ldl1x[4]),v(ldl1x[3]),v(ldl1x[2]),v(ldl1x[1]),v(ldl1x[0])
|
||||
LDY1,v(ldy1[3]),v(ldy1[2]),v(ldy1[1]),v(ldy1[0])
|
||||
---Decoders---
|
||||
LDQ,v(ldq[15]),v(ldq[14]),v(ldq[13]),v(ldq[12]),v(ldq[11]),v(ldq[10]),v(ldq[9]),v(ldq[8]),v(ldq[7]),v(ldq[6]),v(ldq[5]),v(ldq[4]),v(ldq[3]),v(ldq[2]),v(ldq[1]),v(ldq[0])
|
||||
LDA,v(lda[12]),v(lda[11]),v(lda[10]),v(lda[9]),v(lda[8]),v(lda[7]),v(lda[6]),v(lda[5]),v(lda[4]),v(lda[3]),v(lda[2]),v(lda[1]),v(lda[0])
|
||||
v(ldcp)
|
||||
---In/Out---
|
||||
"
|
||||
color=4
|
||||
xcolor="5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 3 4 5 6"
|
||||
color="4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15 4 15"
|
||||
unitx=n
|
||||
}
|
||||
B 2 1840 -1030 2890 -920 {flags=1
|
||||
y1 = 0
|
||||
y2 = 2
|
||||
divy = 2
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
divx=8
|
||||
comm="example of using tcl to replace the path
|
||||
with $path variable automatically"
|
||||
node="tcleval(v(xctrl.ldcp_ref) v(xctrl.ldprechref))"
|
||||
color="16 11 15"
|
||||
}
|
||||
B 2 1840 -1120 2890 -1030 {flags=1
|
||||
y1 = 0
|
||||
y2 = 2
|
||||
divy = 2
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
divx=8
|
||||
comm="example of using tcl to replace the path
|
||||
with $path variable automatically"
|
||||
node="tcleval(v(xctrl.ldcp_ref) v(xctrl.ldcpb))"
|
||||
color="16 11 15"
|
||||
}
|
||||
B 2 1840 -1210 2890 -1120 {flags=1
|
||||
y1 = 0
|
||||
y2 = 2
|
||||
divy = 2
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
divx=8
|
||||
comm="example of using tcl to replace the path
|
||||
with $path variable automatically"
|
||||
node="tcleval(v(xctrl.ldcp_ref) v(xctrl.ldouti) v(xctrl.ldoutib))"
|
||||
color="16 11 15"
|
||||
}
|
||||
B 2 1840 -1500 2890 -1320 {flags=1
|
||||
y1 = 0
|
||||
y2 = 2
|
||||
B 2 1840 -1270 2890 -1090 {flags=1
|
||||
y1 = -0.0479717
|
||||
y2 = 1.55203
|
||||
divy = 4
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
x1=1.30572e-07
|
||||
x2=1.82007e-07
|
||||
divx=8
|
||||
node="v(xsa[0].ldqi) v(xsa[0].ldqib) v(xsa[0].ldsali)"
|
||||
color="16 11 15"}
|
||||
B 2 1840 -1320 2890 -1210 {flags=1
|
||||
y1 = 0
|
||||
y2 = 2
|
||||
divy = 2
|
||||
x1=1.26223e-07
|
||||
x2=2.06222e-07
|
||||
divx=8
|
||||
node="v(xsa[0].ldqiii) v(xsa[0].ldqii) v(xsa[0].ldsali)"
|
||||
color="16 11 15"}
|
||||
color="16 8 15"}
|
||||
B 7 950 -250 980 -80 {}
|
||||
B 7 1150 -250 1180 -80 {}
|
||||
B 21 10 -970 240 -750 {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue