add command "xschem select_dangling_nets" that selects all labels/wires that are not connected to any non-label/non-probe components
This commit is contained in:
parent
afd25cf430
commit
75e5d3d5b0
|
|
@ -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 </pre>
|
||||
<li><kbd> select_all</kbd></li><pre>
|
||||
Selects all objects in schematic </pre>
|
||||
<li><kbd> select_dangling_nets </kbd></li><pre>
|
||||
Select all nets/labels that are dangling, ie not attached to any non pin/port/probe components
|
||||
Returns 1 if danglings found, 0 otherwise </pre>
|
||||
<li><kbd> select_hilight_net</kbd></li><pre>
|
||||
Select all highlight objects (wires, labels, pins, instances) </pre>
|
||||
<li><kbd> selected_set</kbd></li><pre>
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
173
src/select.c
173
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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue