From d03f3b52e112dc6dc84342c5310c8320ca189b8e Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 19 Dec 2024 23:53:11 +0100 Subject: [PATCH] bars for hystograms use squared lines, not rounded lines, added command `xschem raw pos_at node value` to find position (in raw file) where node = value --- doc/xschem_man/developer_info.html | 10 ++++++- src/draw.c | 29 ++++++++++++------- src/save.c | 36 ++++++++++++++++++++++++ src/scheduler.c | 28 +++++++++++++++++- src/xschem.h | 1 + xschem_library/examples/cmos_example.sch | 18 ++++++------ 6 files changed, 101 insertions(+), 21 deletions(-) diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index d988da0f..ee0ddf30 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -1165,7 +1165,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Push current state on undo stack
  • raw what ...
  •       what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
    -            read | set | sim_type | switch | switch_back | table_read | value | values | vars |
    +            read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
           
        xschem raw read filename [type [sweep1 sweep2]]
          if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
    @@ -1229,6 +1229,13 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
          print all simulation values of 'node' for dataset 'dset' (default dset=0)
          dset= -1: print all values for all datasets
           
    +   xschem raw pos_at node value [dset] [from_start] [to_end]
    +     returns the position, starting from 0 or from_start if given, to the end of dataset
    +     or to_end if given of the first point 'p' where node[p] and node[p+1] bracket value.
    +     If dset not given assume dset 0 (first one)
    +     This is usually done on the sweep (time) variable in transient sims where timestep is
    +     not uniform
    +      
        xschem raw points [dset]
          print simulation points for dataset 'dset' (default: all dataset points combined)
           
    @@ -1672,6 +1679,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
     
     
     
    +
     
     
      
    diff --git a/src/draw.c b/src/draw.c
    index f373d54e..1a9fc28a 100644
    --- a/src/draw.c
    +++ b/src/draw.c
    @@ -2271,15 +2271,20 @@ static SPICE_DATA **get_bus_idx_array(const char *ntok, int *n_bits)
      */
     static void set_thick_waves(int what, int wcnt, int wave_col, Graph_ctx *gr)
     {
    +  unsigned long valuemask;
    +  XGCValues values;
    +  valuemask = GCLineWidth;
       dbg(1, "set_thick_waves(): what=%d\n", what);
       if(what) {
    -      if(gr->hilight_wave == wcnt)
    -         XSetLineAttributes (display, xctx->gc[wave_col],
    -            XLINEWIDTH(2.4 * gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
    +      if(gr->hilight_wave == wcnt) {
    +         values.line_width = XLINEWIDTH(2.4 * gr->linewidth_mult * xctx->lw);
    +         XChangeGC(display, xctx->gc[wave_col], valuemask, &values);
    +      }
       } else {
    -      if(gr->hilight_wave == wcnt)
    -         XSetLineAttributes (display, xctx->gc[wave_col],
    -            XLINEWIDTH(gr->linewidth_mult * xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
    +      if(gr->hilight_wave == wcnt) {
    +         values.line_width = XLINEWIDTH(gr->linewidth_mult * xctx->lw);
    +         XChangeGC(display, xctx->gc[wave_col], valuemask, &values);
    +      }
       }
     }
     
    @@ -2610,9 +2615,8 @@ static void draw_graph_bus_points(const char *ntok, int n_bits, SPICE_DATA **idx
       }
       for(p=0;pgc[p], 
    -       XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
    +       XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP, LINEJOIN);
       }
    -
       if(gr->logx) {
         lx1 = W_X(mylog10(raw->values[sweep_idx][first]));
         lx2 = W_X(mylog10(raw->values[sweep_idx][last]));
    @@ -2689,8 +2693,13 @@ static void draw_graph_points(int idx, int first, int last,
       dbg(1, "draw_graph_points: idx=%d, first=%d, last=%d, wcnt=%d\n", idx, first, last, wcnt);
       if(idx == -1) return;
       for(p=0;pgc[p],
    -      XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
    +    if(gr->mode == 1 || gr->mode == 2) { /* Histograms */
    +      XSetLineAttributes(display, xctx->gc[p],
    +         XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, xCap , xJoin);
    +    } else {
    +      XSetLineAttributes(display, xctx->gc[p],
    +         XLINEWIDTH(gr->linewidth_mult * xctx->lw), LineSolid, LINECAP , LINEJOIN);
    +    }
       }
       digital = gr->digital;
       if(digital) {
    diff --git a/src/save.c b/src/save.c
    index 02b0b32f..4b711b96 100644
    --- a/src/save.c
    +++ b/src/save.c
    @@ -1538,6 +1538,42 @@ int table_read(const char *f)
       return 0;
     }
     
    +int raw_get_pos(const char *node, double value, int dset, int from_start, int to_end)
    +{
    +  int x = -1;
    +  Raw *raw = xctx->raw;
    +  int idx = -1;
    +
    +  if(sch_waves_loaded() >= 0) {
    +    if(dset >= raw->datasets) dset = raw->datasets - 1;
    +    if(dset < 0) dset = 0;
    +    idx = get_raw_index(node, NULL);
    +    if(idx >= 0) {
    +      double vx;
    +      int start, end;
    +
    +      start = from_start >= 0 ? from_start : 0;
    +      end = to_end >= 0 ? to_end : raw->npoints[dset] - 1;
    +      double vstart = get_raw_value(dset, idx, start);
    +      double vend = get_raw_value(dset, idx, end);
    +      int sign = (vend > vstart) ? 1 : -1;
    +      dbg(0, "%d %d\n", start, end);
    +
    +      if(start >= end) start = end;
    +      if( sign * value >= sign * vstart && sign * value <= sign * vend) {
    +        while(1) {
    +          x = (start + end ) / 2;
    +          vx = get_raw_value(dset, idx, x);
    +          if(end - start <= 1) break;
    +          if( sign * vx > sign * value) end = x;
    +          else start = x;
    +        }
    +      }
    +    }
    +  }
    +
    +  return x;
    +}
     /* given a node XXyy try XXyy , xxyy, XXYY, v(XXyy), v(xxyy), V(XXYY) */
     int get_raw_index(const char *node, Int_hashentry **entry_ret)
     {
    diff --git a/src/scheduler.c b/src/scheduler.c
    index e74b0edc..e2d286c8 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -3791,7 +3791,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
     
         /* raw what ...
          *     what = add | clear | datasets | index | info | loaded | list | new | points | rawfile | del |
    -     *            read | set | sim_type | switch | switch_back | table_read | value | values | vars |
    +     *            read | set | sim_type | switch | switch_back | table_read | value | values | pos_at | vars |
          *
          *   xschem raw read filename [type [sweep1 sweep2]]
          *     if sweep1, sweep2 interval is given in 'read' subcommand load only the interval
    @@ -3855,6 +3855,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
          *     print all simulation values of 'node' for dataset 'dset' (default dset=0)
          *     dset= -1: print all values for all datasets
          *
    +     *   xschem raw pos_at node value [dset] [from_start] [to_end]
    +     *     returns the position, starting from 0 or from_start if given, to the end of dataset
    +     *     or to_end if given of the first point 'p' where node[p] and node[p+1] bracket value.
    +     *     If dset not given assume dset 0 (first one)
    +     *     This is usually done on the sweep (time) variable in transient sims where timestep is
    +     *     not uniform
    +     *
          *   xschem raw points [dset]
          *     print simulation points for dataset 'dset' (default: all dataset points combined)
          *
    @@ -3994,6 +4001,25 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                   Tcl_AppendResult(interp, n, " ", NULL);
                 }
               }
    +        } else if(argc > 4 && !strcmp(argv[2], "pos_at")) {
    +          /* xschem raw pos_at node value [dset] [from_start] [to_end] */
    +          int dset = 0;
    +          int from_start = -1;
    +          int to_end = -1;
    +          int pos = -1;
    +          double value = 0.0;
    +          if(argc > 5) {
    +            dset = atoi(argv[5]);
    +          }
    +          if(argc > 6) {
    +            from_start = atoi(argv[6]);
    +          }
    +          if(argc > 7) {
    +            to_end = atoi(argv[7]);
    +          }
    +          value = atof_spice(argv[4]);
    +          pos = raw_get_pos(argv[3], value, dset, from_start, to_end);
    +          Tcl_SetResult(interp, my_itoa(pos), TCL_VOLATILE);
             } else if(argc > 3 && !strcmp(argv[2], "add")) {
               int res = 0;
               int sweep_idx = 0;
    diff --git a/src/xschem.h b/src/xschem.h
    index df46aeee..3f59ee9b 100644
    --- a/src/xschem.h
    +++ b/src/xschem.h
    @@ -1267,6 +1267,7 @@ extern int set_rect_extraptr(int what, xRect *drptr);
     extern unsigned char *base64_decode(const char *data, const size_t input_length, size_t *output_length);
     extern char *base64_encode(const unsigned char *data, const size_t input_length, size_t *output_length, int brk);
     extern unsigned char *ascii85_encode(const unsigned char *data, const size_t input_length, size_t *output_length);
    +extern int raw_get_pos(const char *node, double value, int dset, int from_start, int to_end);
     extern int  get_raw_index(const char *node, Int_hashentry **entry_ret);
     extern void free_rawfile(Raw **rawptr, int dr);
     extern int update_op();
    diff --git a/xschem_library/examples/cmos_example.sch b/xschem_library/examples/cmos_example.sch
    index 10360840..be0657d9 100644
    --- a/xschem_library/examples/cmos_example.sch
    +++ b/xschem_library/examples/cmos_example.sch
    @@ -1,4 +1,4 @@
    -v {xschem version=3.4.6RC file_version=1.2
    +v {xschem version=3.4.6 file_version=1.2
     *
     * This file is part of XSCHEM,
     * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
    @@ -31,8 +31,8 @@ y1=-160
     y2=0
     divy=4
     subdivy=1
    -x1=2.3
    -x2=2.7
    +x1=2.4
    +x2=2.6
     divx=6
     subdivx=1
     node="\\"GAIN @ 2uA;diffout deriv() % 0\\"
    @@ -57,8 +57,8 @@ y1=0.875402
     y2=5.6754
     divy=4
     subdivy=1
    -x1=2.3
    -x2=2.7
    +x1=2.4
    +x2=2.6
     divx=6
     subdivx=1
     node="diffout@2uA;v(diffout)%0
    @@ -144,8 +144,8 @@ y1=2.3
     y2=2.7
     divy=4
     subdivy=1
    -x1=2.3088075
    -x2=2.7088075
    +x1=2.4
    +x2=2.6
     divx=6
     subdivx=1
     node="minus;minus%0
    @@ -344,7 +344,7 @@ value=".temp 30
       settype power power
       write cmos_example_ngspice.raw
       set appendwrite
    -  dc vminus 2.3 2.7 0.001
    +  dc vminus 2.4 2.6 0.001
       write cmos_example_ngspice.raw
       tran 0.5n 5u
       write cmos_example_ngspice.raw
    @@ -366,7 +366,7 @@ value=".temp 30
       alterparam IB=100u
       reset
       save all
    -  dc vminus 2.3 2.7 0.001
    +  dc vminus 2.4 2.6 0.001
       write cmos_example_ngspice.raw
       tran 0.5n 5u
       write cmos_example_ngspice.raw