From cab89d03d94199c17dbfe236493644157a634827 Mon Sep 17 00:00:00 2001
From: Stefan Schippers
Date: Sat, 30 Mar 2024 19:20:51 +0100
Subject: [PATCH] revert to commit 2024-03-26 18:48:48
---
doc/xschem_man/install_xschem.html | 9 +-
src/actions.c | 2 +-
src/callback.c | 154 ++++++---------
src/draw.c | 221 +++++++++++-----------
src/save.c | 6 -
src/scheduler.c | 4 +-
src/xschem.h | 3 +-
xschem_library/examples/LCC_instances.sch | 10 +-
8 files changed, 186 insertions(+), 223 deletions(-)
diff --git a/doc/xschem_man/install_xschem.html b/doc/xschem_man/install_xschem.html
index 88b025bd..89ffc4ec 100644
--- a/doc/xschem_man/install_xschem.html
+++ b/doc/xschem_man/install_xschem.html
@@ -105,7 +105,10 @@ p{padding: 15px 30px 10px;}
./configure --prefix=new/prefix/path
-
+
+
+ DESTDIR is supported.
+
For testing purposes xschem can be run and invoked from the build directory
xschem-<version>/src/ without installation.
@@ -128,14 +131,12 @@ p{padding: 15px 30px 10px;}
If you need to override system settings, create a
~/.xschem/xschemrc. The easiest way is to copy the system
installed version from ${prefix}/share/xschem/xschemrc and then
- make the necessary changes.
+ make the necessary changes
user:$ mkdir ~/.xschem
user:$ cp <install root>/share/xschem/xschemrc ~/.xschem/xschemrc
- When xschem is run the first time it will do the above operations, create a
- ${HOME}/.xschem/ directory and place a xschemrc into it.
diff --git a/src/actions.c b/src/actions.c
index c323eee8..368a8573 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -2276,7 +2276,7 @@ int descend_schematic(int instnumber, int fallback, int alert)
Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
- backannotate_at_cursor_pos(2, 0, gr);
+ backannotate_at_cursor_b_pos(r, gr);
}
}
diff --git a/src/callback.c b/src/callback.c
index d94439b9..fc6cf28f 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -37,7 +37,7 @@ static int waves_selected(int event, KeySym key, int state, int button)
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sifficient */
if(xctx->ui_state & excl) skip = 1;
else if(sch_waves_loaded() < 0 ) skip = 1;
- else if(SET_MODMASK) skip = 1;
+ else if(key !='a' && SET_MODMASK) skip = 1;
else if(event == MotionNotify && (state & Button2Mask)) skip = 1;
else if(event == MotionNotify && (state & Button1Mask) && (state & ShiftMask)) skip = 1;
else if(event == ButtonPress && button == Button2) skip = 1;
@@ -204,18 +204,18 @@ static void start_wire(double mx, double my)
new_wire(PLACE,mx, my);
}
-static double interpolate_yval(int idx, int point_not_last, int p, double x, int sweep_idx)
+static double interpolate_yval(int idx, int point_not_last)
{
- double val = xctx->raw->values[idx][p];
+ double val = xctx->raw->values[idx][xctx->raw->annot_p];
/* not operating point, annotate from 'b' cursor */
- if((xctx->raw->allpoints > 1) && sweep_idx >= 0) {
+ if((xctx->raw->allpoints > 1) && xctx->raw->annot_sweep_idx >= 0) {
Raw *raw = xctx->raw;
- SPICE_DATA *sweep_gv = raw->values[sweep_idx];
+ SPICE_DATA *sweep_gv = raw->values[raw->annot_sweep_idx];
SPICE_DATA *gv = raw->values[idx];
if(point_not_last) {
- double dx = sweep_gv[p + 1] - sweep_gv[p];
- double dy = gv[p + 1] - gv[p];
- double offset = x - sweep_gv[p];
+ double dx = sweep_gv[raw->annot_p + 1] - sweep_gv[raw->annot_p];
+ double dy = gv[raw->annot_p + 1] - gv[raw->annot_p];
+ double offset = raw->annot_x - sweep_gv[raw->annot_p];
double interp = dx != 0.0 ? offset * dy / dx : 0.0;
val += interp;
}
@@ -223,14 +223,13 @@ static double interpolate_yval(int idx, int point_not_last, int p, double x, int
return val;
}
-void backannotate_at_cursor_pos(int cursor, int i, Graph_ctx *gr)
+void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
{
- xRect *r = &xctx->rect[GRIDLAYER][i];
if(sch_waves_loaded() >= 0) {
int dset, first = -1, last, dataset = gr->dataset, i, p, ofs = 0, ofs_end;
double start, end;
int sweepvar_wrap = 0, sweep_idx;
- double xx, cursorpos; /* xx is the p-th sweep variable value, cursorpos is cursor 'cursor' x position */
+ double xx, cursor2; /* xx is the p-th sweep variable value, cursor2 is cursor 'b' x position */
Raw *raw = xctx->raw;
int save_datasets = -1, save_npoints = -1;
/* transform multiple OP points into a dc sweep */
@@ -242,17 +241,16 @@ void backannotate_at_cursor_pos(int cursor, int i, Graph_ctx *gr)
}
sweep_idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1), NULL);
if(sweep_idx < 0) sweep_idx = 0;
- if(cursor == 1) cursorpos = xctx->graph_cursor1_x;
- else cursorpos = xctx->graph_cursor2_x;
+ cursor2 = xctx->graph_cursor2_x;
start = (gr->gx1 <= gr->gx2) ? gr->gx1 : gr->gx2;
end = (gr->gx1 <= gr->gx2) ? gr->gx2 : gr->gx1;
- dbg(1, "backannotate_at_cursor_pos(): start=%g, end=%g\n", start, end);
+ dbg(1, "start=%g, end=%g\n", start, end);
if(gr->logx) {
- cursorpos = pow(10, cursorpos);
+ cursor2 = pow(10, cursor2);
start = pow(10, start);
end = pow(10, end);
}
- dbg(1, "backannotate_at_cursor_pos(): cursor%d pos: %g dataset=%d\n", cursor, cursorpos, gr->dataset);
+ dbg(1, "cursor b pos: %g dataset=%d\n", cursor2, gr->dataset);
if(dataset < 0) dataset = 0; /* if all datasets are plotted use first for backannotation */
dbg(1, "dataset=%d\n", dataset);
ofs = 0;
@@ -274,15 +272,15 @@ void backannotate_at_cursor_pos(int cursor, int i, Graph_ctx *gr)
}
if(xx >= start && xx <= end) {
if((dataset == -1 && sweepvar_wrap == 0) || (dataset == sweepvar_wrap)) {
- dbg(1, "xx=%g cursorpos=%g first=%d last=%d start=%g end=%g p=%d wrap=%d sweepvar_wrap=%d ofs=%d\n",
- xx, cursorpos, first, last, start, end, p, wrap, sweepvar_wrap, ofs);
+ dbg(1, "xx=%g cursor2=%g first=%d last=%d start=%g end=%g p=%d wrap=%d sweepvar_wrap=%d ofs=%d\n",
+ xx, cursor2, first, last, start, end, p, wrap, sweepvar_wrap, ofs);
if(first == -1) first = p;
if(p == first) {
- if(xx == cursorpos) {goto done;}
- s = XSIGN0(xx - cursorpos);
+ if(xx == cursor2) {goto done;}
+ s = XSIGN0(xx - cursor2);
dbg(1, "s=%d\n", s);
} else {
- int ss = XSIGN0(xx - cursorpos);
+ int ss = XSIGN0(xx - cursor2);
dbg(1, "s=%d, ss=%d\n", s, ss);
if(ss != s) {goto done;}
}
@@ -304,35 +302,24 @@ void backannotate_at_cursor_pos(int cursor, int i, Graph_ctx *gr)
p = last;
sweep0 = raw->values[sweep_idx][first];
sweep1 = raw->values[sweep_idx][p];
- if(fabs(sweep0 - cursorpos) < fabs(sweep1 - cursorpos)) {
+ if(fabs(sweep0 - cursor2) < fabs(sweep1 - cursor2)) {
p = first;
}
}
dbg(1, "xx=%g, p=%d\n", xx, p);
- if(cursor == 2) {
- Tcl_UnsetVar(interp, "ngspice::ngspice_data", TCL_GLOBAL_ONLY);
- raw->annot_p = p;
- raw->annot_x = cursorpos;
- raw->annot_sweep_idx = sweep_idx;
- for(i = 0; i < raw->nvars; ++i) {
- char s[100];
- raw->cursor_b_val[i] = interpolate_yval(i, (p < ofs_end), p, cursorpos, sweep_idx);
- my_snprintf(s, S(s), "%.5g", raw->cursor_b_val[i]);
- /* tclvareval("array set ngspice::ngspice_data [list {", raw->names[i], "} ", s, "]", NULL); */
- Tcl_SetVar2(interp, "ngspice::ngspice_data", raw->names[i], s, TCL_GLOBAL_ONLY);
- }
- Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ vars", my_itoa( raw->nvars), TCL_GLOBAL_ONLY);
- Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ points", "1", TCL_GLOBAL_ONLY);
- } else { /* cursor == 1 */
- dbg(1, "backannotate_at_cursor_pos(): updating cursor_a_val with sweep_idx=%d\n", sweep_idx);
- dbg(1, " : cursorpos=%g\n", cursorpos);
- dbg(1, " : p=%d\n", p);
- for(i = 0; i < raw->nvars; ++i) {
- raw->cursor_a_val[i] = interpolate_yval(i, (p < ofs_end), p, cursorpos, sweep_idx);
- dbg(1, "backannotate_at_cursor_pos(): cursor_a_val[%d] = %g\n", i, raw->cursor_a_val[i]);
- }
- dbg(1, " : cursor_a_val[0]=%g\n", raw->cursor_a_val[0]);
+ Tcl_UnsetVar(interp, "ngspice::ngspice_data", TCL_GLOBAL_ONLY);
+ raw->annot_p = p;
+ raw->annot_x = cursor2;
+ raw->annot_sweep_idx = sweep_idx;
+ for(i = 0; i < raw->nvars; ++i) {
+ char s[100];
+ raw->cursor_b_val[i] = interpolate_yval(i, (p < ofs_end));
+ my_snprintf(s, S(s), "%.5g", raw->cursor_b_val[i]);
+ /* tclvareval("array set ngspice::ngspice_data [list {", raw->names[i], "} ", s, "]", NULL); */
+ Tcl_SetVar2(interp, "ngspice::ngspice_data", raw->names[i], s, TCL_GLOBAL_ONLY);
}
+ Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ vars", my_itoa( raw->nvars), TCL_GLOBAL_ONLY);
+ Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ points", "1", TCL_GLOBAL_ONLY);
}
if(save_npoints != -1) { /* restore multiple OP points from artificial dc sweep */
raw->datasets = save_datasets;
@@ -393,15 +380,14 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
/* set cursor position from master graph x-axis */
if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 16 )) {
xctx->graph_cursor1_x = G_X(xctx->mousex);
- backannotate_at_cursor_pos(1, i, gr);
}
/* move cursor2 */
/* set cursor position from master graph x-axis */
else if(event == MotionNotify && (state & Button1Mask) && (xctx->graph_flags & 32 )) {
int floaters = there_are_floaters();
xctx->graph_cursor2_x = G_X(xctx->mousex);
- backannotate_at_cursor_pos(2, i, gr);
if(tclgetboolvar("live_cursor2_backannotate")) {
+ backannotate_at_cursor_b_pos(r, gr);
if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
redraw_all_at_end = 1;
}
@@ -429,37 +415,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
xctx->graph_master = i;
zoom_m = (xctx->mousex - gr->x1) / gr->w;
if(event == ButtonPress && button == Button1) {
-
-
- if(xctx->graph_flags & 2) {
- int idx;
- double cursorx;
- idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1), NULL);
- cursorx = xctx->graph_cursor1_x;
- if(idx < 0) idx = 0;
- if(xctx->raw && xctx->raw->cursor_a_val) {
- cursorx = xctx->raw->cursor_a_val[idx];
- }
- if(gr->logx) cursorx = log10(cursorx);
- /* dragging cursors when mouse is very close */
- if( fabs(xctx->mousex - W_X(cursorx)) < 10) {
- xctx->graph_flags |= 16; /* Start move cursor1 */
- }
+ /* dragging cursors when mouse is very close */
+ if( (xctx->graph_flags & 2) && fabs(xctx->mousex - W_X(xctx->graph_cursor1_x)) < 10) {
+ xctx->graph_flags |= 16; /* Start move cursor1 */
}
- if(xctx->graph_flags & 4) {
- int idx;
- double cursorx;
- idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1), NULL);
- cursorx = xctx->graph_cursor2_x;
- if(idx < 0) idx = 0;
- if(xctx->raw && xctx->raw->cursor_b_val) {
- cursorx = xctx->raw->cursor_b_val[idx];
- }
- if(gr->logx) cursorx = log10(cursorx);
- /* dragging cursors when mouse is very close */
- if(fabs(xctx->mousex - W_X(cursorx)) < 10) {
- xctx->graph_flags |= 32; /* Start move cursor2 */
- }
+ if( (xctx->graph_flags & 4) && fabs(xctx->mousex - W_X(xctx->graph_cursor2_x)) < 10) {
+ xctx->graph_flags |= 32; /* Start move cursor2 */
}
}
else if(event == ButtonPress && button == Button3) {
@@ -498,15 +459,18 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
tclvareval("graph_edit_properties ", my_itoa(i), NULL);
}
}
+ /* backannotate node values at cursor b position */
+ else if(key == 'a' && EQUAL_MODMASK && (xctx->graph_flags & 4)) {
+ int floaters = there_are_floaters();
+ backannotate_at_cursor_b_pos(r, gr);
+ if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
+ redraw_all_at_end = 1;
+ }
/* x cursor1 toggle */
else if((key == 'a' && rstate == 0) ) {
xctx->graph_flags ^= 2;
need_all_redraw = 1;
- if(xctx->graph_flags & 2) {
- xctx->graph_cursor1_x = G_X(xctx->mousex);
- dbg(0, "waves_callback(): graph_cursor1_x=%g\n", xctx->graph_cursor1_x);
- backannotate_at_cursor_pos(1, i, gr);
- }
+ if(xctx->graph_flags & 2) xctx->graph_cursor1_x = G_X(xctx->mousex);
}
/* x cursor2 toggle */
else if((key == 'b') ) {
@@ -514,8 +478,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
xctx->graph_flags ^= 4;
if(xctx->graph_flags & 4) {
xctx->graph_cursor2_x = G_X(xctx->mousex);
- backannotate_at_cursor_pos(2, i, gr);
if(tclgetboolvar("live_cursor2_backannotate")) {
+ backannotate_at_cursor_b_pos(r, gr);
if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
redraw_all_at_end = 1;
} else {
@@ -535,9 +499,8 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
tmp = xctx->graph_cursor2_x;
xctx->graph_cursor2_x = xctx->graph_cursor1_x;
xctx->graph_cursor1_x = tmp;
- backannotate_at_cursor_pos(1, i, gr);
- backannotate_at_cursor_pos(2, i, gr);
if(tclgetboolvar("live_cursor2_backannotate")) {
+ backannotate_at_cursor_b_pos(r, gr);
if(floaters) set_modify(-2); /* update floater caches to reflect actual backannotation */
redraw_all_at_end = 1;
}
@@ -800,21 +763,15 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
set_modify(-2); /* update floater caches to reflect actual backannotation */
redraw_all_at_end = 1;
}
- if((xctx->graph_flags & 2)) {
+ if((xctx->graph_flags & 4) && tclgetboolvar("live_cursor2_backannotate")) {
if(i == xctx->graph_master) {
- backannotate_at_cursor_pos(1, i, gr);
+ backannotate_at_cursor_b_pos(r, gr);
}
- }
- if((xctx->graph_flags & 4)) {
- if(i == xctx->graph_master) {
- backannotate_at_cursor_pos(2, i, gr);
- }
- }
- if((xctx->graph_flags & 4) && tclgetboolvar("live_cursor2_backannotate")) {
redraw_all_at_end = 1;
} else {
if(!redraw_all_at_end) need_redraw = 1;
}
+
}
} /* key == 't' */
else if(key == XK_Left) {
@@ -2741,6 +2698,15 @@ int rstate; /* (reduced state, without ShiftMask) */
go_back(1);break;
}
+ if(key=='a' && EQUAL_MODMASK) /* graph annotate dc point @cursor2 */
+ {
+ if(xctx->semaphore >= 2) break;
+ if(waves_selected(event, key, state, button)) {
+ waves_callback(event, mx, my, key, button, aux, state);
+ break;
+ }
+ break;
+ }
if(key=='a' && rstate == 0) /* make symbol */
{
if(xctx->semaphore >= 2) break;
diff --git a/src/draw.c b/src/draw.c
index 31b6a0ec..f6159f05 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -2111,7 +2111,7 @@ int sch_waves_loaded(void)
return -1;
}
-static void get_bus_value(int n_bits, int hex_digits, int *idx_arr, int p, char *busval,
+static void get_bus_value(int n_bits, int hex_digits, SPICE_DATA **idx_arr, int p, char *busval,
double vthl, double vthh)
{
double val;
@@ -2122,21 +2122,8 @@ static void get_bus_value(int n_bits, int hex_digits, int *idx_arr, int p, char
char hexstr[] = "084C2A6E195D3B7F"; /* mirrored (Left/right) hex */
int x = 0;
for(i = n_bits - 1; i >= 0; i--) {
- if(p == -1) {
- if(idx_arr && idx_arr[i] != -1 && xctx->raw && xctx->raw->cursor_a_val) {
- val = xctx->raw->cursor_a_val[idx_arr[i]];
- }
- else {
- val = 0.0; /* undefined bus element */
- }
- } else {
- if(idx_arr && idx_arr[i] != -1) {
- double *valptr = xctx->raw->values[idx_arr[i]];
- val = valptr[p];
- } else {
- val = 0.0;
- }
- }
+ if(idx_arr[i]) val = idx_arr[i][p];
+ else val = 0.0; /* undefined bus element */
if(val >= vthl && val <= vthh) { /* signal transitioning --> 'X' */
x = 1; /* flag for 'X' value */
i += bin - 3;
@@ -2168,17 +2155,19 @@ static void get_bus_value(int n_bits, int hex_digits, int *idx_arr, int p, char
}
busval[hex_digits] = '\0';
}
+
+
/* idx_arr malloc-ated and returned, caller must free! */
-static int *get_bus_idx_array(const char *ntok, int *n_bits)
+static SPICE_DATA **get_bus_idx_array(const char *ntok, int *n_bits)
{
- int *idx_arr =NULL;
+ SPICE_DATA **idx_arr =NULL;
int p;
char *saven, *nptr, *ntok_copy = NULL;
const char *bit_name;
*n_bits = count_items(ntok, ";,", "") - 1;
dbg(1, "get_bus_idx_array(): ntok=%s\n", ntok);
dbg(1, "get_bus_idx_array(): *n_bits=%d\n", *n_bits);
- idx_arr = my_malloc(_ALLOC_ID_, (*n_bits) * sizeof(int));
+ idx_arr = my_malloc(_ALLOC_ID_, (*n_bits) * sizeof(SPICE_DATA *));
p = 0;
my_strdup2(_ALLOC_ID_, &ntok_copy, ntok);
nptr = ntok_copy;
@@ -2186,8 +2175,11 @@ static int *get_bus_idx_array(const char *ntok, int *n_bits)
while( (bit_name = my_strtok_r(NULL, ";, \n", "", 0, &saven)) ) {
int idx;
if(p >= *n_bits) break; /* security check to avoid out of bound writing */
- idx = get_raw_index(bit_name, NULL);
- idx_arr[p] = idx;
+ if( (idx = get_raw_index(bit_name, NULL)) != -1) {
+ idx_arr[p] = xctx->raw->values[idx];
+ } else {
+ idx_arr[p] = NULL;
+ }
/* dbg(0, "get_bus_idx_array(): bit_name=%s, p=%d\n", bit_name, p); */
++p;
}
@@ -2481,7 +2473,7 @@ int graph_fullyzoom(xRect *r, Graph_ctx *gr, int graph_dataset)
* 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 n_bits, int *idx_arr,
+static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx_arr,
int first, int last, int wave_col, int sweep_idx, int wcnt, int n_nodes, Graph_ctx *gr, void *ct)
{
int p;
@@ -2907,44 +2899,17 @@ void setup_graph_data(int i, int skip, Graph_ctx *gr)
gr->dsdy = (gr->ddy + xctx->yorigin) * xctx->mooz;
}
-static void draw_cursor(int active_cursor, int cursor_color, int i, Graph_ctx *gr)
+static void draw_cursor(double active_cursorx, double other_cursorx, int cursor_color, Graph_ctx *gr)
{
- double active_cursorx, other_cursorx;
- double xx;
+ double xx = W_X(active_cursorx);
double tx1, ty1, tx2, ty2, dtmp;
- int tmp, idx;
+ int tmp;
char tmpstr[100];
double txtsize = gr->txtsizex;
- short flip;
- int xoffs;
- xRect *r = &xctx->rect[GRIDLAYER][i];
+ short flip = (other_cursorx > active_cursorx) ? 0 : 1;
+ int xoffs = flip ? 3 : -3;
- if(active_cursor == 1) {
- active_cursorx = xctx->graph_cursor1_x;
- other_cursorx = xctx->graph_cursor2_x;
- } else {
- active_cursorx = xctx->graph_cursor2_x;
- other_cursorx = xctx->graph_cursor1_x;
- }
- idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1), NULL);
- dbg(1, "draw_cursor(): before: idx=%d, cursor=%g\n", idx, active_cursorx);
- if(idx < 0) idx = 0;
- if(xctx->raw && xctx->raw->cursor_a_val && xctx->raw->cursor_b_val) {
- if(active_cursor == 1) {
- active_cursorx = xctx->raw->cursor_a_val[idx];
- other_cursorx = xctx->raw->cursor_b_val[idx];
- } else {
- active_cursorx = xctx->raw->cursor_b_val[idx];
- other_cursorx = xctx->raw->cursor_a_val[idx];
- }
- }
- if(gr->logx) active_cursorx = log10(active_cursorx);
- if(gr->logx) other_cursorx = log10(other_cursorx);
- dbg(1, "draw_cursor(): after: idx=%d, cursor=%g\n", idx, active_cursorx);
- xx = W_X(active_cursorx);
- flip = (other_cursorx > active_cursorx) ? 0 : 1;
- xoffs = flip ? 3 : -3;
if(xx >= gr->x1 && xx <= gr->x2) {
drawline(cursor_color, NOW, xx, gr->ry1, xx, gr->ry2, 1, NULL);
if(gr->logx) active_cursorx = pow(10, active_cursorx);
@@ -3097,8 +3062,8 @@ static void draw_graph_variables(int wcnt, int wave_color, int n_nodes, int swee
bbox(END, 0.0, 0.0, 0.0, 0.0);
}
-static void show_node_measures(
- const char *bus_msb, int wave_color, int idx, int *idx_arr,
+static void show_node_measures(int measure_p, double measure_x, double measure_prev_x,
+ const char *bus_msb, int wave_color, int idx, SPICE_DATA **idx_arr,
int n_bits, int n_nodes, const char *ntok, int wcnt, Graph_ctx *gr)
{
char tmpstr[1024];
@@ -3109,52 +3074,56 @@ static void show_node_measures(
dbg(0, "show_node_measures(): no raw struct allocated\n");
return;
}
- dbg(1, "show_node_measures(): bus_msb=%s, ntok=%s\n", bus_msb ? bus_msb : "NULL", ntok);
- /* draw node values in graph */
- bbox(START, 0.0, 0.0, 0.0, 0.0);
- bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
- bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
- if(!bus_msb) {
- char *fmt1, *fmt2;
- if(xctx->raw->cursor_a_val)
- yy = xctx->raw->cursor_a_val[idx];
- else
- yy = 0.0;
- /* is below line necessary? */
- /* if(XSIGN0(gr->gy1) != XSIGN0(gr->gy2) && fabs(yy) < 1e-9 * fabs(gr->gh)) yy = 0.0; */
- if(yy != 0.0 && fabs(yy * gr->unity) < 1.0e-3) {
- fmt1="%.2e";
- fmt2="%.2e%c";
+ if(measure_p >= 0) {
+
+ /* draw node values in graph */
+ bbox(START, 0.0, 0.0, 0.0, 0.0);
+ bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
+ bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
+ if(!bus_msb) {
+ double diffy;
+ double diffx;
+ char *fmt1, *fmt2;
+ double yy1;
+ yy1 = xctx->raw->values[idx][measure_p-1];
+ diffy = xctx->raw->values[idx][measure_p] - yy1;
+ diffx = measure_x - measure_prev_x;
+ yy = yy1 + diffy / diffx * (xctx->graph_cursor1_x - measure_prev_x);
+ if(XSIGN0(gr->gy1) != XSIGN0(gr->gy2) && fabs(yy) < 1e-4 * fabs(gr->gh)) yy = 0.0;
+ if(yy != 0.0 && fabs(yy * gr->unity) < 1.0e-3) {
+ fmt1="%.2e";
+ fmt2="%.2e%c";
+ } else {
+ fmt1="%.4g";
+ fmt2="%.4g%c";
+ }
+ if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), fmt2, yy * gr->unity, gr->unity_suffix);
+ else my_snprintf(tmpstr, S(tmpstr), fmt1, yy);
} else {
- fmt1="%.4g";
- fmt2="%.4g%c";
+ double vthl, vthh;
+ int hex_digits = ((n_bits - 1) >> 2) + 1;
+ vthh = gr->gy1 * 0.2 + gr->gy2 * 0.8;
+ vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2;
+ get_bus_value(n_bits, hex_digits, idx_arr, measure_p - 1, tmpstr, vthl, vthh);
}
- if(gr->unity != 1.0) my_snprintf(tmpstr, S(tmpstr), fmt2, yy * gr->unity, gr->unity_suffix);
- else my_snprintf(tmpstr, S(tmpstr), fmt1, yy);
- } else {
- double vthl, vthh;
- int hex_digits = ((n_bits - 1) >> 2) + 1;
- vthh = gr->gy1 * 0.2 + gr->gy2 * 0.8;
- vthl = gr->gy1 * 0.8 + gr->gy2 * 0.2;
- get_bus_value(n_bits, hex_digits, idx_arr, -1, tmpstr, vthl, vthh);
- }
- if(!bus_msb && !gr->digital) {
- draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0,
- gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry1 + gr->txtsizelab * 60,
- gr->txtsizelab * 0.8, gr->txtsizelab * 0.8);
- dbg(1, "node: %s, value=%g\n", ntok, yy);
- }
- else if(gr->digital) {
- double xt = gr->x1 - 15 * gr->txtsizelab;
- double s1 = DIG_NWAVES; /* 1/DIG_NWAVES waveforms fit in graph if unscaled vertically */
- double s2 = DIG_SPACE; /* (DIG_NWAVES - DIG_SPACE) spacing between traces */
- double yt = s1 * (double)(n_nodes - wcnt) * gr->gh + gr->gh * 0.4 * s2;
- if(yt <= gr->ypos2 && yt >= gr->ypos1) {
- draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0,
- xt, DW_Y(yt) + gr->digtxtsizelab * 50, gr->digtxtsizelab * 0.8, gr->digtxtsizelab * 0.8);
+ if(!bus_msb && !gr->digital) {
+ draw_string(wave_color, NOW, tmpstr, 0, 0, 0, 0,
+ gr->rx1 + 2 + gr->rw / n_nodes * wcnt, gr->ry1 + gr->txtsizelab * 60,
+ gr->txtsizelab * 0.8, gr->txtsizelab * 0.8);
+ dbg(1, "node: %s, x=%g, value=%g\n", ntok, measure_x, yy);
}
- }
- bbox(END, 0.0, 0.0, 0.0, 0.0);
+ else if(gr->digital) {
+ double xt = gr->x1 - 15 * gr->txtsizelab;
+ double s1 = DIG_NWAVES; /* 1/DIG_NWAVES waveforms fit in graph if unscaled vertically */
+ double s2 = DIG_SPACE; /* (DIG_NWAVES - DIG_SPACE) spacing between traces */
+ double yt = s1 * (double)(n_nodes - wcnt) * gr->gh + gr->gh * 0.4 * s2;
+ if(yt <= gr->ypos2 && yt >= gr->ypos1) {
+ draw_string(wave_color, NOW, tmpstr, 2, 0, 0, 0,
+ xt, DW_Y(yt) + gr->digtxtsizelab * 50, gr->digtxtsizelab * 0.8, gr->digtxtsizelab * 0.8);
+ }
+ }
+ bbox(END, 0.0, 0.0, 0.0, 0.0);
+ } /* if(measure_p >= 0) */
}
int embed_rawfile(const char *rawfile)
@@ -3514,6 +3483,9 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
const char *ntok, *ctok, *stok;
char *bus_msb = NULL;
int wcnt = 0, idx, expression;
+ int *measure_p = NULL;
+ double *measure_x = NULL;
+ double *measure_prev_x = NULL;
char *express = NULL;
xRect *r = &xctx->rect[GRIDLAYER][i];
Raw *raw = NULL;
@@ -3535,6 +3507,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
/* draw stuff */
if(flags & 8) {
+ int k;
char *tmp_ptr = NULL;
int save_datasets = -1, save_npoints = -1;
#if !defined(__unix__) && HAS_CAIRO==1
@@ -3557,6 +3530,14 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
cptr = color;
sptr = sweep;
n_nodes = count_items(node, "\n\t ", "\"");
+ measure_p = my_malloc(_ALLOC_ID_, sizeof(int) * n_nodes);
+ measure_x = my_malloc(_ALLOC_ID_, sizeof(double) * n_nodes);
+ measure_prev_x = my_malloc(_ALLOC_ID_, sizeof(double) * n_nodes);
+ for(k = 0 ; k < n_nodes; k++) {
+ measure_p[k] = -1;
+ measure_x[k] = 0.0;
+ measure_prev_x[k] = 0.0;
+ }
/* process each node given in "node" attribute, get also associated color/sweep var if any*/
while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", 4, &saven)) ) {
@@ -3669,7 +3650,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
double start;
double end;
int n_bits = 1;
- int *idx_arr = NULL;
+ SPICE_DATA **idx_arr = NULL;
int sweepvar_wrap = 0; /* incremented on new dataset or sweep variable wrap */
XPoint *point = NULL;
int dataset = node_dataset >=0 ? node_dataset : gr->dataset;
@@ -3685,6 +3666,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
bbox(SET, 0.0, 0.0, 0.0, 0.0);
/* loop through all datasets found in raw file */
for(dset = 0 ; dset < raw->datasets; dset++) {
+ double prev_x;
int cnt=0, wrap;
register SPICE_DATA *gv = raw->values[sweep_idx];
@@ -3694,6 +3676,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
my_realloc(_ALLOC_ID_, &point, raw->npoints[dset] * sizeof(XPoint));
/* Process "npoints" simulation items
* p loop split repeated 2 timed (for x and y points) to preserve cache locality */
+ prev_x = 0;
last = ofs;
for(p = ofs ; p < ofs_end; p++) {
if(gr->logx) xx = mylog10(gv[p]);
@@ -3729,10 +3712,21 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
if(first == -1) first = p;
/* Build poly x array. Translate from graph coordinates to screen coords */
point[poly_npoints].x = (short)S_X(xx);
+ if(dataset == -1 || dataset == sweepvar_wrap) {
+ /* cursor1: show measurements on nodes in graph */
+ if(measure_p[wcnt] == -1 && flags & 2 && cnt) {
+ if(XSIGN(xx - xctx->graph_cursor1_x) != XSIGN(prev_x - xctx->graph_cursor1_x)) {
+ measure_p[wcnt] = p;
+ measure_x[wcnt] = xx;
+ measure_prev_x[wcnt] = prev_x;
+ }
+ } /* if(measure_p[wcnt] == -1 && flags & 2 && p > ofs) */
+ } /* if(dataset == -1 || dataset == sweepvar_wrap) */
last = p;
poly_npoints++;
++cnt;
} /* if(xx >= start && xx <= end) */
+ prev_x = xx;
} /* for(p = ofs ; p < ofs + raw->npoints[dset]; p++) */
if(first != -1) {
if(dataset == -1 || dataset == sweepvar_wrap) {
@@ -3755,7 +3749,10 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
sweepvar_wrap++;
} /* for(dset...) */
bbox(END, 0.0, 0.0, 0.0, 0.0);
- show_node_measures(bus_msb, wave_color, idx, idx_arr, n_bits, n_nodes, ntok_copy, wcnt, gr);
+ if(measure_p[wcnt] != -1)
+ show_node_measures(measure_p[wcnt], measure_x[wcnt], measure_prev_x[wcnt], bus_msb, wave_color,
+ idx, idx_arr, n_bits, n_nodes, ntok_copy, wcnt, gr);
+
my_free(_ALLOC_ID_, &point);
if(idx_arr) my_free(_ALLOC_ID_, &idx_arr);
} /* if( expression || (idx = get_raw_index(bus_msb ? bus_msb : express, NULL)) != -1 ) */
@@ -3780,18 +3777,23 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
my_free(_ALLOC_ID_, &node);
my_free(_ALLOC_ID_, &color);
my_free(_ALLOC_ID_, &sweep);
-
- bbox(START, 0.0, 0.0, 0.0, 0.0);
- bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
- bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
+ my_free(_ALLOC_ID_, &measure_p);
+ my_free(_ALLOC_ID_, &measure_x);
+ my_free(_ALLOC_ID_, &measure_prev_x);
+ } /* if(flags & 8) */
+ /*
+ * bbox(START, 0.0, 0.0, 0.0, 0.0);
+ * bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
+ * bbox(SET_INSIDE, 0.0, 0.0, 0.0, 0.0);
+ */
+ if(flags & 8) {
/* cursor1 */
- if((flags & 2)) draw_cursor(1, 1, i, gr);
+ if((flags & 2)) draw_cursor(xctx->graph_cursor1_x, xctx->graph_cursor2_x, 1, gr);
/* cursor2 */
- if((flags & 4)) draw_cursor(2, 3, i, gr);
+ if((flags & 4)) draw_cursor(xctx->graph_cursor2_x, xctx->graph_cursor1_x, 3, gr);
/* difference between cursors */
if((flags & 2) && (flags & 4)) draw_cursor_difference(gr);
- bbox(END, 0.0, 0.0, 0.0, 0.0);
- } /* if(flags & 8) */
+ }
if(flags & 1) { /* copy save buffer to screen */
if(!xctx->draw_window) {
/*
@@ -3803,6 +3805,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr, void *ct)
}
}
+ /* bbox(END, 0.0, 0.0, 0.0, 0.0); */
}
/* flags:
diff --git a/src/save.c b/src/save.c
index 00509d58..2c0a3c6f 100644
--- a/src/save.c
+++ b/src/save.c
@@ -672,7 +672,6 @@ static int read_dataset(FILE *fd, Raw **rawptr, const char *type)
/* get the list of lines with index and node name */
if(!raw->names) raw->names = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(char *));
if(!raw->cursor_b_val) raw->cursor_b_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
- if(!raw->cursor_a_val) raw->cursor_a_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
my_realloc(_ALLOC_ID_, &varname, strlen(line) + 1) ;
n = sscanf(line, "%d %s", &i, varname); /* read index and name of saved waveform */
if(n < 2) {
@@ -738,7 +737,6 @@ void free_rawfile(Raw **rawptr, int dr)
}
my_free(_ALLOC_ID_, &raw->names);
my_free(_ALLOC_ID_, &raw->cursor_b_val);
- my_free(_ALLOC_ID_, &raw->cursor_a_val);
}
if(raw->values) {
/* free also extra column for custom data plots */
@@ -845,9 +843,7 @@ int raw_add_vector(const char *varname, const char *expr)
raw->nvars++;
my_realloc(_ALLOC_ID_, &raw->names, raw->nvars * sizeof(char *));
my_realloc(_ALLOC_ID_, &raw->cursor_b_val, raw->nvars * sizeof(double));
- my_realloc(_ALLOC_ID_, &raw->cursor_a_val, raw->nvars * sizeof(double));
raw->cursor_b_val[raw->nvars - 1] = 0.0;
- raw->cursor_a_val[raw->nvars - 1] = 0.0;
raw->names[raw->nvars - 1] = NULL;
my_strdup2(_ALLOC_ID_, &raw->names[raw->nvars - 1], varname);
int_hash_lookup(&raw->table, raw->names[raw->nvars - 1], raw->nvars - 1, XINSERT_NOREPLACE);
@@ -1007,7 +1003,6 @@ int new_rawfile(const char *name, const char *type, const char *sweepvar,
raw->values[1] = my_calloc(_ALLOC_ID_, number, sizeof(SPICE_DATA));
raw->names = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(char *));
raw->cursor_b_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
- raw->cursor_a_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
my_strdup2(_ALLOC_ID_, &raw->names[0], sweepvar);
int_hash_lookup(&raw->table, raw->names[0], 0, XINSERT_NOREPLACE);
@@ -1393,7 +1388,6 @@ int table_read(const char *f)
dbg(0, "table_read(): no useful data found\n");
}
raw->cursor_b_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
- raw->cursor_a_val = my_calloc(_ALLOC_ID_, raw->nvars, sizeof(double));
fclose(fd);
return res;
}
diff --git a/src/scheduler.c b/src/scheduler.c
index add2f01f..d1e7a109 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -4704,7 +4704,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
- backannotate_at_cursor_pos(1, 0, gr);
+ backannotate_at_cursor_b_pos(r, gr);
}
}
}
@@ -4715,7 +4715,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Graph_ctx *gr = &xctx->graph_struct;
xRect *r = &xctx->rect[GRIDLAYER][0];
if(r->flags & 1) {
- backannotate_at_cursor_pos(2, 0, gr);
+ backannotate_at_cursor_b_pos(r, gr);
}
}
}
diff --git a/src/xschem.h b/src/xschem.h
index e9bc3d9b..49bdada7 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -790,7 +790,6 @@ typedef struct {
* need to interpolate the Y value between annot_p and annot_p + 1 */
int annot_sweep_idx; /* index of sweep variable where cursor annotation has occurred */
double *cursor_b_val;
- double *cursor_a_val;
/* when descending hierarchy xctx->current_name changes, xctx->raw_schname
* holds the name of the top schematic from which the raw file was loaded */
char *schname;
@@ -1383,7 +1382,7 @@ extern int select_dangling_nets(void);
extern int Tcl_AppInit(Tcl_Interp *interp);
extern void abort_operation(void);
extern void draw_crosshair(int del);
-extern void backannotate_at_cursor_pos(int cursor, int i, Graph_ctx *gr);
+extern void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr);
extern int callback(const char *winpath, int event, int mx, int my, KeySym key,
int button, int aux, int state);
extern void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h);
diff --git a/xschem_library/examples/LCC_instances.sch b/xschem_library/examples/LCC_instances.sch
index a810985e..9c840322 100644
--- a/xschem_library/examples/LCC_instances.sch
+++ b/xschem_library/examples/LCC_instances.sch
@@ -63,11 +63,11 @@ divy = 6
x1=0
x2=3
divx=6
-
-
-sweep="z a"
-color="4 8"
-node="a z"}
+node="z
+a"
+color="4 6"
+sweep="v(a) v(z)"
+}
P 4 5 560 -700 560 -510 1350 -510 1350 -700 560 -700 {dash=3}
P 4 5 820 -920 820 -730 1350 -730 1350 -920 820 -920 {dash=3}
P 4 5 0 -1160 1840 -1160 1840 0 -0 0 0 -1160 {dash=4}