From 9c29324c8a1e9cf700860d395b766f6d1293b006 Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Tue, 4 Oct 2022 12:34:09 +0200 Subject: [PATCH] allow nets with no label pass thru symbols with duplicated pins. named nets will propagate through duplicated pins --- src/actions.c | 1 + src/move.c | 1 + src/netlist.c | 121 ++++++++++++++++++++- src/save.c | 5 + src/scheduler.c | 1 + src/spice_netlist.c | 16 +-- src/verilog_netlist.c | 1 + src/vhdl_netlist.c | 1 + src/xinit.c | 2 + src/xschem.h | 1 + xschem_library/examples/test_doublepin.sch | 11 +- 11 files changed, 145 insertions(+), 16 deletions(-) diff --git a/src/actions.c b/src/actions.c index a10b4f01..9d7d0b9f 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1853,6 +1853,7 @@ void new_wire(int what, double mx_snap, double my_snap) { int big = xctx->wires> 2000 || xctx->instances > 2000 ; int s_pnetname; + xctx->hash_size = HASHSIZE; if( (what & PLACE) ) { s_pnetname = tclgetboolvar("show_pin_net_names"); if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) { diff --git a/src/move.c b/src/move.c index 0c5d58b1..0cb56596 100644 --- a/src/move.c +++ b/src/move.c @@ -492,6 +492,7 @@ void find_inst_to_be_redrawn(int what) int s_pnetname = tclgetboolvar("show_pin_net_names"); + xctx->hash_size = HASHSIZE; dbg(1,"find_inst_to_be_redrawn(): what=%d\n", what); if(what & 16) { my_free(1202, &xctx->inst_redraw_table); diff --git a/src/netlist.c b/src/netlist.c index 3d9a2439..eb84aff0 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -622,6 +622,123 @@ int record_global_node(int what, FILE *fp, char *node) return 0; } + +/* name nets that are attached to symbols with duplicated pins. + * if another duplicated pin is attached to a named net/label/pin get name from there */ +static void name_pass_through_nets() +{ + int i, j, rects, rot, flip, sqx, sqy, changed = 0; + double x0, y0, rx1, ry1; + char *type = NULL, *type2 = NULL; + xRect *rct; + Wireentry *wptr; + Instpinentry *iptr; + xInstance * const inst = xctx->inst; + int const instances = xctx->instances; + Str_hashentry *table[17]; + Str_hashentry *entry; + const char *pin_name; + + xctx->hash_size = 17; + do { /* keep looping until propagation of nets occurs */ + changed = 0; + memset(table, 0, xctx->hash_size * sizeof(Str_hashentry *)); + for (i=0;isym)->type); + if (type && !IS_LABEL_OR_PIN(type) ) { + if ((rects = (inst[i].ptr+ xctx->sym)->rects[PINLAYER]) > 0) { + /* 1st loop: hash symbol pins that are attached to named nets/pins/labels */ + for (j=0;jsym)->rect[PINLAYER]; + x0=(rct[j].x1+rct[j].x2)/2; + y0=(rct[j].y1+rct[j].y2)/2; + rot=inst[i].rot; + flip=inst[i].flip; + ROTATION(rot, flip, 0.0,0.0,x0,y0,rx1,ry1); + x0=inst[i].x0+rx1; + y0=inst[i].y0+ry1; + get_square(x0, y0, &sqx, &sqy); + pin_name = get_tok_value(rct[j].prop_ptr, "name", 0); + /* find attached nets */ + wptr = xctx->wire_spatial_table[sqx][sqy]; + while(wptr) { + if (touch(xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1, + xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) { + if(xctx->wire[wptr->n].node) { + dbg(1, "pin_name=%s, node=%s\n", pin_name, xctx->wire[wptr->n].node); + entry = str_hash_lookup(table, pin_name, xctx->wire[wptr->n].node, XINSERT_NOREPLACE); + if(entry) signal_short(xctx->wire[wptr->n].node, entry->value); + } + } + wptr=wptr->next; + } + /* find attached pins/labels */ + iptr=xctx->instpin_spatial_table[sqx][sqy]; + while (iptr) { + if (iptr->n == i || inst[iptr->n].ptr < 0) { + iptr=iptr->next; + continue; + } + my_strdup(1566, &type2, (inst[iptr->n].ptr + xctx->sym)->type); + if (!type2 || !IS_LABEL_OR_PIN(type2) ) { + iptr=iptr->next; + continue; + } + if ((iptr->x0==x0) && (iptr->y0==y0)) { + if(xctx->inst[iptr->n].node[0]) { + dbg(1, "pin_name=%s, node=%s\n", pin_name, xctx->inst[iptr->n].node[0]); + entry = str_hash_lookup(table, pin_name, xctx->inst[iptr->n].node[0], XINSERT_NOREPLACE); + if(entry) signal_short(xctx->inst[iptr->n].node[0], entry->value); + } + + } + iptr=iptr->next; + } + } /* for (j=0;jsym)->rect[PINLAYER]; + x0=(rct[j].x1+rct[j].x2)/2; + y0=(rct[j].y1+rct[j].y2)/2; + rot=inst[i].rot; + flip=inst[i].flip; + ROTATION(rot, flip, 0.0,0.0,x0,y0,rx1,ry1); + x0=inst[i].x0+rx1; + y0=inst[i].y0+ry1; + get_square(x0, y0, &sqx, &sqy); + wptr = xctx->wire_spatial_table[sqx][sqy]; + pin_name = get_tok_value(rct[j].prop_ptr, "name", 0); + while(wptr) { + if (touch(xctx->wire[wptr->n].x1, xctx->wire[wptr->n].y1, + xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) { + if(!xctx->wire[wptr->n].node) { /* net is unnamed */ + dbg(1, "lookup pin_name=%s\n", pin_name); + entry = str_hash_lookup(table, pin_name, NULL, XLOOKUP); + if(entry) { /* found duplicated pin */ + my_strdup(1568, &xctx->wire[wptr->n].node, entry->value); + my_strdup(1569, &xctx->wire[wptr->n].prop_ptr, + subst_token(xctx->wire[wptr->n].prop_ptr, "lab", entry->value)); + wirecheck(wptr->n); + changed = 1; + } + } + } + wptr=wptr->next; + } + } /* for (j=0;jsym)->rects[PINLAYER]) > 0) */ + } /* if (type && !IS_LABEL_OR_PIN(type) ) */ + str_hash_free(table); + } /* for (i=0;ihash_size = HASHSIZE; +} + + void prepare_netlist_structs(int for_netlist) { xRect *rct; @@ -669,7 +786,7 @@ void prepare_netlist_structs(int for_netlist) statusmsg(nn,2); } /* reset wire & inst node labels */ - dbg(2, "prepare_netlist_structs(): rehashing wires and instances in spatial hash table\n"); + dbg(2, "prepare_netlist_structs(): rehashing wires and instance pins in spatial hash table\n"); hash_wires(); for (i=0;ihash_size = HASHSIZE; memset(table, 0, HASHSIZE * sizeof(Int_hashentry *)); for(i = 0; i < xctx->instances; i++) { dbg(1, "instance:%s: %s\n", xctx->inst[i].instname, xctx->inst[i].name); diff --git a/src/save.c b/src/save.c index 2d325c0d..24923bc2 100644 --- a/src/save.c +++ b/src/save.c @@ -304,6 +304,7 @@ static int read_dataset(FILE *fd, const char *type) int n = 0, done_header = 0, ac = 0; int exit_status = 0, npoints, nvars; int dbglev=1; + xctx->hash_size = HASHSIZE; xctx->graph_sim_type = NULL; dbg(1, "read_dataset(): type=%s\n", type ? type : ""); while((fgets(line, sizeof(line), fd)) ) { @@ -476,6 +477,7 @@ void free_rawfile(int dr) int i; int deleted = 0; + xctx->hash_size = HASHSIZE; if(xctx->graph_names) { deleted = 1; for(i = 0 ; i < xctx->graph_nvars; i++) { @@ -606,6 +608,7 @@ int get_raw_index(const char *node) dbg(1, "get_raw_index(): node=%s\n", node); + xctx->hash_size = HASHSIZE; if(sch_waves_loaded() >= 0) { my_strncpy(inode, node, S(inode)); strtolower(inode); @@ -2450,6 +2453,7 @@ static void get_sym_type(const char *symname, char **type, FILE *fd; char tag[1]; int found = 0; + xctx->hash_size = HASHSIZE; if(!strcmp(xctx->file_version,"1.0")) { my_strncpy(name, abs_sym_path(symname, ".sym"), S(name)); } else { @@ -2548,6 +2552,7 @@ static void align_sch_pins_with_sym(const char *name, int pos) int i, fail = 0, sym_n_pins=0; Int_hashentry *pintable[HASHSIZE]; + xctx->hash_size = HASHSIZE; if ((ptr = strrchr(name, '.')) && !strcmp(ptr, ".sch")) { my_strncpy(symname, add_ext(name, ".sym"), S(symname)); memset(pintable, 0, HASHSIZE * sizeof(Int_hashentry *)); diff --git a/src/scheduler.c b/src/scheduler.c index 05698b3e..6bfd1d71 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -2098,6 +2098,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg /* xschem rawfile_query index v(ldcp) */ Int_hashentry *entry; int idx; + xctx->hash_size = HASHSIZE; entry = int_hash_lookup(xctx->graph_raw_table, argv[3], 0, XLOOKUP); idx = entry ? entry->value : -1; Tcl_SetResult(interp, my_itoa(idx), TCL_VOLATILE); diff --git a/src/spice_netlist.c b/src/spice_netlist.c index a57ca956..88c4de98 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -33,6 +33,7 @@ void hier_psprint(void) /* netlister driver */ char filename[PATH_MAX]; char *abs_path = NULL; + xctx->hash_size = HASHSIZE; if(!ps_draw(1)) return; /* prolog */ xctx->push_undo(); str_hash_free(subckt_table); @@ -111,7 +112,8 @@ static void spice_netlist(FILE *fd, int spice_stop ) int i, flag = 0; char *type=NULL; int top_sub; - + + xctx->hash_size = HASHSIZE; top_sub = tclgetboolvar("top_subckt"); if(!spice_stop) { xctx->prep_net_structs = 0; @@ -197,6 +199,7 @@ void global_spice_netlist(int global) /* netlister driver */ int top_sub; int split_f; + xctx->hash_size = HASHSIZE; split_f = tclgetboolvar("split_files"); top_sub = tclgetboolvar("top_subckt"); xctx->push_undo(); @@ -435,7 +438,7 @@ void global_spice_netlist(int global) /* netlister driver */ } /* print device_model attributes */ - for(i=0;ihash_size; i++) { model_entry=model_table[i]; while(model_entry) { if(first == 0) fprintf(fd,"**** begin user architecture code\n"); @@ -568,7 +571,7 @@ Str_hashentry *str_hash_lookup(Str_hashentry **table, const char *token, const c if(token==NULL) return NULL; hashcode=str_hash(token); - idx=hashcode % HASHSIZE; + idx=hashcode % xctx->hash_size; entry=table[idx]; preventry=&table[idx]; while(1) @@ -626,7 +629,7 @@ void str_hash_free(Str_hashentry **table) { int i; - for(i=0;ihash_size;i++) { str_hash_free_entry( table[i] ); table[i] = NULL; @@ -635,7 +638,6 @@ void str_hash_free(Str_hashentry **table) /* GENERIC PURPOSE INT HASH TABLE */ - /* token value what ... what ... * -------------------------------------------------------------------------- * "whatever" "whatever" XINSERT insert in hash table if not in. @@ -655,7 +657,7 @@ Int_hashentry *int_hash_lookup(Int_hashentry **table, const char *token, const i if(token==NULL) return NULL; hashcode=str_hash(token); - idx=hashcode % HASHSIZE; + idx=hashcode % xctx->hash_size; entry=table[idx]; preventry=&table[idx]; while(1) @@ -710,7 +712,7 @@ void int_hash_free(Int_hashentry **table) { int i; - for(i=0;ihash_size;i++) { int_hash_free_entry( table[i] ); table[i] = NULL; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 3ac8a909..996d7c85 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -92,6 +92,7 @@ void global_verilog_netlist(int global) /* netlister driver */ int split_f; const char *fmt_attr = NULL; + xctx->hash_size = HASHSIZE; split_f = tclgetboolvar("split_files"); xctx->push_undo(); xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */ diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 6bc6c52e..43dcb83c 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -130,6 +130,7 @@ void global_vhdl_netlist(int global) /* netlister driver */ char *abs_path = NULL; int split_f; + xctx->hash_size = HASHSIZE; split_f = tclgetboolvar("split_files"); xctx->push_undo(); xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */ diff --git a/src/xinit.c b/src/xinit.c index 6586a63a..9b48a96f 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -470,6 +470,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->need_reb_sel_arr = 1; xctx->lastsel = 0; xctx->maxsel = 0; + xctx->hash_size = HASHSIZE; xctx->prep_net_structs = 0; xctx->prep_hi_structs = 0; xctx->simdata = NULL; @@ -672,6 +673,7 @@ int compare_schematics(const char *f) int ret=0; /* ret==0 means no differences found */ Xschem_ctx *save_xctx; + xctx->hash_size = HASHSIZE; memset(table1, 0, HASHSIZE * sizeof(Int_hashentry *)); memset(table2, 0, HASHSIZE * sizeof(Int_hashentry *)); diff --git a/src/xschem.h b/src/xschem.h index a4a0982f..23ecda3c 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -770,6 +770,7 @@ typedef struct { int need_reb_sel_arr; int lastsel; int maxsel; + int hash_size; /* used in str_hash_lookup and int_hash_lookup */ Selected *sel_array; int prep_net_structs; int prep_hi_structs; diff --git a/xschem_library/examples/test_doublepin.sch b/xschem_library/examples/test_doublepin.sch index 0230bbbd..423613ac 100644 --- a/xschem_library/examples/test_doublepin.sch +++ b/xschem_library/examples/test_doublepin.sch @@ -1,4 +1,5 @@ -v {xschem version=3.0.0 file_version=1.2 } +v {xschem version=3.1.0 file_version=1.2 +} G {} K {} V { @@ -23,17 +24,11 @@ vvss vss 0 dc 0 .tran 1n 200n} E {} -L 5 130 -460 910 -270 {} -L 5 160 -270 950 -470 {} -P 5 7 530 -390 525 -380 530 -380 530 -240 530 -380 535 -380 530 -390 {} -P 5 7 100 -375 95 -365 100 -365 100 -240 100 -365 105 -365 100 -375 {} -T {WRONG!} 410 -490 0 0 1 1 {layer=5} T {OK!} 470 -750 0 0 1 1 {layer=4} T {OK!} 470 -1010 0 0 1 1 {layer=4} T {OK!} 470 -1260 0 0 1 1 {layer=4} T {Spice netlist allows duplicated pins on symbols} 20 -1350 0 0 1 1 {} -T {if connecting both duplicated pins you should name the nets otherwise -xschem might pick 'net2' instead of 'CCKK'} 50 -230 0 0 0.5 0.5 {layer=5} +T {OK!} 470 -490 0 0 1 1 {layer=4} N 450 -660 600 -660 { lab=RRSSTT} N 450 -640 600 -640 {