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:
stefan schippers 2023-05-26 11:56:52 +02:00
parent 970c8597f6
commit 09a373954f
6 changed files with 85 additions and 23 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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 */

View File

@ -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) {

View File

@ -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;

View File

@ -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. */