diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html index ebd464e5..965f744e 100644 --- a/doc/xschem_man/developer_info.html +++ b/doc/xschem_man/developer_info.html @@ -500,8 +500,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns" - - @@ -556,9 +554,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Compare currently loaded schematic with another 'sch_file' schematic.
if no file is given prompt user to choose one
- - Select nets connected to currently selected net or net label/pin. - if '1' argument is given, stop at wire junctions+
+ Select nets/labels connected to currently selected instance + if '1' argument is given, stop at wire junctions + if '2' argument is given select only wires directly attached to selected instance/net + if '3' argument is given combine '1' and '2'
Copy selection to clipboard
@@ -1284,6 +1284,9 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
+
+
+
diff --git a/src/callback.c b/src/callback.c
index 830baf9a..34c378f9 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -2416,7 +2416,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(button == Button3 && state == ControlMask && xctx->semaphore <2)
{
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
- if(sel) select_connected_wires(1);
+ if(sel) select_connected_nets(1);
}
else if(button == Button3 && state == Mod1Mask && xctx->semaphore <2)
{
@@ -2425,7 +2425,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
{
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0);
- if(sel) select_connected_wires(0);
+ if(sel) select_connected_nets(0);
}
else if(button == Button3 && state == 0 && xctx->semaphore <2) {
int ret;
diff --git a/src/scheduler.c b/src/scheduler.c
index f3a9b710..16d2cbd2 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -477,14 +477,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE);
}
- /* connected_nets [1|0]
- * Select nets connected to currently selected net or net label/pin.
- * if '1' argument is given, stop at wire junctions */
+ /* connected_nets [0|1|2|3]
+ * Select nets/labels connected to currently selected instance
+ * if '1' argument is given, stop at wire junctions
+ * if '2' argument is given select only wires directly attached to selected instance/net
+ * if '3' argument is given combine '1' and '2' */
else if(!strcmp(argv[1], "connected_nets"))
{
int stop_at_junction = 0;
- if(argc > 2 && argv[2][0] == '1') stop_at_junction = 1;
- select_connected_wires(stop_at_junction);
+ if(argc > 2 ) stop_at_junction = atoi(argv[2]);
+ select_connected_nets(stop_at_junction);
Tcl_ResetResult(interp);
}
diff --git a/src/select.c b/src/select.c
index 996c1d9d..8e4dab79 100644
--- a/src/select.c
+++ b/src/select.c
@@ -22,10 +22,12 @@
#include "xschem.h"
-/* select all nets and pins/labels that are *physically* connected to current selected wire segments */
-/* stop_at_junction==1 --> stop selecting wires at 'T' junctions */
-/* Recursive routine */
-static void check_connected_wire(int stop_at_junction, int n)
+/* select all nets and pins/labels that are *physically* connected to current selected wire segments
+ * stop_at_junction==1 --> stop selecting wires at 'T' junctions
+ * stop_at_junction==2 --> select only wires directly attached to selected net/instance
+ * Recursive routine
+ */
+static void check_connected_nets(int stop_at_junction, int n)
{
int k, touches;
xWire * const wire = xctx->wire;
@@ -40,7 +42,7 @@ static void check_connected_wire(int stop_at_junction, int n)
x2 = wire[n].x2;
y2 = wire[n].y2;
RECTORDER(x1, y1, x2, y2);
- dbg(1, "check_connected_wire(): n=%d, %g %g %g %g\n", n, x1, y1, x2, y2);
+ dbg(1, "check_connected_nets(): n=%d, %g %g %g %g\n", n, x1, y1, x2, y2);
for(init_inst_iterator(&ctx, x1, y1, x2, y2); (instptr = inst_iterator_next(&ctx)) ;) {
k = instptr->n;
type = (xctx->inst[k].ptr+ xctx->sym)->type;
@@ -58,28 +60,83 @@ static void check_connected_wire(int stop_at_junction, int n)
}
}
}
- for(init_wire_iterator(&ctx, x1, y1, x2, y2); (wireptr = wire_iterator_next(&ctx)) ;) {
- k = wireptr->n;
- if(n == k || xctx->wire[k].sel == SELECTED) continue;
- if(!stop_at_junction) {
- touches = touch(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2, wire[k].x1, wire[k].y1) ||
- touch(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2, wire[k].x2, wire[k].y2) ||
- touch(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, wire[n].x1, wire[n].y1) ||
- touch(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, wire[n].x2, wire[n].y2);
- } else {
- touches = (wire[n].x1 == wire[k].x1 && wire[n].y1 == wire[k].y1 && wire[n].end1 < 2 && wire[k].end1 < 2) ||
- (wire[n].x1 == wire[k].x2 && wire[n].y1 == wire[k].y2 && wire[n].end1 < 2 && wire[k].end2 < 2) ||
- (wire[n].x2 == wire[k].x1 && wire[n].y2 == wire[k].y1 && wire[n].end2 < 2 && wire[k].end1 < 2) ||
- (wire[n].x2 == wire[k].x2 && wire[n].y2 == wire[k].y2 && wire[n].end2 < 2 && wire[k].end2 < 2);
- }
- if(touches) {
- xctx->need_reb_sel_arr=1;
- xctx->wire[k].sel = SELECTED;
- check_connected_wire(stop_at_junction, k); /* recursive check */
+ if(!(stop_at_junction & 2)) {
+ for(init_wire_iterator(&ctx, x1, y1, x2, y2); (wireptr = wire_iterator_next(&ctx)) ;) {
+ k = wireptr->n;
+ if(n == k || xctx->wire[k].sel == SELECTED) continue;
+
+
+
+
+ if((stop_at_junction & 1)== 0) {
+ touches = touch(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2, wire[k].x1, wire[k].y1) ||
+ touch(wire[n].x1, wire[n].y1, wire[n].x2, wire[n].y2, wire[k].x2, wire[k].y2) ||
+ touch(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, wire[n].x1, wire[n].y1) ||
+ touch(wire[k].x1, wire[k].y1, wire[k].x2, wire[k].y2, wire[n].x2, wire[n].y2);
+ } else {
+ touches = (wire[n].x1 == wire[k].x1 && wire[n].y1 == wire[k].y1 && wire[n].end1 < 2 && wire[k].end1 < 2) ||
+ (wire[n].x1 == wire[k].x2 && wire[n].y1 == wire[k].y2 && wire[n].end1 < 2 && wire[k].end2 < 2) ||
+ (wire[n].x2 == wire[k].x1 && wire[n].y2 == wire[k].y1 && wire[n].end2 < 2 && wire[k].end1 < 2) ||
+ (wire[n].x2 == wire[k].x2 && wire[n].y2 == wire[k].y2 && wire[n].end2 < 2 && wire[k].end2 < 2);
+ }
+ if(touches) {
+ xctx->wire[k].sel = SELECTED;
+ check_connected_nets(stop_at_junction, k); /* recursive check */
+ }
}
}
}
+/* stop_at_junction==1 --> stop selecting wires at 'T' junctions
+ * stop_at_junction==2 --> select only wires directly attached to selected net/instance
+ */
+void select_connected_nets(int stop_at_junction)
+{
+ int i, n;
+
+ if(stop_at_junction & 1) trim_wires();
+ hash_wires();
+ hash_instances();
+ rebuild_selected_array(); /* does nothing as already done in most of use cases */
+ for(n=0; nlastsel; ++n) {
+ i = xctx->sel_array[n].n;
+ switch(xctx->sel_array[n].type) {
+ double x0, y0;
+ int sqx, sqy, p, rects;
+ Wireentry *wptr;
+
+ case WIRE:
+ if(xctx->wire[i].sel == SELECTED) check_connected_nets(stop_at_junction, i);
+ break;
+ case ELEMENT:
+ rects = (xctx->inst[i].ptr + xctx->sym)->rects[PINLAYER];
+ for(p = 0; p < rects; p++)
+ {
+ get_inst_pin_coord(i, p, &x0, &y0);
+ get_square(x0, y0, &sqx, &sqy);
+ wptr = xctx->wire_spatial_table[sqx][sqy];
+ while (wptr) {
+ dbg(1, "select_connected_nets(): x0=%g y0=%g wire[%d]=%g %g %g %g\n",
+ x0, y0, wptr->n, xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1,
+ xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2);
+ if (touch(xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1,
+ xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) {
+ xctx->wire[wptr->n].sel = SELECTED;
+ check_connected_nets(stop_at_junction, wptr->n);
+ }
+ wptr=wptr->next;
+ }
+ } /* for(p...) */
+ break;
+ default:
+ break;
+ } /* switch(...) */
+ } /* for(... lastsel ...) */
+ xctx->need_reb_sel_arr=1;
+ rebuild_selected_array();
+ draw_selection(xctx->gc[SELLAYER], 0);
+}
+
int select_dangling_nets(void)
{
int netlist_lvs_ignore=tclgetboolvar("lvs_ignore");
@@ -243,57 +300,6 @@ int select_dangling_nets(void)
return ret;
}
-/* stop_at_junction==1 --> stop selecting wires at 'T' junctions */
-void select_connected_wires(int stop_at_junction)
-{
- int i, n;
-
- if(stop_at_junction) trim_wires();
- hash_wires();
- hash_instances();
- rebuild_selected_array(); /* does nothing as already done in most of use cases */
- for(n=0; nlastsel; ++n) {
- i = xctx->sel_array[n].n;
- switch(xctx->sel_array[n].type) {
- char *type;
- case WIRE:
- if(xctx->wire[i].sel == SELECTED) check_connected_wire(stop_at_junction, i);
- break;
- case ELEMENT:
- 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];
- while (wptr) {
- dbg(1, "select_connected_wires(): x0=%g y0=%g wire[%d]=%g %g %g %g\n",
- x0, y0, wptr->n, xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1,
- xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2);
- if (touch(xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1,
- xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) {
- xctx->wire[wptr->n].sel = SELECTED;
- check_connected_wire(stop_at_junction, wptr->n);
- }
- wptr=wptr->next;
- }
- } /* if(rct) */
- } /* if(type & ...) */
- break;
- default:
- break;
- } /* switch(...) */
- } /* for(... lastsel ...) */
- rebuild_selected_array();
- draw_selection(xctx->gc[SELLAYER], 0);
-}
-
-
void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
{
int j, tmp;
diff --git a/src/xschem.h b/src/xschem.h
index 09d52dd7..fcab50ec 100644
--- a/src/xschem.h
+++ b/src/xschem.h
@@ -1537,7 +1537,7 @@ extern void logic_set(int v, int num, const char *net_name);
extern int hilight_netname(const char *name);
extern void unhilight_net();
extern void propagate_hilights(int set, int clear, int mode);
-extern void select_connected_wires(int stop_at_junction);
+extern void select_connected_nets(int stop_at_junction);
extern char *resolved_net(const char *net);
extern void draw_hilight_net(int on_window);
extern void display_hilights(int what, char **str);