initial implementation of portmap feature: from sub-schematics resolve hierarchic name of schematic nets connected to I/O pins (go to the upper level recursively until resolved)
This commit is contained in:
parent
970c8597f6
commit
09a373954f
|
|
@ -530,6 +530,7 @@ void ask_new_file(void)
|
|||
remove_symbols();
|
||||
load_schematic(1, f, 1, 1);
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]);
|
||||
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch],".");
|
||||
xctx->sch_path_hash[xctx->currsch] = 0;
|
||||
xctx->sch_inst_number[xctx->currsch] = 1;
|
||||
|
|
@ -1602,11 +1603,11 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst)
|
|||
|
||||
int descend_schematic(int instnumber)
|
||||
{
|
||||
const char *str;
|
||||
char *str = NULL;
|
||||
char filename[PATH_MAX];
|
||||
int inst_mult, inst_number;
|
||||
int save_ok = 0;
|
||||
int n = 0;
|
||||
int i, n = 0;
|
||||
|
||||
rebuild_selected_array();
|
||||
if(xctx->lastsel !=1 || xctx->sel_array[0].type!=ELEMENT) {
|
||||
|
|
@ -1655,17 +1656,13 @@ int descend_schematic(int instnumber)
|
|||
dbg(1, "descend_schematic(): selected instname=%s\n", xctx->inst[n].instname);
|
||||
|
||||
if(xctx->inst[n].instname && xctx->inst[n].instname[0]) {
|
||||
str=expandlabel(xctx->inst[n].instname, &inst_mult);
|
||||
my_strdup2(_ALLOC_ID_, &str, expandlabel(xctx->inst[n].instname, &inst_mult));
|
||||
} else {
|
||||
str = "";
|
||||
my_strdup2(_ALLOC_ID_, &str, "");
|
||||
inst_mult = 1;
|
||||
}
|
||||
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
|
||||
xctx->sch_path_hash[xctx->currsch+1] =0;
|
||||
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].prop_ptr,
|
||||
xctx->inst[n].prop_ptr);
|
||||
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ,
|
||||
get_tok_value((xctx->inst[n].ptr+ xctx->sym)->prop_ptr, "template", 0));
|
||||
prepare_netlist_structs(0);
|
||||
|
||||
inst_number = 1;
|
||||
if(inst_mult > 1) { /* on multiple instances ask where to descend, to correctly evaluate
|
||||
the hierarchy path you descend to */
|
||||
|
|
@ -1677,8 +1674,7 @@ int descend_schematic(int instnumber)
|
|||
inum = tclresult();
|
||||
dbg(1, "descend_schematic(): inum=%s\n", inum);
|
||||
if(!inum[0]) {
|
||||
my_free(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1]);
|
||||
xctx->sch_path_hash[xctx->currsch+1] =0;
|
||||
my_free(_ALLOC_ID_, &str);
|
||||
return 0;
|
||||
}
|
||||
inst_number=atoi(inum);
|
||||
|
|
@ -1689,11 +1685,48 @@ int descend_schematic(int instnumber)
|
|||
/* any invalid number->descend to leftmost inst */
|
||||
if(inst_number <1 || inst_number > inst_mult) inst_number = 1;
|
||||
}
|
||||
|
||||
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
|
||||
xctx->sch_path_hash[xctx->currsch+1] =0;
|
||||
if(xctx->portmap[xctx->currsch + 1].table) str_hash_free(&xctx->portmap[xctx->currsch + 1]);
|
||||
str_hash_init(&xctx->portmap[xctx->currsch + 1], HASHSIZE);
|
||||
|
||||
for(i = 0; i < xctx->sym[xctx->inst[n].ptr].rects[PINLAYER]; i++) {
|
||||
const char *pin_name = get_tok_value(xctx->sym[xctx->inst[n].ptr].rect[PINLAYER][i].prop_ptr,"name",0);
|
||||
char *pin_node = NULL, *net_node = NULL;
|
||||
int k, mult, net_mult;
|
||||
char *single_p = NULL, *single_n = NULL;
|
||||
|
||||
if(!pin_name[0]) continue;
|
||||
if(!xctx->inst[n].node[i]) continue;
|
||||
|
||||
my_strdup2(_ALLOC_ID_, &pin_node, expandlabel(pin_name, &mult));
|
||||
my_strdup2(_ALLOC_ID_, &net_node, expandlabel(xctx->inst[n].node[i], &net_mult));
|
||||
|
||||
for(k = 1; k<=mult; ++k) {
|
||||
my_strdup2(_ALLOC_ID_, &single_p, find_nth(pin_node, ",", k));
|
||||
my_strdup2(_ALLOC_ID_, &single_n,
|
||||
find_nth(net_node, ",", ((inst_number - 1) * mult + k - 1) % net_mult + 1));
|
||||
str_hash_lookup(&xctx->portmap[xctx->currsch + 1], single_p, single_n, XINSERT);
|
||||
dbg(1, "descend_schematic(): %s: %s ->%s\n", xctx->inst[n].instname, single_p, single_n);
|
||||
}
|
||||
if(single_p) my_free(_ALLOC_ID_, &single_p);
|
||||
if(single_n) my_free(_ALLOC_ID_, &single_n);
|
||||
my_free(_ALLOC_ID_, &net_node);
|
||||
my_free(_ALLOC_ID_, &pin_node);
|
||||
}
|
||||
|
||||
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].prop_ptr,
|
||||
xctx->inst[n].prop_ptr);
|
||||
my_strdup(_ALLOC_ID_, &xctx->hier_attr[xctx->currsch].templ,
|
||||
get_tok_value((xctx->inst[n].ptr+ xctx->sym)->prop_ptr, "template", 0));
|
||||
|
||||
dbg(1,"descend_schematic(): inst_number=%d\n", inst_number);
|
||||
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], find_nth(str, ",", inst_number));
|
||||
my_free(_ALLOC_ID_, &str);
|
||||
dbg(1,"descend_schematic(): inst_number=%d\n", inst_number);
|
||||
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], ".");
|
||||
xctx->sch_inst_number[xctx->currsch+1] = inst_number;
|
||||
xctx->sch_inst_number[xctx->currsch] = inst_number;
|
||||
dbg(1, "descend_schematic(): current path: %s\n", xctx->sch_path[xctx->currsch+1]);
|
||||
dbg(1, "descend_schematic(): inst_number=%d\n", inst_number);
|
||||
|
||||
|
|
@ -1703,7 +1736,6 @@ int descend_schematic(int instnumber)
|
|||
xctx->zoom_array[xctx->currsch].zoom=xctx->zoom;
|
||||
xctx->currsch++;
|
||||
hilight_child_pins();
|
||||
|
||||
unselect_all(1);
|
||||
get_sch_from_sym(filename, xctx->inst[n].ptr+ xctx->sym, n);
|
||||
dbg(1, "descend_schematic(): filename=%s\n", filename);
|
||||
|
|
@ -1756,6 +1788,9 @@ void go_back(int confirm) /* 20171006 add confirm */
|
|||
from_embedded_sym=1;
|
||||
}
|
||||
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
|
||||
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]);
|
||||
|
||||
xctx->sch_path_hash[xctx->currsch] = 0;
|
||||
xctx->currsch--;
|
||||
save_modified = xctx->modified; /* we propagate modified flag (cleared by load_schematic */
|
||||
/* by default) to parent schematic if going back from embedded symbol */
|
||||
|
|
@ -1765,7 +1800,7 @@ void go_back(int confirm) /* 20171006 add confirm */
|
|||
/* if we are returning from a symbol created from a generator don't set modified flag on parent
|
||||
* as these symbols can not be edited / saved as embedded
|
||||
* xctx->sch_inst_number[xctx->currsch + 1] == -1 --> we came from an inst with no embed flag set */
|
||||
if(from_embedded_sym && xctx->sch_inst_number[xctx->currsch + 1] != -1)
|
||||
if(from_embedded_sym && xctx->sch_inst_number[xctx->currsch] != -1)
|
||||
xctx->modified=save_modified; /* to force ask save embedded sym in parent schematic */
|
||||
|
||||
if(xctx->hilight_nets) {
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ void hilight_parent_pins(void)
|
|||
if(!xctx->hilight_nets) return;
|
||||
prepare_netlist_structs(0);
|
||||
i=xctx->previous_instance[xctx->currsch];
|
||||
inst_number = xctx->sch_inst_number[xctx->currsch+1];
|
||||
inst_number = xctx->sch_inst_number[xctx->currsch];
|
||||
|
||||
/* may be set to -1 by descend_symbol to notify we are
|
||||
* descending into a smbol from an instance with no embed flag set
|
||||
|
|
@ -529,7 +529,7 @@ void hilight_parent_pins(void)
|
|||
bus_hilight_hash_lookup(find_nth(net_node, ",",
|
||||
((inst_number - 1) * mult + k - 1) % net_mult + 1), 0, XDELETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my_free(_ALLOC_ID_, &pin_node);
|
||||
my_free(_ALLOC_ID_, &net_node);
|
||||
|
|
@ -545,10 +545,12 @@ void hilight_child_pins(void)
|
|||
int mult, net_mult, i, inst_number;
|
||||
|
||||
i = xctx->previous_instance[xctx->currsch-1];
|
||||
if(!xctx->hilight_nets) return;
|
||||
if(!xctx->hilight_nets) {
|
||||
return;
|
||||
}
|
||||
prepare_netlist_structs(0);
|
||||
rects = (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER];
|
||||
inst_number = xctx->sch_inst_number[xctx->currsch];
|
||||
inst_number = xctx->sch_inst_number[xctx->currsch-1];
|
||||
|
||||
/* may be set to -1 by descend_symbol to notify we are
|
||||
* descending into a smbol from an instance with no embed flag set
|
||||
|
|
|
|||
|
|
@ -4076,6 +4076,9 @@ void descend_symbol(void)
|
|||
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
|
||||
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], str);
|
||||
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch+1], ".");
|
||||
if(xctx->portmap[xctx->currsch + 1].table) str_hash_free(&xctx->portmap[xctx->currsch + 1]);
|
||||
str_hash_init(&xctx->portmap[xctx->currsch + 1], HASHSIZE);
|
||||
|
||||
xctx->sch_path_hash[xctx->currsch+1] = 0;
|
||||
my_free(_ALLOC_ID_, &str);
|
||||
|
||||
|
|
@ -4089,9 +4092,9 @@ void descend_symbol(void)
|
|||
/* use -1 to keep track we are descending into symbol from instance with no embed attr
|
||||
* we use this info to avoid asking to save parent schematic when returning from a symbol
|
||||
* created from a generator */
|
||||
xctx->sch_inst_number[xctx->currsch+1] = -1;
|
||||
xctx->sch_inst_number[xctx->currsch] = -1;
|
||||
else
|
||||
xctx->sch_inst_number[xctx->currsch+1] = 1; /* inst number we descend into. For symbol always 1 */
|
||||
xctx->sch_inst_number[xctx->currsch] = 1; /* inst number we descend into. For symbol always 1 */
|
||||
xctx->previous_instance[xctx->currsch]=n; /* instance we are descending from */
|
||||
|
||||
/* store previous zoom area */
|
||||
|
|
|
|||
|
|
@ -1950,6 +1950,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
load_schematic(load_symbols, f, undo_reset, !force);
|
||||
tclvareval("update_recent_file {", f, "}", NULL);
|
||||
my_strdup(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], ".");
|
||||
if(xctx->portmap[xctx->currsch].table) str_hash_free(&xctx->portmap[xctx->currsch]);
|
||||
str_hash_init(&xctx->portmap[xctx->currsch], HASHSIZE);
|
||||
xctx->sch_path_hash[xctx->currsch] = 0;
|
||||
xctx->sch_inst_number[xctx->currsch] = 1;
|
||||
if(nofullzoom) draw();
|
||||
|
|
@ -2732,11 +2734,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(!strcmp(argv[1], "rebuild_connectivity"))
|
||||
{
|
||||
int err = 0;
|
||||
int n = 1;
|
||||
if(argc > 2) n = atoi(argv[2]);
|
||||
xctx->prep_hash_inst=0;
|
||||
xctx->prep_hash_wires=0;
|
||||
xctx->prep_net_structs=0;
|
||||
xctx->prep_hi_structs=0;
|
||||
err |= prepare_netlist_structs(1);
|
||||
err |= prepare_netlist_structs(n);
|
||||
Tcl_SetResult(interp, my_itoa(err), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
|
|
@ -3689,7 +3693,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* testmode */
|
||||
else if(!strcmp(argv[1], "test"))
|
||||
{
|
||||
Str_hashentry *entry;
|
||||
int level;
|
||||
Tcl_ResetResult(interp);
|
||||
if(argc > 2) {
|
||||
const char *node = argv[2];
|
||||
level = xctx->currsch;
|
||||
while(level > 0) {
|
||||
entry = str_hash_lookup(&xctx->portmap[level], node, NULL, XLOOKUP);
|
||||
if(entry) node = entry->value;
|
||||
else break;
|
||||
level--;
|
||||
}
|
||||
Tcl_AppendResult(interp, node, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* toggle_colorscheme
|
||||
|
|
@ -4144,7 +4161,7 @@ int tclvareval(const char *script, ...)
|
|||
size = my_strcat(_ALLOC_ID_, &str, p);
|
||||
dbg(2, "tclvareval(): p=%s, str=%s, size=%d\n", p, str, size);
|
||||
}
|
||||
dbg(1, "tclvareval(): script=%s, str=%s, size=%d\n", script, str ? str : "<NULL>", size);
|
||||
dbg(2, "tclvareval(): script=%s, str=%s, size=%d\n", script, str ? str : "<NULL>", size);
|
||||
return_code = Tcl_EvalEx(interp, str, (int)size, TCL_EVAL_GLOBAL);
|
||||
va_end(args);
|
||||
if(return_code != TCL_OK) {
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ static void free_xschem_data()
|
|||
my_free(_ALLOC_ID_, &xctx->maxl);
|
||||
my_free(_ALLOC_ID_, &xctx->sel_array);
|
||||
for(i=0;i<CADMAXHIER; ++i) {
|
||||
if(xctx->portmap[i].table) str_hash_free(&xctx->portmap[i]);
|
||||
if(xctx->sch_path[i]) my_free(_ALLOC_ID_, &xctx->sch_path[i]);
|
||||
if(xctx->hier_attr[i].templ) my_free(_ALLOC_ID_, &xctx->hier_attr[i].templ);
|
||||
if(xctx->hier_attr[i].prop_ptr) my_free(_ALLOC_ID_, &xctx->hier_attr[i].prop_ptr);
|
||||
|
|
@ -541,8 +542,11 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
|
|||
xctx->hier_attr[i].templ = NULL;
|
||||
xctx->hier_attr[i].symname = NULL;
|
||||
xctx->hier_attr[i].fd = NULL;
|
||||
xctx->portmap[i].table = NULL;
|
||||
xctx->portmap[i].size = 0;
|
||||
}
|
||||
my_strdup(_ALLOC_ID_, &xctx->sch_path[0],".");
|
||||
|
||||
xctx->sch_inst_number[0] = 1;
|
||||
xctx->maxt=CADMAXTEXT;
|
||||
xctx->maxw=CADMAXWIRES;
|
||||
|
|
|
|||
|
|
@ -837,6 +837,7 @@ typedef struct {
|
|||
char current_name[PATH_MAX];
|
||||
char file_version[100];
|
||||
char *sch_path[CADMAXHIER];
|
||||
Str_hashtable portmap[CADMAXHIER];
|
||||
int sch_path_hash[CADMAXHIER]; /* cached hash of hierarchic schematic path for speed */
|
||||
int sch_inst_number[CADMAXHIER]; /* inst number descended into in case of vector instances X1[5:0] */
|
||||
int previous_instance[CADMAXHIER]; /* to remember the instance we came from when going up the hier. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue