From cf5813970ccd90596d8bb740f7615309cd860d6b Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Sat, 2 Jan 2021 23:42:22 +0100 Subject: [PATCH] prepare for delete connection implementation --- src/callback.c | 2 +- src/netlist.c | 2 +- src/scheduler.c | 4 +- src/select.c | 90 ++++++++++++--------- src/xschem.h | 2 +- xschem_library/examples/mos_power_ampli.sch | 6 ++ 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/src/callback.c b/src/callback.c index 2159e26f..1bf30cc6 100644 --- a/src/callback.c +++ b/src/callback.c @@ -642,7 +642,7 @@ int callback(int event, int mx, int my, KeySym key, if(key==XK_Delete && (xctx->ui_state & SELECTION) && state == ShiftMask ) { if(xctx->semaphore >= 2) break; - select_connected_wires();break; + select_connected_wires(0);break; } if(key==XK_Delete && (xctx->ui_state & SELECTION) && state == 0) /* delete objects */ { diff --git a/src/netlist.c b/src/netlist.c index 0f01f1a7..fda23f8f 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -346,8 +346,8 @@ void hash_wire(int what, int n, int incremental) void hash_wires(void) { int n; - if(xctx->prep_hash_wires) return; + here(1234); del_wire_table(); for(n=0; nwires; n++) hash_wire(XINSERT, n, 0); diff --git a/src/scheduler.c b/src/scheduler.c index 64ee90f0..33453827 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -270,8 +270,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1],"connected_nets")) /* selected nets connected to currently selected ones */ { + int stop_at_junction = 0; cmd_found = 1; - select_connected_wires(); + if(argc>=3 && argv[2][0] == '1') stop_at_junction = 1; + select_connected_wires(stop_at_junction); Tcl_ResetResult(interp); } diff --git a/src/select.c b/src/select.c index 567aeb39..d9ed0997 100644 --- a/src/select.c +++ b/src/select.c @@ -27,8 +27,9 @@ static short select_flip = 0; static double xx1,yy1,xx2,yy2; /* 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 n) +static void check_connected_wire(int stop_at_junction, int n) { int k, touches; xWire * const wire = xctx->wire; @@ -71,63 +72,74 @@ static void check_connected_wire(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; - 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); + 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(k); /* recursive check */ + check_connected_wire(stop_at_junction, k); /* recursive check */ } } } -void select_connected_wires(void) +/* 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(i); + 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") || !strcmp(type, "ngprobe"))) { - double rx1, ry1, x0, y0; - int rot, flip, sqx, sqy; - xRect *rct; - struct wireentry *wptr; - rct = (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER]; - if(rct) { - x0 = (rct[0].x1 + rct[0].x2) / 2; - y0 = (rct[0].y1 + rct[0].y2) / 2; - rot = xctx->inst[i].rot; - flip = xctx->inst[i].flip; - ROTATION(rot, flip, 0.0,0.0,x0,y0,rx1,ry1); - x0 = xctx->inst[i].x0+rx1; - y0 = xctx->inst[i].y0+ry1; - get_square(x0, y0, &sqx, &sqy); - wptr = xctx->wiretable[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(wptr->n); - } - wptr=wptr->next; - } - } /* if(rct) */ - } /* if(type & ...) */ + if(!stop_at_junction) { + type = (xctx->inst[i].ptr+ xctx->sym)->type; + if( type && (IS_LABEL_SH_OR_PIN(type) || !strcmp(type, "probe") || !strcmp(type, "ngprobe"))) { + double rx1, ry1, x0, y0; + int rot, flip, sqx, sqy; + xRect *rct; + struct wireentry *wptr; + rct = (xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER]; + if(rct) { + x0 = (rct[0].x1 + rct[0].x2) / 2; + y0 = (rct[0].y1 + rct[0].y2) / 2; + rot = xctx->inst[i].rot; + flip = xctx->inst[i].flip; + ROTATION(rot, flip, 0.0,0.0,x0,y0,rx1,ry1); + x0 = xctx->inst[i].x0+rx1; + y0 = xctx->inst[i].y0+ry1; + get_square(x0, y0, &sqx, &sqy); + wptr = xctx->wiretable[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 & ...) */ + } /* if(!stop_at_junction) */ break; default: break; diff --git a/src/xschem.h b/src/xschem.h index 076605a7..d6825070 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1149,7 +1149,7 @@ extern void logic_set(int v, int num); 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(void); +extern void select_connected_wires(int stop_at_junction); extern void draw_hilight_net(int on_window); extern void display_hilights(char **str); extern void redraw_hilights(void); diff --git a/xschem_library/examples/mos_power_ampli.sch b/xschem_library/examples/mos_power_ampli.sch index 9642c6c5..1da18731 100644 --- a/xschem_library/examples/mos_power_ampli.sch +++ b/xschem_library/examples/mos_power_ampli.sch @@ -92,6 +92,12 @@ N 340 -1180 560 -1180 {lab=VPP} N 1110 -1180 1110 -790 { lab=VPP} N 560 -1180 1110 -1180 {lab=VPP} N 230 -950 800 -950 { lab=#net2} +N 1290 -370 1450 -370 { lab=#net8} +N 1450 -370 1570 -370 { lab=#net8} +N 1450 -490 1450 -370 { lab=#net8} +N 1300 -300 1450 -300 { lab=#net9} +N 1450 -300 1570 -240 { lab=#net9} +N 1450 -340 1450 -300 { lab=#net9} C {ipin.sym} 530 -160 0 0 {name=p0 lab=PLUS} C {ipin.sym} 530 -120 0 0 {name=p2 lab=VPP} C {ipin.sym} 530 -100 0 0 {name=p3 lab=VNN}