From 26bfe7691ba4d8709254e94557c0b2712cc7c97a Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 24 Jan 2025 18:57:35 +0100 Subject: [PATCH 1/3] add `xschem draw_hilight_net [on_window]` for quick draw or hilighted objects; add `xschem get_sim_sch` to get the current schematic hierarchy path, stripping off levels above the level the raw file was loaded. Strip off also leading dot; `xschem hilight_instname`: move fast option as -fast option; list_nets(): expand vector ports ; optimize update_op() for speed --- doc/xschem_man/developer_info.html | 8 +++-- src/callback.c | 1 + src/hilight.c | 3 +- src/node_hash.c | 20 ++++++++---- src/save.c | 8 ++--- src/scheduler.c | 52 ++++++++++++++++++++++++++---- src/xschem.tcl | 7 ++-- src/xschemrc | 10 ++++++ 8 files changed, 86 insertions(+), 23 deletions(-) diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index 54dfad7f..4cc88d12 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -687,6 +687,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Redraw graph rectangle number 'n'. If the optional 'flags' integer is given it will be used as the flags bitmask to use while drawing (can be used to restrict what to redraw) +
  • draw_hilight_net [1|0]
  • +   Redraw only hilight colors on nets and instances
    +   the parameter specifies if drawing on window or only on back buffer 
  • drc_check [i]
  •     Perform DRC rulecheck of instances.
        if i is specified do check of specified instance
    @@ -800,6 +803,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
          
  • schtedaxprop get schematic "tedax" global attributes
  • sch_path get hierarchy path. if 'n' given get hierpath of level 'n'
  • sch_to_compare if set return schematic current design is compared with
  • +
  • sim_sch_path get sim hier path. start from level where raw was loaded
  • symbols number of loaded symbols
  • temp_dir get windows temporary dir
  • text_svg return 1 if using <text> elements in svg export
  • @@ -899,9 +903,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" Highlight selected element/pins/labels/nets if 'drill' is given propagate net highlights through conducting elements (elements that have the 'propag' attribute on pins )
    -
  • hilight_instname inst [fast]
  • +   
  • hilight_instname [-fast] inst
  •     Highlight instance 'inst'
    -       if 'fast' is specified do not redraw
    +       if '-fast' is specified do not redraw
        'inst' can be an instance name or number 
  • hilight_netname [-fast] net
  •     Highlight net name 'net'
    diff --git a/src/callback.c b/src/callback.c
    index b10acd4f..0bdbe88e 100644
    --- a/src/callback.c
    +++ b/src/callback.c
    @@ -242,6 +242,7 @@ static double interpolate_yval(int idx, int p, double x, int sweep_idx, int poin
     
     void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr)
     {
    +  tcleval("catch {eval $cursor_2_hook}");
       if(sch_waves_loaded() >= 0) { 
         int dset, first = -1, last, dataset = gr->dataset, i, p, ofs = 0, ofs_end;
         double start, end;
    diff --git a/src/hilight.c b/src/hilight.c
    index 8f2406fb..19c18a34 100644
    --- a/src/hilight.c
    +++ b/src/hilight.c
    @@ -1104,6 +1104,7 @@ static void drill_hilight(int mode)
       if(propagate_str) my_free(_ALLOC_ID_, &propagate_str);
     }
     
    +/* if fast is set you need to do a propagate_hilights() at the end to finalize the operation */
     int hilight_netname(const char *name, int fast)
     {
       Node_hashentry *node_entry;
    @@ -1113,8 +1114,8 @@ int hilight_netname(const char *name, int fast)
       node_entry = bus_node_hash_lookup(name, "", XLOOKUP, 0, "", "", "", "");
                         /* sets xctx->hilight_nets=1 */
       if(node_entry && !bus_hilight_hash_lookup(name, xctx->hilight_color, XINSERT_NOREPLACE)) {
    -    propagate_hilights(1, 0, XINSERT_NOREPLACE);
         if(!fast) {
    +      propagate_hilights(1, 0, XINSERT_NOREPLACE);
           if(tclgetboolvar("incr_hilight")) incr_hilight_color();
           redraw_hilights(0);
         }
    diff --git a/src/node_hash.c b/src/node_hash.c
    index b7939e5e..4b44d98f 100644
    --- a/src/node_hash.c
    +++ b/src/node_hash.c
    @@ -368,24 +368,30 @@ void print_verilog_signals(FILE *fd)
     void list_nets(char **result)
     {
       Node_hashentry *ptr;
    -  char *type = NULL;
       int i;
       int netlist_lvs_ignore=tclgetboolvar("lvs_ignore");
    +  char *type = NULL;
    +  int mult, k;
    +  char *pin_node = NULL;
    +  char *p_n_s1, *p_n_s2, *lab;
     
       prepare_netlist_structs(1);
       for(i = 0; i < xctx->instances; i++) {
         if(skip_instance(i, 0, netlist_lvs_ignore)) continue;
         my_strdup(_ALLOC_ID_, &type,(xctx->inst[i].ptr+ xctx->sym)->type);
         if(type && xctx->inst[i].node && IS_PIN(type)) {
    -      /* 
    -       * my_mstrcat(_ALLOC_ID_, result, 
    -       *  "{", get_tok_value(xctx->inst[i].prop_ptr, "lab", 0), " ", type, "}\n", NULL);
    -       */
    -      my_mstrcat(_ALLOC_ID_, result, 
    -        "{", xctx->inst[i].lab, " ", type, "}\n", NULL);
    +      my_strdup2(_ALLOC_ID_, &pin_node, expandlabel(xctx->inst[i].lab, &mult));
    +      p_n_s1 = pin_node;
    +      for(k = 1; k <= mult; ++k) {
    +        lab = my_strtok_r(p_n_s1, ",", "", 0, &p_n_s2);
    +        p_n_s1 = NULL;
    +        my_mstrcat(_ALLOC_ID_, result, "{", lab, " ", type, "}\n", NULL);
    +      }
         }
    +    if(pin_node) my_free(_ALLOC_ID_, &pin_node);
       }
       if(type) my_free(_ALLOC_ID_, &type);
    +
       for(i=0;inode_table[i];
         while(ptr) {
    diff --git a/src/save.c b/src/save.c
    index 4c4c4991..8dad1292 100644
    --- a/src/save.c
    +++ b/src/save.c
    @@ -1388,7 +1388,7 @@ int extra_rawfile(int what, const char *file, const char *type, double sweep1, d
     int update_op()
     {
       int res = 0, p = 0, i;
    -  tcleval("array unset ngspice::ngspice_data");
    +  Tcl_UnsetVar(interp, "ngspice::ngspice_data", TCL_GLOBAL_ONLY);
       if(xctx->raw && xctx->raw->values) {
         xctx->raw->annot_p = 0;
         dbg(1, "update_op(): nvars=%d\n", xctx->raw->nvars);
    @@ -1398,10 +1398,10 @@ int update_op()
           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);
    +      Tcl_SetVar2(interp, "ngspice::ngspice_data", xctx->raw->names[i], s, TCL_GLOBAL_ONLY);
         }
    -    tclvareval("set ngspice::ngspice_data(n\\ vars) ", my_itoa( xctx->raw->nvars), NULL);
    -    tclvareval("set ngspice::ngspice_data(n\\ points) 1", NULL);
    +    Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ vars", my_itoa( xctx->raw->nvars), TCL_GLOBAL_ONLY);
    +    Tcl_SetVar2(interp, "ngspice::ngspice_data", "n\\ points", "1", TCL_GLOBAL_ONLY);
       } 
       return res;
     }
    diff --git a/src/scheduler.c b/src/scheduler.c
    index 2bba379e..f4534fa7 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -899,6 +899,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           }
           Tcl_ResetResult(interp);
         }
    +
    +    /* draw_hilight_net [1|0]
    +     *   Redraw only hilight colors on nets and instances
    +     *   the parameter specifies if drawing on window or only on back buffer */
    +    else if(!strcmp(argv[1], "draw_hilight_net")) {
    +      int on_window = 1;
    +      if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
    +      if(argc > 2) {
    +        on_window = atoi(argv[2]);
    +      }
    +      draw_hilight_net(on_window);
    +      Tcl_ResetResult(interp);
    +    }
    +
         /* drc_check [i]
          *   Perform DRC rulecheck of instances.
          *   if i is specified do check of specified instance
    @@ -1619,6 +1633,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
                 if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
                 Tcl_SetResult(interp, xctx->sch_to_compare, TCL_VOLATILE);
               }
    +          else if(!strcmp(argv[2], "sim_sch_path")) /* get sim hier path. start from level where raw was loaded */
    +          {
    +            int x = xctx->currsch;
    +            char *path = xctx->sch_path[x] + 1;
    +            int skip = 0;
    +            int start_level;
    +            if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
    +            start_level = sch_waves_loaded();
    +            /* skip path components that are above the level where raw file was loaded */
    +            while(*path && skip < start_level) {
    +              if(*path == '.') skip++;
    +              ++path;
    +            }
    +            Tcl_SetResult(interp, path, TCL_VOLATILE);
    +          }
               else if(!strcmp(argv[2], "symbols")) { /* number of loaded symbols */
                 if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
                 Tcl_SetResult(interp, my_itoa(xctx->symbols), TCL_VOLATILE);
    @@ -2202,23 +2231,34 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           redraw_hilights(0);
           Tcl_ResetResult(interp);
         }
    -    /* hilight_instname inst [fast]
    +    /* hilight_instname [-fast] inst
          *   Highlight instance 'inst'
    -     * if 'fast' is specified do not redraw
    +     * if '-fast' is specified do not redraw
          *   'inst' can be an instance name or number */
         else if(!strcmp(argv[1], "hilight_instname"))
         {
    +      const char *instname=NULL;
    +      int i, fast = 0;
    +      
           if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
    -      if(argc > 2) {
    +      for(i = 2; i < argc; i++) {
    +        if(argv[i][0] == '-') {
    +          if(!strcmp(argv[i], "-fast")) {
    +            fast = 1;
    +          }
    +        } else { 
    +          instname = argv[i];
    +          break;
    +        }
    +      } 
    +      if(instname) {
             int inst;
             char *type;
             int incr_hi;
    -        int fast = 0;
    -        if(argc > 3 && !strcmp(argv[3], "fast")) fast = 1;
             xctx->enable_drill=0;
             incr_hi = tclgetboolvar("incr_hilight");
             prepare_netlist_structs(0);
    -        if((inst = get_instance(argv[2])) < 0 ) {
    +        if((inst = get_instance(instname)) < 0 ) {
               Tcl_SetResult(interp, "xschem hilight_instname: instance not found", TCL_STATIC);
               return TCL_ERROR;
             } else {
    diff --git a/src/xschem.tcl b/src/xschem.tcl
    index d0c70af9..1321e560 100644
    --- a/src/xschem.tcl
    +++ b/src/xschem.tcl
    @@ -7656,9 +7656,9 @@ set tctx::global_list {
       add_all_windows_drives auto_hilight auto_hilight_graph_nodes autofocus_mainwindow
       autotrim_wires bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
       cadsnap cairo_font_name cairo_font_scale change_lw color_ps tctx::colors compare_sch constr_mv
    -  copy_cell crosshair_layer crosshair_size custom_label_prefix custom_token dark_colors dark_colorscheme
    -  dark_gui_colorscheme delay_flag  dim_bg dim_value disable_unique_names
    -  do_all_inst draw_crosshair
    +  copy_cell crosshair_layer crosshair_size cursor_2_hook custom_label_prefix custom_token
    +  dark_colors dark_colorscheme dark_gui_colorscheme delay_flag
    +  dim_bg dim_value disable_unique_names do_all_inst draw_crosshair
       draw_grid draw_grid_axes draw_window edit_prop_pos edit_prop_size
       edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch
       enter_text_default_geometry filetmp fix_broken_tiled_fill flat_netlist fullscreen
    @@ -9107,6 +9107,7 @@ set_ne zoom_full_center 0
     set_ne change_lw 1
     set_ne line_width 0
     set_ne live_cursor2_backannotate 1
    +set_ne cursor_2_hook {}
     set_ne draw_window 0
     set_ne show_hidden_texts 0
     set_ne incr_hilight 1
    diff --git a/src/xschemrc b/src/xschemrc
    index 70513e40..159c300a 100644
    --- a/src/xschemrc
    +++ b/src/xschemrc
    @@ -582,6 +582,16 @@
     #### default: not enabled (0)
     # set hide_empty_graphs 0
     
    +
    +###########################################################################
    +#### ATTACH HOOK FUNCTION TO CURSOR 2 MOVEMENT 
    +###########################################################################
    +#### if enabled whenever the cursor2 is moved the specified script is
    +#### executed. Examples:
    +####  set cursor_2_hook {conducting_devices 10e-3 nodraw}
    +####  set cursor_2_hook {hilight_high_nets 0 1.8 nodraw}
    +#### this can be used to add backannotation actions.
    +
     ###########################################################################
     #### LIVE BACKANNOTATION OF DATA AT CURSOR 2 (B) POSITION
     ###########################################################################
    
    From 4700483fa4d2cda49d8b3ebfd9729bd16ef51324 Mon Sep 17 00:00:00 2001
    From: stefan schippers 
    Date: Sat, 25 Jan 2025 02:13:59 +0100
    Subject: [PATCH 2/3] draw_crosshair(): more logical what parameter values
    
    ---
     src/callback.c | 10 +++++-----
     src/draw.c     |  2 +-
     src/move.c     |  4 ++--
     3 files changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/src/callback.c b/src/callback.c
    index 0bdbe88e..deccfbfb 100644
    --- a/src/callback.c
    +++ b/src/callback.c
    @@ -1335,7 +1335,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
       return 0;
     }
     
    -/* what == 0 : delete and draw
    +/* what == 3 : delete and draw
      * what == 1 : delete
      * what == 2 : draw */
     void draw_crosshair(int what)
    @@ -1350,7 +1350,7 @@ void draw_crosshair(int what)
     
       xctx->draw_pixmap = 0;
       xctx->draw_window = 1;
    -  if(what != 2) { /* delete previous */
    +  if(what & 1) { /* delete previous */
         if(fix_broken_tiled_fill || !_unix) {
           if(xhair_size) {
             MyXCopyArea(display, xctx->save_pixmap, xctx->window, xctx->gc[0],
    @@ -1408,7 +1408,7 @@ void draw_crosshair(int what)
           }
         }
       }
    -  if(what != 1) { /* draw new */
    +  if(what & 2) { /* draw new */
         if(xhair_size) {
           draw_xhair_line(xctx->gc[xctx->crosshair_layer], xhair_size,
               X_TO_SCREEN(xctx->mousex_snap) - xhair_size,
    @@ -1439,7 +1439,7 @@ void draw_crosshair(int what)
              X_TO_SCREEN(xctx->mousex_snap), xctx->areay2);
         }
       }
    -  draw_selection(xctx->gc[SELLAYER], 0);
    +  if(what) draw_selection(xctx->gc[SELLAYER], 0);
       xctx->prev_crossx = xctx->mousex_snap;
       xctx->prev_crossy = xctx->mousey_snap;
     
    @@ -4302,7 +4302,7 @@ int rstate; /* (reduced state, without ShiftMask) */
          break;
        }
     
    -   if(draw_xhair) draw_crosshair(0);
    +   if(draw_xhair) draw_crosshair(3);
        break;
       case -3:  /* double click  : edit prop */
         if( waves_selected(event, key, state, button)) {
    diff --git a/src/draw.c b/src/draw.c
    index f2041244..b92f9312 100644
    --- a/src/draw.c
    +++ b/src/draw.c
    @@ -5137,7 +5137,7 @@ void draw(void)
         } else {
           draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */
         }
    -    if(tclgetboolvar("draw_crosshair")) draw_crosshair(0);
    +    if(tclgetboolvar("draw_crosshair")) draw_crosshair(3);
       } /* if(has_x) */
     }
     
    diff --git a/src/move.c b/src/move.c
    index ee5c6ff6..317ab661 100644
    --- a/src/move.c
    +++ b/src/move.c
    @@ -907,7 +907,7 @@ void copy_objects(int what)
         xctx->rotatelocal=0;
       } /* if(what & END) */
       draw_selection(xctx->gc[SELLAYER], 0);
    -  if(tclgetboolvar("draw_crosshair")) draw_crosshair(0);
    +  if(tclgetboolvar("draw_crosshair")) draw_crosshair(3);
     }
     
     
    @@ -1361,5 +1361,5 @@ void move_objects(int what, int merge, double dx, double dy)
        xctx->rotatelocal=0;
       } /* what & end */
       draw_selection(xctx->gc[SELLAYER], 0);
    -  if(tclgetboolvar("draw_crosshair")) draw_crosshair(0);
    +  if(tclgetboolvar("draw_crosshair")) draw_crosshair(3);
     }
    
    From 71aa4339bdbc2ebfc0b878b8bd25ed462e1c5512 Mon Sep 17 00:00:00 2001
    From: stefan schippers 
    Date: Sat, 25 Jan 2025 02:46:54 +0100
    Subject: [PATCH 3/3] add comment
    
    ---
     src/callback.c | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/src/callback.c b/src/callback.c
    index deccfbfb..66a14b98 100644
    --- a/src/callback.c
    +++ b/src/callback.c
    @@ -4301,8 +4301,7 @@ int rstate; /* (reduced state, without ShiftMask) */
          xctx->ui_state &= ~MENUSTART;
          break;
        }
    -
    -   if(draw_xhair) draw_crosshair(3);
    +   if(draw_xhair) draw_crosshair(3); /* restore crosshair when selecting / unselecting */
        break;
       case -3:  /* double click  : edit prop */
         if( waves_selected(event, key, state, button)) {