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}