From 983f6d9d6b371af0d3a68df5eb941692dacb7bf0 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 26 Sep 2023 01:38:48 +0200 Subject: [PATCH] add tcl variable "unselect_partial_sel_wires" and related options menu entry to unselect partially selected wires attached to component pins after a stretch move command --- src/actions.c | 123 +++++++++++++++++++++++++++++++++---------------- src/move.c | 7 ++- src/xschem.h | 5 +- src/xschem.tcl | 8 ++-- src/xschemrc | 5 ++ 5 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/actions.c b/src/actions.c index 603204cb..486f66a2 100644 --- a/src/actions.c +++ b/src/actions.c @@ -973,20 +973,18 @@ void clear_partial_selected_wires(void) int wire = xctx->sel_array[j].n; select_wire(wire, 0, 1); } + xctx->need_reb_sel_arr = 1; rebuild_selected_array(); } -/* Add wires when moving instances or wires - * action: 1 to select, 0 to unselect */ -short connect_by_kissing(int action) +/* Add wires when moving instances or wires */ +int connect_by_kissing(void) { xSymbol *symbol; int npin, i, j; double x0,y0, pinx0, piny0; - short flip, rot; - xRect *rct; - short kissing, changed = 0; + int kissing, changed = 0; int k, ii, done_undo = 0; Wireentry *wptr; Instpinentry *iptr; @@ -997,24 +995,15 @@ short connect_by_kissing(int action) str_hash_init(&coord_table, HASHSIZE); rebuild_selected_array(); k = xctx->lastsel; - prepare_netlist_structs(0); + prepare_netlist_structs(0); /* rebuild spatial hashes */ /* add wires to moving instance pins */ for(j=0;jsel_array[j].type==ELEMENT) { int inst = xctx->sel_array[j].n; - x0 = xctx->inst[inst].x0; - y0 = xctx->inst[inst].y0; - rot = xctx->inst[inst].rot; - flip = xctx->inst[inst].flip; symbol = xctx->sym + xctx->inst[inst].ptr; npin = symbol->rects[PINLAYER]; - rct=symbol->rect[PINLAYER]; for(i=0;iinstpin_spatial_table[sqx][sqy]; wptr=xctx->wire_spatial_table[sqx][sqy]; @@ -1025,23 +1014,17 @@ short connect_by_kissing(int action) iptr = iptr->next; continue; } - if( iptr->x0 == pinx0 && iptr->y0 == piny0 && xctx->inst[ii].sel == 0) { - kissing=1; + if( iptr->x0 == pinx0 && iptr->y0 == piny0 && xctx->inst[ii].sel == 0) { + kissing = 1; break; } iptr = iptr->next; } while(wptr) { xWire *w = &xctx->wire[wptr->n]; - if( touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0)) { - if( w->sel) { - kissing=0; - break; - } - else { - kissing = 1; - break; - } + if( touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0) && w->sel == 0) { + kissing = 1; + break; } wptr = wptr->next; } @@ -1057,6 +1040,7 @@ short connect_by_kissing(int action) str_hash_lookup(&coord_table, coord, "", XINSERT); storeobject(-1, pinx0, piny0, pinx0, piny0, WIRE, 0, SELECTED1, NULL); changed = 1; + xctx->prep_hash_wires=0; xctx->need_reb_sel_arr = 1; } } @@ -1085,7 +1069,7 @@ short connect_by_kissing(int action) dbg(1, "connect_by_kissing(): ii=%d, x0=%g, y0=%g, iptr->x0=%g, iptr->y0=%g\n", ii, x0, y0, iptr->x0, iptr->y0); if( iptr->x0 == x0 && iptr->y0 == y0 && xctx->inst[ii].sel == 0) { - kissing=1; + kissing = 1; break; } iptr = iptr->next; @@ -1096,15 +1080,9 @@ short connect_by_kissing(int action) wptr = wptr->next; continue; } - if( touch(w->x1, w->y1, w->x2, w->y2, x0, y0)) { - if( w->sel) { - kissing=0; - break; - } - else { - kissing = 1; - break; - } + if( touch(w->x1, w->y1, w->x2, w->y2, x0, y0) && w->sel == 0) { + kissing = 1; + break; } wptr = wptr->next; } @@ -1119,9 +1097,9 @@ short connect_by_kissing(int action) str_hash_lookup(&coord_table, coord, "", XINSERT); storeobject(-1, x0, y0, x0, y0, WIRE, 0, SELECTED1, NULL); changed = 1; + xctx->prep_hash_wires=0; xctx->need_reb_sel_arr = 1; } - } } } @@ -1130,6 +1108,73 @@ short connect_by_kissing(int action) return changed; } +int unselect_partial_sel_wires(void) +{ + xSymbol *symbol; + int npin, i, j; + double x0,y0, pinx0, piny0; + int changed = 0; + int k; + Wireentry *wptr; + int sqx, sqy; + + if(!tclgetboolvar("unselect_partial_sel_wires")) return 0; + rebuild_selected_array(); + k = xctx->lastsel; + prepare_netlist_structs(0); /* rebuild spatial hashes */ + /* unselect wires attached to moved instance pins */ + for(j=0;jsel_array[j].type==ELEMENT) { + int inst = xctx->sel_array[j].n; + symbol = xctx->sym + xctx->inst[inst].ptr; + npin = symbol->rects[PINLAYER]; + for(i=0;iwire_spatial_table[sqx][sqy]; + while(wptr) { + xWire *w = &xctx->wire[wptr->n]; + if(touch(w->x1, w->y1, w->x2, w->y2, pinx0, piny0) && w->sel && w->sel != SELECTED) { + select_wire(wptr->n, 0, 1); + changed = 1; + } + wptr = wptr->next; + } + } + } + /* unselect wires attached to moved wire endpoints */ + for(j=0; j < k; ++j) if(xctx->sel_array[j].type == WIRE) { + int wire = xctx->sel_array[j].n; + if(xctx->wire[wire].sel != SELECTED) continue; /* skip partially selected wires */ + for(i=0;i<2; ++i) { + if(i == 0) { + x0 = xctx->wire[wire].x1; + y0 = xctx->wire[wire].y1; + } else { + x0 = xctx->wire[wire].x2; + y0 = xctx->wire[wire].y2; + } + get_square(x0, y0, &sqx, &sqy); + wptr=xctx->wire_spatial_table[sqx][sqy]; + while(wptr) { + xWire *w = &xctx->wire[wptr->n]; + if(wire == wptr->n) { + wptr = wptr->next; + continue; + } + if(touch(w->x1, w->y1, w->x2, w->y2, x0, y0) && w->sel && w->sel != SELECTED) { + xctx->wire[wptr->n].sel = 0; + select_wire(wptr->n, 0, 1); + changed = 1; + } + wptr = wptr->next; + } + } + } + return changed; +} + + + void attach_labels_to_inst(int interactive) /* offloaded from callback.c 20171005 */ { xSymbol *symbol; diff --git a/src/move.c b/src/move.c index aed3c16e..1bc52adb 100644 --- a/src/move.c +++ b/src/move.c @@ -658,7 +658,7 @@ void copy_objects(int what) xctx->rotatelocal=0; dbg(1, "copy_objects(): START copy\n"); rebuild_selected_array(); - if(tclgetintvar("connect_by_kissing") == 2) xctx->kissing = connect_by_kissing(1); + if(tclgetintvar("connect_by_kissing") == 2) xctx->kissing = connect_by_kissing(); else xctx->kissing = 0; save_selection(1); @@ -1106,7 +1106,7 @@ void move_objects(int what, int merge, double dx, double dy) xctx->deltax = xctx->deltay = 0.0; rebuild_selected_array(); /* if connect_by_kissing==2 it was set in callback.c ('M' command) */ - if(tclgetintvar("connect_by_kissing")) xctx->kissing = connect_by_kissing(1); + if(tclgetintvar("connect_by_kissing")) xctx->kissing = connect_by_kissing(); else xctx->kissing = 0; xctx->movelastsel = xctx->lastsel; if(xctx->lastsel==1 && xctx->sel_array[0].type==ARC && @@ -1622,6 +1622,9 @@ void move_objects(int what, int merge, double dx, double dy) draw(); if(!floaters) bbox(END , 0.0 , 0.0 , 0.0 , 0.0); xctx->rotatelocal=0; + + unselect_partial_sel_wires(); + } draw_selection(xctx->gc[SELLAYER], 0); if(tclgetboolvar("draw_crosshair")) draw_crosshair(0); diff --git a/src/xschem.h b/src/xschem.h index d23a4ffd..1e43c3ec 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -947,7 +947,7 @@ typedef struct { double rx1, rx2, ry1, ry2; short move_rot; /* a wire was created while separating a component frm a net or another component */ - short kissing; + int kissing; short move_flip; int manhattan_lines; double x1, y_1, x2, y_2, deltax, deltay; @@ -1355,7 +1355,8 @@ extern int place_symbol(int pos, const char *symbol_name, double x, double y, sh extern void place_net_label(int type); extern void attach_labels_to_inst(int interactive); extern void clear_partial_selected_wires(void); -extern short connect_by_kissing(int action); /* action: 1 to select, 0 to unselect */ +extern int connect_by_kissing(void); +extern int unselect_partial_sel_wires(void); extern void delete_files(void); extern int sym_vs_sch_pins(void); extern char *get_generator_command(const char *str); diff --git a/src/xschem.tcl b/src/xschem.tcl index 3523b926..4d41acf1 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -5610,7 +5610,8 @@ set tctx::global_list { svg_font_name sym_txt symbol symbol_width tclcmd_txt tclstop text_line_default_geometry text_replace_selection textwindow_fileid textwindow_filename textwindow_w tmp_bus_char toolbar_horiz toolbar_list - toolbar_visible transparent_svg undo_type use_lab_wire use_label_prefix use_tclreadline + toolbar_visible transparent_svg undo_type use_lab_wire unselect_partial_sel_wires + use_label_prefix use_tclreadline user_wants_copy_cell verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w vsize xschem_libs xschem_listen_port zoom_full_center } @@ -5983,6 +5984,8 @@ proc build_widgets { {topwin {} } } { -onvalue disk -offvalue memory -command {switch_undo} $topwin.menubar.option.menu add checkbutton -label "Enable stretch" -variable enable_stretch \ -accelerator Y + $topwin.menubar.option.menu add checkbutton -label "Unsel. partial sel. wires after stretch move" \ + -variable unselect_partial_sel_wires $topwin.menubar.option.menu add checkbutton -label "Auto Join/Trim Wires" -variable autotrim_wires \ -command { @@ -6007,7 +6010,6 @@ proc build_widgets { {topwin {} } } { set bus_replacement_char $tmp_bus_char } } - $topwin.menubar.option.menu add checkbutton -label "Verilog 2001 netlist variant" -variable verilog_2001 $topwin.menubar.option.menu add checkbutton \ -label "Group bus slices in Verilog instances" -variable verilog_bitblast $topwin.menubar.option.menu add checkbutton -label "Draw grid" -variable draw_grid \ @@ -6072,7 +6074,6 @@ proc build_widgets { {topwin {} } } { -value 1 -accelerator H -command {xschem set constrained_move 1} $topwin.menubar.edit.menu add radiobutton -label "Constrained Vertical move" -variable constrained_move \ -value 2 -accelerator V -command {xschem set constrained_move 2} - $topwin.menubar.edit.menu add checkbutton -label "Add wire when separating pins" -variable connect_by_kissing $topwin.menubar.edit.menu add command -label "Push schematic" -command "xschem descend" -accelerator E toolbar_add EditPushSch "xschem descend" "Push schematic" $topwin $topwin.menubar.edit.menu add command -label "Push symbol" -command "xschem descend_symbol" -accelerator I @@ -6754,6 +6755,7 @@ set_ne incr_hilight 1 set_ne enable_stretch 0 set_ne constrained_move 0 set_ne connect_by_kissing 0 +set_ne unselect_partial_sel_wires 0 set_ne draw_crosshair 0 set_ne draw_grid 1 set_ne big_grid_points 0 diff --git a/src/xschemrc b/src/xschemrc index 5eb8f231..e07ac463 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -181,6 +181,11 @@ #### connected by pins. Default: not enabled (0) # set connect_by_kissing 1 +#### if set to 1 at end of a move operation that stretches wires attached to +#### moved objects these wires will be unselected. +#### default: not enabled (0) +# set unselect_partial_sel_wires 0 + #### if set to 1 automatically join/trim wires while editing #### this may slow down on rally big designs. Can be disabled via menu #### default: 0