diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html
index f8af26ee..c936661c 100644
--- a/doc/xschem_man/developer_info.html
+++ b/doc/xschem_man/developer_info.html
@@ -492,6 +492,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
+
abort_operation
Resets UI state, unselect all and abort any pending operation
add_symbol_pin
@@ -513,8 +514,10 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Attach net labels to selected component(s) instance(s)
bbox begin|end
Start/end bounding box calculation: parameter is either 'begin' or 'end'
- break_wires
- Break wires at selected instance pins
+ break_wires [remove]
+ Break wires at selected instance pins
+ if '1' is given as 'remove' parameter broken wires that are all inside selected
+ instances will be deleted
build_colors
Rebuild color palette using values of tcl vars dim_value and dim_bg
callback winpath event mx my key button aux state
@@ -873,6 +876,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
destroy: destroy tab/window identified by winpath. Example:
xschem new_schematic destroy .x1.drw
destroy_all: close all tabs/additional windows
+ if the 'force'argument is given do not issue a warning if modified
+ tabs are about to be closed.
switch: switch context to specified 'winpath' window or specified schematic name
Main window/tab has winpath set to .drw,
Additional windows/tabs have winpath set to .x1.drw, .x2.drw and so on...
diff --git a/src/callback.c b/src/callback.c
index 95d86d9e..7b101c17 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -2377,13 +2377,20 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
view_unzoom(0.0);
break;
}
- if(key=='!')
+ if(key=='!' && !(state & ControlMask))
{
if(xctx->semaphore >= 2) break;
- break_wires_at_pins();
+ break_wires_at_pins(0);
+ break;
+ }
+ if(key=='!' && (state & ControlMask))
+ {
+ if(xctx->semaphore >= 2) break;
+ break_wires_at_pins(1);
break;
}
break;
+
case ButtonPress: /* end operation */
dbg(1, "callback(): ButtonPress ui_state=%d state=%d\n",xctx->ui_state,state);
if(waves_selected(event, key, state, button)) {
diff --git a/src/check.c b/src/check.c
index 5a4bfe1b..95a703e4 100644
--- a/src/check.c
+++ b/src/check.c
@@ -378,13 +378,34 @@ void trim_wires(void)
update_conn_cues(WIRELAYER, 0, 0);
}
-void break_wires_at_pins(void)
+static int touches_inst_pin(double x, double y, int inst)
+{
+ int rects, r;
+ double x0, y0;
+ int touches = 0;
+ if((xctx->inst[inst].ptr >= 0)) {
+ rects = (xctx->inst[inst].ptr + xctx->sym)->rects[PINLAYER];
+ for(r=0;rwire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
if(!changed) { xctx->push_undo(); changed=1;}
check_wire_storage();
- xctx->wire[xctx->wires].x1=xctx->wire[i].x1;
- xctx->wire[xctx->wires].y1=xctx->wire[i].y1;
- xctx->wire[xctx->wires].x2=x0;
- xctx->wire[xctx->wires].y2=y0;
- xctx->wire[xctx->wires].sel=0;
- xctx->wire[xctx->wires].prop_ptr=NULL;
- my_strdup(_ALLOC_ID_, &xctx->wire[xctx->wires].prop_ptr, xctx->wire[i].prop_ptr);
- if(!strcmp(get_tok_value(xctx->wire[xctx->wires].prop_ptr,"bus",0), "true"))
- xctx->wire[xctx->wires].bus=1;
- else
- xctx->wire[xctx->wires].bus=0;
- xctx->wire[xctx->wires].node=NULL;
- hash_wire(XINSERT, xctx->wires, 0); /* insertion happens at beginning of list */
- dbg(1, "break_wires_at_pins(): hashing new wire %d: %g %g %g %g\n",
- xctx->wires, xctx->wire[xctx->wires].x1, xctx->wire[xctx->wires].y1,
- xctx->wire[xctx->wires].x2, xctx->wire[xctx->wires].y2);
- my_strdup(_ALLOC_ID_, &xctx->wire[xctx->wires].node, xctx->wire[i].node);
- xctx->need_reb_sel_arr=1;
- xctx->wires++;
+ if(!remove || !RECT_INSIDE(xctx->wire[i].x1, xctx->wire[i].y1, x0, y0,
+ xctx->inst[k].xx1, xctx->inst[k].yy1, xctx->inst[k].xx2, xctx->inst[k].yy2)
+ || !touches_inst_pin(xctx->wire[i].x1, xctx->wire[i].y1, k)
+ ) {
+ xctx->wire[xctx->wires].x1=xctx->wire[i].x1;
+ xctx->wire[xctx->wires].y1=xctx->wire[i].y1;
+ xctx->wire[xctx->wires].end1 = xctx->wire[i].end1;
+ xctx->wire[xctx->wires].end2 = 0;
+ xctx->wire[xctx->wires].x2=x0;
+ xctx->wire[xctx->wires].y2=y0;
+ xctx->wire[xctx->wires].sel=0;
+ xctx->wire[xctx->wires].prop_ptr=NULL;
+ my_strdup(_ALLOC_ID_, &xctx->wire[xctx->wires].prop_ptr, xctx->wire[i].prop_ptr);
+ if(!strcmp(get_tok_value(xctx->wire[xctx->wires].prop_ptr,"bus",0), "true"))
+ xctx->wire[xctx->wires].bus=1;
+ else
+ xctx->wire[xctx->wires].bus=0;
+ xctx->wire[xctx->wires].node=NULL;
+ hash_wire(XINSERT, xctx->wires, 0); /* insertion happens at beginning of list */
+ dbg(1, "break_wires_at_pins(): hashing new wire %d: %g %g %g %g\n",
+ xctx->wires, xctx->wire[xctx->wires].x1, xctx->wire[xctx->wires].y1,
+ xctx->wire[xctx->wires].x2, xctx->wire[xctx->wires].y2);
+ my_strdup(_ALLOC_ID_, &xctx->wire[xctx->wires].node, xctx->wire[i].node);
+ xctx->need_reb_sel_arr=1;
+ xctx->wires++;
+ } else {
+ dbg(0, "break_wires_at_pins(): skipping wire creation on wire %d\n", i);
+ deleted_wire = 1;
+ }
xctx->wire[i].x1 = x0;
xctx->wire[i].y1 = y0;
+ if(remove && RECT_INSIDE(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2,
+ xctx->inst[k].xx1, xctx->inst[k].yy1, xctx->inst[k].xx2, xctx->inst[k].yy2)) {
+
+ if(touches_inst_pin(xctx->wire[i].x2, xctx->wire[i].y2, k)) {
+ dbg(1, "break_wires_at_pins(): wire %d needs to be deleted: %g %g %g %g\n",
+ i, xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2);
+ /* mark for deletion only if no other nets attached */
+ xctx->wire[i].sel = SELECTED4; /* use a special flag to later delete these wires
+ * only and not other seleted wires */
+ dbg(0, "break_wires_at_pins(): mark wire %d for deletion: end2=%d\n", i, xctx->wire[i].end2);
+ }
+ }
}
}
}
}
}
}
+
+ if(remove) {
+ if(delete_wires(1, SELECTED4)) {
+ deleted_wire = 1;
+ }
+ }
/* break wires that touch selected wires */
rebuild_selected_array();
for(j=0;jlastsel; ++j) if(xctx->sel_array[j].type==WIRE) {
@@ -493,6 +542,10 @@ void break_wires_at_pins(void)
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
xctx->prep_hash_wires=0;
- /*update_conn_cues(WIRELAYER, 0, 0); */
+ if(deleted_wire) {
+ if(tclgetboolvar("autotrim_wires")) trim_wires();
+ update_conn_cues(WIRELAYER, 0, 0);
+ draw();
+ }
}
diff --git a/src/netlist.c b/src/netlist.c
index 18ad946a..77dd924c 100644
--- a/src/netlist.c
+++ b/src/netlist.c
@@ -186,6 +186,7 @@ static void wiredelete(int n, int x, int y)
Wireentry *saveptr, **prevptr;
prevptr = &xctx->wire_spatial_table[x][y];
+ if(*prevptr == NULL) return;
while( (*prevptr)->n != n) prevptr = &(*prevptr)->next;
saveptr = (*prevptr)->next;
my_free(_ALLOC_ID_, prevptr);
diff --git a/src/scheduler.c b/src/scheduler.c
index 6e768d1c..c2093e12 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -307,11 +307,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_ResetResult(interp);
}
- /* break_wires
- * Break wires at selected instance pins */
+ /* break_wires [remove]
+ * Break wires at selected instance pins
+ * if '1' is given as 'remove' parameter broken wires that are all inside selected
+ * instances will be deleted */
else if(!strcmp(argv[1], "break_wires"))
{
- break_wires_at_pins();
+ int remove = 0;
+ if(argc > 2) remove = atoi(argv[2]);
+ break_wires_at_pins(remove);
Tcl_ResetResult(interp);
}
diff --git a/src/select.c b/src/select.c
index be36613f..84190051 100644
--- a/src/select.c
+++ b/src/select.c
@@ -333,6 +333,50 @@ static void del_rect_line_arc_poly(int floaters)
}
+int delete_wires(int floaters, int selected_flag)
+{
+ int i, j = 0, deleted = 0;
+ for(i=0;iwires; ++i)
+ {
+ if(xctx->wire[i].sel == selected_flag) {
+ ++j;
+ if(xctx->wire[i].bus){
+ double ov, y1, y2;
+ ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE;
+ if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
+ else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
+ if(!floaters) bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
+ } else {
+ double ov, y1, y2;
+ ov = cadhalfdotsize;
+ if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
+ else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
+ if(!floaters) bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
+ }
+
+ hash_wire(XDELETE, i, 0);
+ my_free(_ALLOC_ID_, &xctx->wire[i].prop_ptr);
+ my_free(_ALLOC_ID_, &xctx->wire[i].node);
+
+ deleted = 1;
+ continue;
+ }
+ if(j) {
+ xctx->wire[i-j] = xctx->wire[i];
+ }
+ }
+ xctx->wires -= j;
+ if(j) {
+ xctx->prep_hash_wires=0;
+ xctx->prep_net_structs=0;
+ xctx->prep_hi_structs=0;
+ }
+ if(xctx->hilight_nets) {
+ propagate_hilights(1, 1, XINSERT_NOREPLACE);
+ }
+ return deleted;
+}
+
void delete(int to_push_undo)
{
int i, j, tmp, deleted = 0, floaters;
@@ -420,44 +464,15 @@ void delete(int to_push_undo)
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;
}
- j = 0;
- for(i=0;iwires; ++i)
- {
- if(xctx->wire[i].sel == SELECTED) {
- ++j;
- if(xctx->wire[i].bus){
- double ov, y1, y2;
- ov = INT_BUS_WIDTH(xctx->lw)> cadhalfdotsize ? INT_BUS_WIDTH(xctx->lw) : CADHALFDOTSIZE;
- if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
- else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
- if(!floaters) bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
- } else {
- double ov, y1, y2;
- ov = cadhalfdotsize;
- if(xctx->wire[i].y1 < xctx->wire[i].y2) { y1 = xctx->wire[i].y1-ov; y2 = xctx->wire[i].y2+ov; }
- else { y1 = xctx->wire[i].y1+ov; y2 = xctx->wire[i].y2-ov; }
- if(!floaters) bbox(ADD, xctx->wire[i].x1-ov, y1 , xctx->wire[i].x2+ov , y2 );
- }
- my_free(_ALLOC_ID_, &xctx->wire[i].prop_ptr);
- my_free(_ALLOC_ID_, &xctx->wire[i].node);
+ if(delete_wires(floaters, SELECTED)) {
+ deleted = 1;
+ if(tclgetboolvar("autotrim_wires")) trim_wires();
+ update_conn_cues(WIRELAYER, 0, 0);
+ }
- deleted = 1;
- continue;
- }
- if(j) {
- xctx->wire[i-j] = xctx->wire[i];
- }
- }
- xctx->wires -= j;
- if(j) {
- xctx->prep_hash_wires=0;
- xctx->prep_net_structs=0;
- xctx->prep_hi_structs=0;
- }
- if(tclgetboolvar("autotrim_wires")) trim_wires();
del_rect_line_arc_poly(floaters);
- update_conn_cues(WIRELAYER, 0, 0);
+
if(xctx->hilight_nets) {
propagate_hilights(1, 1, XINSERT_NOREPLACE);
}
@@ -479,7 +494,6 @@ void delete(int to_push_undo)
xctx->ui_state &= ~SELECTION;
}
-
void delete_only_rect_line_arc_poly(void)
{
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
diff --git a/src/xschem.h b/src/xschem.h
index 4d9ed391..78144db8 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1221,6 +1221,7 @@ extern const char *get_sym_template(char *s, char *extra);
extern void zoom_full(int draw, int sel, int flags, double shrink);
extern void updatebbox(int count,xRect *boundbox,xRect *tmp);
extern void draw_selection(GC g, int interruptable);
+extern int delete_wires(int floaters, int selected_flag);
extern void delete(int to_push_undo);
extern void delete_only_rect_line_arc_poly(void);
extern void polygon_bbox(double *x, double *y, int points, double *bx1, double *by1, double *bx2, double *by2);
@@ -1300,7 +1301,7 @@ extern int rectclip(int,int,int,int,
double*,double*,double*,double*);
extern void trim_wires(void);
extern void update_conn_cues(int layer, int draw_cues, int dr_win);
-extern void break_wires_at_pins(void);
+extern void break_wires_at_pins(int remove);
extern void check_touch(int i, int j,
unsigned short *parallel,unsigned short *breaks,
diff --git a/src/xschem.tcl b/src/xschem.tcl
index 2265a396..09e97db7 100644
--- a/src/xschem.tcl
+++ b/src/xschem.tcl
@@ -6101,6 +6101,8 @@ proc build_widgets { {topwin {} } } {
toolbar_add ToolJoinTrim "xschem trim_wires" "Join/Trim Wires" $topwin
$topwin.menubar.tools.menu add command -label "Break wires at selected instance pins" \
-command "xschem break_wires" -accelerator {!}
+ $topwin.menubar.tools.menu add command -label "Remove wires running throuh selected inst. pins" \
+ -command "xschem break_wires 1" -accelerator {Ctrl-!}
toolbar_add ToolBreak "xschem break_wires" "Break wires at selected\ninstance pin intersections" $topwin
$topwin.menubar.tools.menu add checkbutton -label "Auto Join/Trim Wires" -variable autotrim_wires \
-command {