diff --git a/src/hilight.c b/src/hilight.c index 994b0367..7d8e636a 100644 --- a/src/hilight.c +++ b/src/hilight.c @@ -61,9 +61,11 @@ void display_hilights(char **str) for(i=0;ipath+1); + if(!first) my_strcat(93, str, " "); + my_strcat(943, str,"{"); + my_strcat(1190, str, entry->path+1); my_strcat(1160, str, entry->token); + my_strcat(562, str,"}"); first = 0; entry = entry->next; } @@ -725,8 +727,8 @@ int hilight_netname(const char *name) if(ret && !bus_hilight_lookup(name, hilight_color, XINSERT)) { hilight_nets=1; if(incr_hilight) hilight_color++; + redraw_hilights(); } - redraw_hilights(); return ret; } diff --git a/src/scheduler.c b/src/scheduler.c index 7c991267..96d40192 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -451,6 +451,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1],"set_modify")) { + if(argc == 3 && argv[2][0] == '0') set_modify(0); set_modify(1); Tcl_ResetResult(interp); } @@ -748,6 +749,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } } + /* xschem instance_net inst pin */ } else if(!strcmp(argv[1],"instance_net")) { int no_of_pins, i, p, mult; const char *str_ptr=NULL; @@ -780,7 +782,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg for(n=0; n < lastselected; n++) { if(selectedgroup[n].type == ELEMENT) { i = selectedgroup[n].n; - my_strcat(645, &res, xctx->inst[i].instname); + my_strcat(1191, &res, "{"); + my_strcat(1192, &res, xctx->inst[i].instname); + my_strcat(645, &res, "}"); if(n < lastselected-1) my_strcat(646, &res, " "); } } @@ -806,29 +810,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } if(!strcmp(argv[2],"instance") && argc==4) { - char *endptr; - int i,found=0; - int n; - n=strtol(argv[3], &endptr, 10); - - /* 20171006 find by instance name */ - for(i=0;iinstances;i++) { - if(!strcmp(xctx->inst[i].instname, argv[3])) { - select_element(i, SELECTED, 0, 0); - found=1; - break; - } + int i; + /* find by instance name or number*/ + i = get_instance(argv[3]); + if(i >= 0) { + select_element(i, SELECTED, 0, 0); } - if(!found && !(endptr == argv[3]) && ninstances && n >= 0) { - select_element(n, SELECTED, 0, 0); - found = 1; - } - if(!found) { - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "xschem select instance: instance not found", NULL); - return TCL_ERROR; - } - + Tcl_SetResult(interp, (i >= 0) ? "1" : "0" , TCL_STATIC); } else if(!strcmp(argv[2],"wire") && argc==4) { int n=atol(argv[3]); @@ -843,6 +831,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg drawtempline(gc[SELLAYER], END, 0.0, 0.0, 0.0, 0.0); } else if(!strcmp(argv[1],"instance")) { if(argc==7) + /* pos sym_name x y rot flip prop draw first */ place_symbol(-1, argv[2], atof(argv[3]), atof(argv[4]), atoi(argv[5]), atoi(argv[6]),NULL, 3, 1); else if(argc==8) place_symbol(-1, argv[2], atof(argv[3]), atof(argv[4]), atoi(argv[5]), atoi(argv[6]), argv[7], 3, 1); @@ -1434,6 +1423,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1],"select_hilight_net")) { select_hilight_net(); + Tcl_ResetResult(interp); } else if(!strcmp(argv[1],"unhilight")) { @@ -1609,13 +1599,164 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg const char *pin; pin = get_tok_value((xctx->inst[i].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr,"name",0); if(!pin[0]) pin = "--ERROR--"; - my_strcat(376, &pins, pin); + my_strcat(376, &pins, "{"); + my_strcat(523, &pins, pin); + my_strcat(533, &pins, "}"); if(p< no_of_pins-1) my_strcat(377, &pins, " "); } Tcl_AppendResult(interp, pins, NULL); - my_free(926, &pins); + my_free(1195, &pins); } + + /* xschem instance_pin_coord m12 pinnumber 2 + * xschem instance_pin_coord m12 name p + * returns pin_name x y */ + else if(!strcmp(argv[1],"instance_pin_coord")) { + xSymbol *symbol; + xRect *rct; + int flip, rot; + double x0,y0, pinx0, piny0; + char num[60]; + int p, i, no_of_pins; + if(argc < 5) { + Tcl_SetResult(interp, + "xschem instance_pin_coord requires an instance, a pin attribute and a value", TCL_STATIC); + return TCL_ERROR; + } + i = get_instance(argv[2]); + if(i < 0) { + 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]; + for(p = 0;p < no_of_pins; p++) { + const char *pin; + pin = get_tok_value(rct[p].prop_ptr,argv[3],0); + if(!strcmp(pin, argv[4])) break; + } + if(p >= no_of_pins) { + 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; + my_snprintf(num, S(num), "{%s} %g %g", get_tok_value(rct[p].prop_ptr, "name", 2), pinx0, piny0); + Tcl_SetResult(interp, num, TCL_STATIC); + } + + /* xschem instances_to_net PLUS */ + else if(!strcmp(argv[1],"instances_to_net")) { + xSymbol *symbol; + xRect *rct; + int flip, rot; + double x0,y0, pinx0, piny0; + char num[40]; + + char *pins = NULL; + int p, i, no_of_pins; + prepare_netlist_structs(0); + if(argc < 3) { + Tcl_SetResult(interp,"xschem instances_to_net requires a net name argument", TCL_STATIC); + 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]; + for(p = 0;p < no_of_pins; p++) { + const char *pin; + pin = get_tok_value(rct[p].prop_ptr,"name",0); + if(!pin[0]) pin = "--ERROR--"; + 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_strcat(534, &pins, "{ {"); + my_strcat(535, &pins, xctx->inst[i].instname); + my_strcat(536, &pins, "} {"); + my_strcat(537, &pins, pin); + + 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; + + my_strcat(538, &pins, "} {"); + my_snprintf(num, S(num), "%g", pinx0); + my_strcat(539, &pins, num); + my_strcat(540, &pins, "} {"); + my_snprintf(num, S(num), "%g", piny0); + my_strcat(541, &pins, num); + my_strcat(542, &pins, "} } "); + } + } + Tcl_AppendResult(interp, pins ? pins : "", NULL); + my_free(926, &pins); + } + } + + else if(argc == 3 && !strcmp(argv[1],"expandlabel")) { + int tmp, llen; + char *result=NULL; + const char *l; + + l = expandlabel(argv[2], &tmp); + llen = strlen(l); + result = my_malloc(378, llen + 30); + my_snprintf(result, llen + 30, "%s %d", l, tmp); + Tcl_AppendResult(interp, result, NULL); + my_free(927, &result); + } + + /* xschem instance_nodemap [instance_name] */ + else if(!strcmp(argv[1],"instance_nodemap")) { + char *pins = NULL; + int p, i, no_of_pins; + int inst = -1; + prepare_netlist_structs(0); + + if(argc>=3) inst = get_instance(argv[2]); + for(i=0;iinstances;i++) { + if(inst>=0 && i != inst) continue; + my_strcat(573, &pins, "{ {"); + my_strcat(574, &pins, xctx->inst[i].instname); + my_strcat(575, &pins, "} "); + no_of_pins= (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER]; + for(p=0;pinst[i].ptr+ xctx->sym)->rect[PINLAYER][p].prop_ptr,"name",0); + if(!pin[0]) pin = "--ERROR--"; + if(argc>=4 && strcmp(argv[3], pin)) continue; + my_strcat(576, &pins, "{ "); + my_strcat(655, &pins, "{"); + my_strcat(662, &pins, pin); + my_strcat(663, &pins, "} {"); + my_strcat(664, &pins, xctx->inst[i].node[p] ? xctx->inst[i].node[p] : ""); + my_strcat(665, &pins, "} "); + my_strcat(1155, &pins, "} "); + } + my_strcat(1188, &pins, "} "); + Tcl_AppendResult(interp, pins, NULL); + my_free(1189, &pins); + } + } + + + /* * ********** xschem get subcommands */ @@ -1641,18 +1782,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_AppendResult(interp, xctx->sch_path[x], NULL); } } - else if(argc == 4 && !strcmp(argv[1],"get") && !strcmp(argv[2],"expandlabel")) { - int tmp, llen; - char *result=NULL; - const char *l; - - l = expandlabel(argv[3], &tmp); - llen = strlen(l); - result = my_malloc(378, llen + 30); - my_snprintf(result, llen + 30, "%s %d", l, tmp); - Tcl_AppendResult(interp, result, NULL); - my_free(927, &result); - } else if(!strcmp(argv[1],"get") && argc==3) { if(!strcmp(argv[2],"incr_hilight")) { diff --git a/src/xschem.tcl b/src/xschem.tcl index 73b36491..638e7b83 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -651,34 +651,122 @@ proc xschem_server {sock addr port} { fileevent $sock readable [list xschem_getdata $sock] } -## given a hierarchical net name x1.xamp.netname go down in the hierarchy and -## highlight the specified net. -proc probe_net {net} { - xschem unselect_all - xschem set no_draw 1 +## given a path (x1.x2.m4) descend into x1.x2 and return m4 whether m4 found or not +proc descend_hierarchy {path {redraw 1}} { # return to top level if not already there + xschem set no_draw 1 while { [xschem get currsch] } { xschem go_back } - while { [regexp {\.} $net] } { - set inst $net - regsub {\..*} $inst {} inst - regsub {[^.]+\.} $net {} net + while { [regexp {\.} $path] } { + xschem unselect_all + set inst $path + regsub {\..*} $inst {} inst ;# take 1st path component: xlev1[3].xlev2.m3 -> xlev1[3] + regsub {[^.]+\.} $path {} path ;# take remaining path: xlev1[3].xlev2.m3 -> xlev2.m3 xschem search exact 1 name $inst - set full_inst [split [lindex [xschem get expandlabel [xschem selected_set]] 0] {,}] - set instnum [expr [lsearch -exact $full_inst $inst] + 1] - # puts "$full_inst --> $instnum" + # handle vector instances: xlev1[3:0] -> xlev1[3],xlev1[2],xlev1[1],xlev1[0] + # descend into the right one + set inst_list [split [lindex [xschem expandlabel [lindex [xschem selected_set] 0 ] ] 0] {,}] + set instnum [expr [lsearch -exact $inst_list $inst] + 1] xschem descend $instnum - -# set a [lindex [split [lindex [xschem get expandlabel {xrdec[31:0]}] 0] ,] 3] - - } - set res [xschem hilight_netname $net] - if {$res==0 && [regexp {^net[0-9]+$} $net]} { - set res [xschem hilight_netname \#$net] } xschem set no_draw 0 - xschem redraw - return $res + if {$redraw} {xschem redraw} + return $path +} + + +## given a hierarchical instname name (x1.xamp.m1) go down in the hierarchy and +## select the specified instance (m1). +## this search assumes it is given from the top of hierarchy +proc select_inst {fullinst {redraw 1 } } { + xschem set no_draw 1 + set inst [descend_hierarchy $fullinst 0] + set res [xschem select instance $inst] + # if nothing found return to top + if {!$res} { + while { [xschem get currsch] } { xschem go_back } + } + xschem set no_draw 0 + if {$redraw} {xschem redraw} + if {$res} {return $inst} else { return {} } +} + +proc pin_label {} { + if { [file exists [abs_sym_path devices/lab_pin.sym]] } { + return {devices/lab_pin.sym} + } + return {lab_pin.sym} +} + +## given a hierarchical net name x1.xamp.netname go down in the hierarchy and +## highlight the specified net. +## this search assumes it is given from the top of hierarchy +proc probe_net {fullnet {redraw 1} } { + xschem set no_draw 1 + set net [descend_hierarchy $fullnet 0] + set res [xschem hilight_netname $net] + if {$res==0 && [regexp {^net[0-9]+$} $net]} { + set net \#$net + set res [xschem hilight_netname $net] + } + if {!$res} { + while { [xschem get currsch] } { xschem go_back } + } + xschem set no_draw 0 + if {$redraw} {xschem redraw} + if {$res} {return $net} else { return {} } +} + +proc reroute_inst {fullinst pinattr pinval newnet} { + if { [regexp {\.} $fullinst] } { set hier 1 } else { set hier 0 } + set res [descend_hierarchy $fullinst 0] + if {$res ne {} } { + set coord [xschem instance_pin_coord $res $pinattr $pinval] + if { $coord eq {} } { + while { [xschem get currsch] } { xschem go_back } + return 0 + } + set pinname [lindex $coord 0] + set x [expr [lindex $coord 1] - 10 ] + set y [expr [lindex $coord 2] - 10 ] + set oldnet [xschem instance_net $res $pinname] + + regsub {.*\.} $newnet {} newnet + if { $oldnet eq $newnet } { + while { [xschem get currsch] } { xschem go_back } + puts "Warning: netlist patch already done? " + return 0 + } + + xschem instance [pin_label] $x $y 0 0 [list name=l1 lab=$newnet] + xschem hilight_netname $newnet + xschem select instance $res + xschem hilight_netname $oldnet + if {$hier} { xschem save} + xschem redraw + return 1 + } + return 0 +} + +## put $new net labels close to pins on all elements connected to $old +proc reroute_net {old new} { + xschem push_undo + xschem set no_undo 1 + xschem clear_hilights + probe_net $old + set old_nopath [regsub {.*\.} $old {}] + set new_nopath [regsub {.*\.} $new {}] + set devlist [xschem instances_to_net $old_nopath] + foreach i $devlist { + set instname [lindex $i 0] + set x [expr [lindex $i 2] - 10] + set y [expr [lindex $i 3] - 10] + xschem instance [pin_label] $x $y 0 0 [list name=l1 lab=$new_nopath] + xschem select instance $instname + } + xschem hilight_netname $new_nopath + xschem set no_undo 0 } proc simulate {{callback {}}} { diff --git a/xschem_library/examples/TwoStageAmp.sch b/xschem_library/examples/TwoStageAmp.sch index 4d315509..3cfe6944 100644 --- a/xschem_library/examples/TwoStageAmp.sch +++ b/xschem_library/examples/TwoStageAmp.sch @@ -164,7 +164,7 @@ C {code.sym} 160 -190 0 0 {name=MODELS value=".model Q2N3904 NPN(Is=6.734f Xti "} C {code_shown.sym} 320 -180 0 0 {name=COMMANDS value=".SAVE ALL -*.OP +* .OP .AC DEC 20 1Hz 100MegHz * .DC Vinput 0 5 .01 * .DC Vinput 1 2 .0 diff --git a/xschem_library/pcb/voltage_protection.sch b/xschem_library/pcb/voltage_protection.sch index 832f8cf4..1969ddd4 100644 --- a/xschem_library/pcb/voltage_protection.sch +++ b/xschem_library/pcb/voltage_protection.sch @@ -34,7 +34,7 @@ N 920 -710 920 -520 { lab=VCC_FIVE} N 170 -710 310 -710 { lab=VCC_UNREG} N 170 -630 310 -630 { lab=VSSA} N 820 -710 920 -710 { lab=VCC_FIVE} -N 230 -740 230 -710 { lab=VCC_UNREG} +N 260 -740 260 -710 { lab=VCC_UNREG} C {conn_3x1.sym} 300 -360 0 0 {name=C1} C {opin.sym} 1010 -300 0 0 {name=p0 lab=VOUT} C {lab_wire.sym} 810 -360 0 0 {name=l9 lab=G} @@ -82,5 +82,5 @@ C {reg.sch} -120 -520 0 0 {name=x2} C {ipin.sym} 170 -710 0 0 {name=p3 lab=VCC_UNREG} C {ipin.sym} 170 -630 0 0 {name=p1 lab=VSSA} C {lab_wire.sym} 690 -520 0 0 {name=l4 lab=VCC_FIVE} -C {diode.sym} 230 -770 0 0 {name=D1 model=D1N914 area=1 device=D1N914 footprint=acy(300)} -C {vdd.sym} 230 -800 0 0 {name=l5 lab=VCC} +C {diode.sym} 260 -770 0 1 {name=D1 model=D1N914 area=1 device=D1N914 footprint=acy(300)} +C {vdd.sym} 260 -800 0 0 {name=l5 lab=VCC}