diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index a8605e52..fe9a2a71 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -496,6 +496,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" + + + @@ -1078,6 +1081,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" if 'clear' is specified does an unselect operation
  • select_all
  •     Selects all objects in schematic 
    +
  • select_dangling_nets
  • +   Select all nets/labels that are dangling, ie not attached to any non pin/port/probe components
    +   Returns 1 if danglings found, 0 otherwise 
  • select_hilight_net
  •     Select all highlight objects (wires, labels, pins, instances) 
  • selected_set
  • diff --git a/src/scheduler.c b/src/scheduler.c
    index b8eed6df..6e5a0a8d 100644
    --- a/src/scheduler.c
    +++ b/src/scheduler.c
    @@ -1768,8 +1768,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
          * returns pin_name x y */
           xSymbol *symbol;
           xRect *rct;
    -      short flip, rot;
    -      double x0,y0, pinx0, piny0;
    +      double pinx0, piny0;
           char num[60];
           int p, i, no_of_pins, slot;
           const char *pin;
    @@ -1785,10 +1784,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
             Tcl_SetResult(interp, "", TCL_STATIC);
             return TCL_OK;
           }
    -      x0 = xctx->inst[i].x0;
    -      y0 = xctx->inst[i].y0;
    -      rot = xctx->inst[i].rot;
    -      flip = xctx->inst[i].flip;
           symbol = xctx->sym + xctx->inst[i].ptr;
           no_of_pins= symbol->rects[PINLAYER];
           rct=symbol->rect[PINLAYER];
    @@ -1810,11 +1805,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
             Tcl_SetResult(interp, "", TCL_STATIC);
             return TCL_OK;
           }
    -      pinx0 = (rct[p].x1+rct[p].x2)/2;
    -      piny0 = (rct[p].y1+rct[p].y2)/2;
    -      ROTATION(rot, flip, 0.0, 0.0, pinx0, piny0, pinx0, piny0);
    -      pinx0 += x0;
    -      piny0 += y0;
    +      get_inst_pin_coord(i, p, &pinx0, &piny0);
           my_snprintf(num, S(num), "{%s} %g %g", get_tok_value(rct[p].prop_ptr, "name", 0), pinx0, piny0);
           Tcl_SetResult(interp, num, TCL_VOLATILE);
           my_free(_ALLOC_ID_, &tmpstr);
    @@ -1869,8 +1860,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
         /* xschem instances_to_net PLUS */
           xSymbol *symbol;
           xRect *rct;
    -      short flip, rot;
    -      double x0,y0, pinx0, piny0, rpinx0, rpiny0;
    +      double pinx0, piny0;
           char *pins = NULL;
           int p, i, no_of_pins;
           prepare_netlist_structs(0);
    @@ -1879,10 +1869,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
             return TCL_ERROR;
           }
           for(i = 0;i < xctx->instances; ++i) {
    -        x0 = xctx->inst[i].x0;
    -        y0 = xctx->inst[i].y0;
    -        rot = xctx->inst[i].rot;
    -        flip = xctx->inst[i].flip;
             symbol = xctx->sym + xctx->inst[i].ptr;
             no_of_pins= symbol->rects[PINLAYER];
             rct=symbol->rect[PINLAYER];
    @@ -1894,13 +1880,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
               if(xctx->inst[i].node[p] && !strcmp(xctx->inst[i].node[p], argv[2]) &&
                  !IS_LABEL_SH_OR_PIN( (xctx->inst[i].ptr+xctx->sym)->type )) {
                 my_mstrcat(_ALLOC_ID_, &pins, "{ {", xctx->inst[i].instname, "} {", pin, NULL);
    -            pinx0 = (rct[p].x1+rct[p].x2)/2;
    -            piny0 = (rct[p].y1+rct[p].y2)/2;
    -            ROTATION(rot, flip, 0.0, 0.0, pinx0, piny0, rpinx0, rpiny0);
    -            rpinx0 += x0;
    -            rpiny0 += y0;
    -            my_strncpy(xx, dtoa(rpinx0), S(xx));
    -            my_strncpy(yy, dtoa(rpiny0), S(yy));
    +            get_inst_pin_coord(i, p, &pinx0, &piny0);
    +            my_strncpy(xx, dtoa(pinx0), S(xx));
    +            my_strncpy(yy, dtoa(piny0), S(yy));
                 my_mstrcat(_ALLOC_ID_, &pins, "} {", xx, "} {", yy, "} } ", NULL);
               }
             }
    @@ -3311,6 +3293,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
           Tcl_ResetResult(interp);
         }
     
    +    /* select_dangling_nets 
    +     *   Select all nets/labels that are dangling, ie not attached to any non pin/port/probe components
    +     *   Returns 1 if danglings found, 0 otherwise */
    +    else if(!strcmp(argv[1], "select_dangling_nets"))  
    +    {       
    +      int r;
    +      r = select_dangling_nets();
    +      Tcl_SetResult(interp, my_itoa(r), TCL_VOLATILE);
    +    }       
    +
         /* select_hilight_net
          *   Select all highlight objects (wires, labels, pins, instances) */
         else if(!strcmp(argv[1], "select_hilight_net"))  
    diff --git a/src/select.c b/src/select.c
    index e07a9a30..9943f7f3 100644
    --- a/src/select.c
    +++ b/src/select.c
    @@ -80,30 +80,165 @@ static void check_connected_wire(int stop_at_junction, int n)
       }
     }
     
    -#if 0
    -int select_dangling_labels(void)
    +int select_dangling_nets(void)
     {
    -  int i;
    -  char * type;
    -  for(i = 0; i < xctx->instances; i++) {
    -    type = (xctx->inst[i].ptr+ xctx->sym)->type;
    -    if( type && (IS_LABEL_SH_OR_PIN(type) || !strcmp(type, "probe") )) {
    -      double x0, y0;
    -      int sqx, sqy;
    -      xRect *rct;
    -      Wireentry *wptr;
    -      rct = (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER];
    -      if(rct) {
    -        get_inst_pin_coord(i, 0, &x0, &y0);
    -        get_square(x0, y0, &sqx, &sqy);
    -        wptr = xctx->wire_spatial_table[sqx][sqy];
    -      }
    +  int i, p, w, touches, rects, done;
    +  int ret = 0; /* return code: 1: dangling elements found */
    +  int *table = NULL;
    +  xRect *rct;
    +  xWire * const wire = xctx->wire;
    +  Instentry *instptr;
    +  Wireentry *wireptr;
    +  Iterator_ctx ctx;
    +  char *type;
    +  double x0, y0, x1, y1, x2, y2;
     
    +  table = my_calloc(_ALLOC_ID_, xctx->wires, sizeof(int));
    +  
    +  hash_instances();
    +  hash_wires();
    +
    +  /* Mark nets connected to non pin/label/probe components as NOT dangling (table[w] = 1) */
    +  for(w = 0; w < xctx->wires; w++) {
    +    x1 = xctx->wire[w].x1;
    +    y1 = xctx->wire[w].y1;
    +    x2 = xctx->wire[w].x2;
    +    y2 = xctx->wire[w].y2;
    +    RECTORDER(x1, y1, x2, y2);
    +    for(init_inst_iterator(&ctx, x1, y1, x2, y2); (instptr = inst_iterator_next(&ctx)) ;) {
    +      i = instptr->n;
    +      type = (xctx->inst[i].ptr+ xctx->sym)->type;
    +      rct=(xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER];
    +      if(!rct) continue;
    +      if( type && (!strcmp(type, "label") || !strcmp(type, "probe") )) {
    +        continue;
    +      }
    +      rects = (xctx->inst[i].ptr + xctx->sym)->rects[PINLAYER];
    +      for(p = 0; p < rects; p++)
    +      {
    +        get_inst_pin_coord(i, p, &x0, &y0);
    +        touches = touch(xctx->wire[w].x1, xctx->wire[w].y1, xctx->wire[w].x2, xctx->wire[w].y2, x0, y0);
    +        if(touches) {
    +          table[w] = 1; /* wire[w] is NOT dangling */
    +          dbg(0, "wire %d touches inst %d\n", w, i);
    +        }
    +      }
         }
       }
    -  return 0;
    +
    +  /* Propagate NOT dangling nets to other nets */
    +  done = 0;
    +  while(!done) {
    +    done = 1;
    +    for(w = 0; w < xctx->wires; w++) {
    +      if(table[w] == 0) continue;
    +      /* wire[w] is not dangling */
    +      x1 = xctx->wire[w].x1;
    +      y1 = xctx->wire[w].y1;
    +      x2 = xctx->wire[w].x2;
    +      y2 = xctx->wire[w].y2;
    +      RECTORDER(x1, y1, x2, y2);
    +      for(init_wire_iterator(&ctx, x1, y1, x2, y2); (wireptr = wire_iterator_next(&ctx)) ;) {
    +        i = wireptr->n;
    +        if(i == w) continue;
    +        if(table[i]) continue;
    +        touches = touch(wire[w].x1, wire[w].y1, wire[w].x2, wire[w].y2, wire[i].x1, wire[i].y1) ||
    +                  touch(wire[w].x1, wire[w].y1, wire[w].x2, wire[w].y2, wire[i].x2, wire[i].y2) ||
    +                  touch(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, wire[w].x1, wire[w].y1) ||
    +                  touch(wire[i].x1, wire[i].y1, wire[i].x2, wire[i].y2, wire[w].x2, wire[w].y2);
    +        if(touches) { 
    +          table[i] = 1; /* wire[i] also not dangling */
    +          done = 0;
    +        }
    +      }
    +    }
    +  }
    +
    +  /* Select all nets that are dangling */
    +  for(w = 0; w < xctx->wires; w++) {
    +    if(!table[w]) {
    +      xctx->wire[w].sel = SELECTED;
    +      ret = 1;
    +    }
    +  }
    +
    +  /* select pins/labels/probes attached to dangling nets */
    +  for(w = 0; w < xctx->wires; w++) {
    +    x1 = xctx->wire[w].x1;
    +    y1 = xctx->wire[w].y1;
    +    x2 = xctx->wire[w].x2;
    +    y2 = xctx->wire[w].y2;
    +    RECTORDER(x1, y1, x2, y2);
    +    for(init_inst_iterator(&ctx, x1, y1, x2, y2); (instptr = inst_iterator_next(&ctx)) ;) {
    +      i = instptr->n;
    +      type = (xctx->inst[i].ptr+ xctx->sym)->type;
    +      if( type && (!strcmp(type, "label") || !strcmp(type, "probe") )) {
    +        rct = (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER];
    +        if(!rct) continue;
    +        get_inst_pin_coord(i, 0, &x0, &y0);
    +        touches = touch(xctx->wire[w].x1, xctx->wire[w].y1, xctx->wire[w].x2, xctx->wire[w].y2, x0, y0);
    +        if(touches && table[w] == 0) {
    +          xctx->inst[i].sel = SELECTED;
    +          ret = 1;
    +        }
    +      }
    +    }
    +  }
    +
    +  /* select dangling labels/probes (not connected to anything) */
    +  for(i = 0; i < xctx->instances; i++) {
    +    int dangling = 1;
    +    type = (xctx->inst[i].ptr+ xctx->sym)->type;
    +    if( type && (!strcmp(type, "label") || !strcmp(type, "probe")) ) {
    +      int sqx, sqy;
    +      rct = (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER];
    +      if(!rct) continue;
    +      get_inst_pin_coord(i, 0, &x0, &y0);
    +      get_square(x0, y0, &sqx, &sqy);
    +      wireptr = xctx->wire_spatial_table[sqx][sqy];
    +      while (wireptr) {
    +        int n = wireptr->n;
    +        if (touch(xctx->wire[n].x1, xctx->wire[n].y1, xctx->wire[n].x2, xctx->wire[n].y2, x0, y0)) {
    +          dangling = 0; /* inst[i] connected to a wire */
    +        }
    +        wireptr = wireptr->next;
    +      }
    +      instptr = xctx->inst_spatial_table[sqx][sqy];
    +      while(instptr) {
    +        int n = instptr->n;
    +        if(n == i) goto cont2;
    +        type = (xctx->inst[n].ptr+ xctx->sym)->type;
    +        if( type && (!strcmp(type, "label") || !strcmp(type, "probe")) ) {
    +          goto cont2;
    +        }
    +        rct = (xctx->inst[n].ptr+ xctx->sym)->rect[PINLAYER];
    +        if(!rct) goto cont2;
    +        rects = (xctx->inst[n].ptr + xctx->sym)->rects[PINLAYER];
    +        for(p = 0; p < rects; p++)
    +        { 
    +          get_inst_pin_coord(n, p, &x1, &y1);
    +          touches = (x0 == x1 && y0 == y1);
    +          if(touches) {
    +            dangling = 0; /* inst[i] connected to non label/probe inst[n] */
    +          }
    +        }
    +        cont2:
    +        instptr = instptr->next;
    +      }
    +      if(dangling) {
    +        xctx->inst[i].sel = SELECTED;
    +        ret = 1;
    +      }
    +    }
    +  }
    +
    +  /* draw selection */
    +  xctx->need_reb_sel_arr = 1;
    +  rebuild_selected_array();
    +  draw_selection(xctx->gc[SELLAYER], 0);
    +  my_free(_ALLOC_ID_, &table);
    +  return ret;
     }
    -#endif
     
     /* stop_at_junction==1 --> stop selecting wires at 'T' junctions */
     void select_connected_wires(int stop_at_junction)
    diff --git a/src/xschem.h b/src/xschem.h
    index c2fac514..09d52dd7 100644
    --- a/src/xschem.h
    +++ b/src/xschem.h
    @@ -1259,6 +1259,8 @@ extern unsigned short select_object(double mx,double my, unsigned short sel_mode
     extern void unselect_all(int dr);
     extern void select_attached_nets(void);
     extern void select_inside(double x1,double y1, double x2, double y2, int sel);
    +/*  Select all nets that are dangling, ie not attached to any non pin/port/probe components */
    +extern int select_dangling_nets(void);
     extern int Tcl_AppInit(Tcl_Interp *interp);
     extern void abort_operation(void);
     extern int callback(const char *winpath, int event, int mx, int my, KeySym key,