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
Selects all objects in schematic
+ + 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 all highlight objects (wires, labels, pins, instances)
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,