From d776d6a35121cf719578ca2fa0fb87437b9f4d2f Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Sun, 29 Oct 2023 14:04:52 +0100 Subject: [PATCH] better handle operating point clear / update when switching / reading / clearing raw files. dont use operating point data (ngspice::ngspice) above the hierarchy level where raw file has been loaded. --- doc/xschem_man/developer_info.html | 6 ++++- src/save.c | 25 ++++++++++++++++++- src/scheduler.c | 39 +++++++++++++++--------------- src/xschem.h | 1 + src/xschem.tcl | 4 +++ 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index aefaa1aa..16dc7648 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -519,6 +519,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" +
  • abort_operation
  • @@ -677,6 +678,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
          
  • draw_window direct draw into window
  • first_sel get data about first selected object
  • fix_broken_tiled_fill get drawing method setting (for broken GPUs)
  • +
  • fix_mouse_coord get fix_mouse_coord setting (fix for broken RDP)
  • format alternate format attribute to use in netlist (or NULL)
  • graph_lastsel number of last graph that was clicked
  • gridlayer layer number for grid
  • @@ -1182,6 +1184,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
  • constrained_move set constrained move (1=horiz, 2=vert, 0=none)
  • draw_window set drawing to window (1 or 0)
  • fix_broken_tiled_fill alternate drawing method for broken GPUs
  • +
  • fix_mouse_coord fix for wrong mouse coords in RDP software
  • format set name of custom format attribute used for netlisting
  • header_text set header metadata (used for license info)
  • hide_symbols set to 0,1,2 for various hiding level of symbols
  • @@ -1323,6 +1326,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Unselect everything. If draw is given and set to '0' no drawing is done
  • update_all_sym_bboxes
  •     Update all symbol bounding boxes (useful if show_pin_net_names is set) 
    +
  • update_op
  • +   update tcl ngspice::ngspice array data from raw file point 0 
  • view_prop
  •     View attributes of selected element (read only)
        if multiple selection show the first element (in xschem  array order) 
    @@ -1393,7 +1398,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" - diff --git a/src/save.c b/src/save.c index cc538486..cc687244 100644 --- a/src/save.c +++ b/src/save.c @@ -818,7 +818,7 @@ int raw_read(const char *f, Raw **rawptr, const char *type) /* what == 1: read another raw file and switch to it (make it the current one) * what == 2: switch raw file. If filename given switch to that one, else switch to next - * what == 3: remove a raw file. If no filename given remove all, keep current in xctx->raw + * what == 3: remove a raw file. If no filename given remove all * what == 4: print info * what == 5: switch back to previous * return 1 if sucessfull, 0 otherwise @@ -910,6 +910,7 @@ int extra_rawfile(int what, const char *file, const char *type) for(i = 0; i < xctx->extra_raw_n; i++) { free_rawfile(&xctx->extra_raw_arr[i], 0); } + tcleval("array unset ngspice::ngspice_data"); xctx->raw = NULL; xctx->extra_prev_idx = 0; xctx->extra_idx = 0; @@ -936,6 +937,7 @@ int extra_rawfile(int what, const char *file, const char *type) if(xctx->extra_raw_n) { xctx->raw = xctx->extra_raw_arr[0]; } else { + tcleval("array unset ngspice::ngspice_data"); xctx->raw = NULL; } } else ret = 0; @@ -957,6 +959,27 @@ int extra_rawfile(int what, const char *file, const char *type) return ret; } +int update_op() +{ + int res = 0, p = 0, i; + tcleval("array unset ngspice::ngspice_data"); + if(xctx->raw && xctx->raw->values) { + tclsetvar("rawfile_loaded", "1"); + xctx->raw->annot_p = 0; + for(i = 0; i < xctx->raw->nvars; ++i) { + char s[100]; + res = 1; + xctx->raw->cursor_b_val[i] = xctx->raw->values[i][p]; + my_snprintf(s, S(s), "%.4g", xctx->raw->values[i][p]); + dbg(1, "%s = %g\n", xctx->raw->names[i], xctx->raw->values[i][p]); + tclvareval("array set ngspice::ngspice_data [list {", xctx->raw->names[i], "} ", s, "]", NULL); + } + tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->raw->nvars), NULL); + tclvareval("set ngspice::ngspice_data(n\\ points) 1", NULL); + } + return res; +} + /* Read data organized as a table * First line is the header line containing variable names. * data is presented in column format after the header line diff --git a/src/scheduler.c b/src/scheduler.c index 21d53dd5..a6755adc 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -260,7 +260,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg * into schematic */ else if(!strcmp(argv[1], "annotate_op")) { - int i; char f[PATH_MAX + 100]; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(argc > 2) { @@ -274,23 +273,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg tclsetvar("rawfile_loaded", "0"); extra_rawfile(3, NULL, NULL); free_rawfile(&xctx->raw, 1); - tcleval("array unset ngspice::ngspice_data"); raw_read(f, &xctx->raw, "op"); - if(xctx->raw && xctx->raw->values) { - tclsetvar("rawfile_loaded", "1"); - xctx->raw->annot_p = 0; - for(i = 0; i < xctx->raw->nvars; ++i) { - char s[100]; - int p = 0; - xctx->raw->cursor_b_val[i] = xctx->raw->values[i][p]; - my_snprintf(s, S(s), "%.4g", xctx->raw->values[i][p]); - dbg(1, "%s = %g\n", xctx->raw->names[i], xctx->raw->values[i][p]); - tclvareval("array set ngspice::ngspice_data [list {", xctx->raw->names[i], "} ", s, "]", NULL); - } - tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->raw->nvars), NULL); - tclvareval("set ngspice::ngspice_data(n\\ points) 1", NULL); - draw(); - } + update_op(); + draw(); } /* arc @@ -3102,15 +3087,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } else { ret = extra_rawfile(2, NULL, NULL); } + update_op(); Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); } else if(argc > 2 && !strcmp(argv[2], "info")) { ret = extra_rawfile(4, NULL, NULL); } else if(argc > 2 && !strcmp(argv[2], "switch_back")) { ret = extra_rawfile(5, NULL, NULL); + update_op(); Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); } else if(argc > 2 && !strcmp(argv[2], "clear")) { - if(argc > 3) ret = extra_rawfile(3, argv[3], NULL); - else ret = extra_rawfile(3, NULL, NULL); + if(argc > 3) { + ret = extra_rawfile(3, argv[3], NULL); + } else { + ret = extra_rawfile(3, NULL, NULL); + } Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); } else { err = 1; @@ -3232,6 +3222,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg int res = 0; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(sch_waves_loaded() >= 0) { + tcleval("array unset ngspice::ngspice_data"); extra_rawfile(3, NULL, NULL); free_rawfile(&xctx->raw, 1); tclsetvar("rawfile_loaded", "0"); @@ -4825,6 +4816,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_ResetResult(interp); } + /* update_op + * update tcl ngspice::ngspice array data from raw file point 0 */ + else if(!strcmp(argv[1], "update_op")) + { + int ret; + if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} + ret = update_op(); + Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); + } + else { cmd_found = 0;} break; case 'v': /*----------------------------------------------*/ diff --git a/src/xschem.h b/src/xschem.h index 14753b66..24441a04 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1210,6 +1210,7 @@ extern char *base64_encode(const unsigned char *data, const size_t input_length, extern unsigned char *ascii85_encode(const unsigned char *data, const size_t input_length, size_t *output_length); extern int get_raw_index(const char *node); extern void free_rawfile(Raw **rawptr, int dr); +extern int update_op(); extern int extra_rawfile(int what, const char *f, const char *type); extern int raw_read(const char *f, Raw **rawptr, const char *type); extern int table_read(const char *f); diff --git a/src/xschem.tcl b/src/xschem.tcl index d6437bab..9d2027fd 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -915,6 +915,7 @@ proc ngspice::get_current {n} { set path [string range [xschem get sch_path] 1 end] # skip hierarchy components above the level where raw file has been loaded. # node path names to look up in raw file begin from there. + if { [xschem get currsch] < $raw_level} { return {}} set skip 0 while { $skip < $raw_level } { regsub {^[^.]*\.} $path {} path @@ -957,6 +958,7 @@ proc ngspice::get_current {n} { proc ngspice::get_diff_voltage {n m} { set raw_level [xschem get raw_level] set path [string range [xschem get sch_path] 1 end] + if { [xschem get currsch] < $raw_level} { return {}} # skip hierarchy components above the level where raw file has been loaded. # node path names to look up in raw file begin from there. set skip 0 @@ -988,6 +990,7 @@ proc ngspice::get_diff_voltage {n m} { proc ngspice::get_voltage {n} { set raw_level [xschem get raw_level] set path [string range [xschem get sch_path] 1 end] + if { [xschem get currsch] < $raw_level} { return {}} # skip hierarchy components above the level where raw file has been loaded. # node path names to look up in raw file begin from there. set skip 0 @@ -1023,6 +1026,7 @@ proc update_schematic_header {} { proc ngspice::get_node {n} { set raw_level [xschem get raw_level] set path [string range [xschem get sch_path] 1 end] + if { [xschem get currsch] < $raw_level} { return {}} # skip hierarchy components above the level where raw file has been loaded. # node path names to look up in raw file begin from there. set skip 0