Added various procedures to select flat / hierarchical instances and re-route a terminal to a different net. reroute_inst -> change a pin connection, reroute_net -> change net updating all connected components. "xschem instances_to_net", "xschem instance_nodemap", "xschem instance_pin_coord" new query commands added. "xschem get expandlabel node" renamed to "xschem expandlabel node".
This commit is contained in:
parent
01077ea162
commit
7a7868318b
|
|
@ -61,9 +61,11 @@ void display_hilights(char **str)
|
|||
for(i=0;i<HASHSIZE;i++) {
|
||||
entry = hilight_table[i];
|
||||
while(entry) {
|
||||
if(!first) my_strcat(93, str, ",");
|
||||
my_strcat(562, str, entry->path+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;
|
||||
}
|
||||
|
||||
|
|
|
|||
203
src/scheduler.c
203
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;i<xctx->instances;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]) && n<xctx->instances && 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;i<xctx->instances;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;p<no_of_pins;p++) {
|
||||
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--";
|
||||
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")) {
|
||||
|
|
|
|||
130
src/xschem.tcl
130
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 {}}} {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Reference in New Issue