diff --git a/src/netlist.c b/src/netlist.c index 5297f529..ad604d81 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -803,6 +803,7 @@ void prepare_netlist_structs(int for_netlist) } /* if(type && ... */ } /* for(i=0;iprep_net_structs=1; xctx->prep_hi_structs=1; } else xctx->prep_hi_structs=1; - my_free(835, &dir); my_free(836, &type); my_free(837, &sig_type); @@ -1046,6 +1046,102 @@ void prepare_netlist_structs(int for_netlist) /* propagate_hilights(1, 0, XINSERT_NOREPLACE);*/ } + +static int double_hash(double e) +{ + union { + double a; + struct { + int a; + int b; + } i; + } x; + + /* Make both representations of 0.0 hash to the same value + * 0.0 and -0.0 + * Since -0.0 has a different binary representation than 0.0 + * And 0.0 == -0.0 is always true + */ + if (e == 0.0) e = 0.0; /* if e == -0.0, now it is 0.0 */ + + x.a = e; + return 5381 + (x.i.a << 5) + x.i.b; +} +int warning_overlapped_symbols() +{ + int i; + Int_hashentry *table[HASHSIZE]; + int hash; + Int_hashentry *found; + char str[2048]; + + memset(table, 0, HASHSIZE * sizeof(Int_hashentry *)); + for(i = 0; i < xctx->instances; i++) { + hash = 5381; + dbg(1, "instance:%s: %s\n", xctx->inst[i].instname, xctx->inst[i].name); + hash += (hash << 5) + double_hash(xctx->inst[i].xx1); + hash += (hash << 5) + double_hash(xctx->inst[i].yy1); + hash += (hash << 5) + double_hash(xctx->inst[i].xx2); + hash += (hash << 5) + double_hash(xctx->inst[i].yy2); + dbg(1, "bbox: %g %g %g %g\n", xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2); + dbg(1, " hash=%d\n", hash); + found = int_hash_lookup(table, my_itoa(hash), 1, XINSERT_NOREPLACE); + if(found) { + xctx->inst[i].color = -PINLAYER; + xctx->hilight_nets=1; + my_snprintf(str, S(str), "Warning: overlapped instance found: %s(%s)\n", + xctx->inst[i].instname, xctx->inst[i].name); + statusmsg(str,2); + tcleval("show_infotext"); /* critical error: force ERC window showing */ + + + } + } + int_hash_free(table); + return 0; +} + + +int xxwarning_overlapped_symbols() +{ + int i, j, rects; + xSymbol *sym; + xRect *rct; + double x0, y0, px0, py0, rpx0, rpy0; + int symrot, symflip; + Int_hashentry *table[HASHSIZE]; + int hash; + Int_hashentry *found; + + memset(table, 0, HASHSIZE * sizeof(Int_hashentry *)); + for(i = 0; i < xctx->instances; i++) { + sym = xctx->inst[i].ptr+ xctx->sym; + rct=sym->rect[PINLAYER]; + x0 = xctx->inst[i].x0; + y0 = xctx->inst[i].y0; + symrot = xctx->inst[i].rot; + symflip = xctx->inst[i].flip; + rects = sym->rects[PINLAYER]; + hash = 5381; + dbg(0, "instance:%s\n", xctx->inst[i].instname); + for(j = 0; j < rects; j++) { + px0 = (rct[j].x1+rct[j].x2)/2; + py0 = (rct[j].y1+rct[j].y2)/2; + ROTATION(symrot, symflip, 0.0,0.0,px0,py0,rpx0,rpy0); + rpx0 += x0; + rpy0 += y0; + hash += (hash << 5) + double_hash(rpx0); + hash += (hash << 5) + double_hash(rpy0); + dbg(0, " rpx0=%g rpy0=%g\n", rpx0, rpy0); + } + dbg(0, " hash=%d\n", hash); + found = int_hash_lookup(table, xctx->inst[i].instname, hash, XINSERT_NOREPLACE); + if(found) dbg(0, "Warning: overlapped instance found: %d\n", i); + } + int_hash_free(table); + return 0; +} + int sym_vs_sch_pins() { char **lab_array =NULL; diff --git a/src/save.c b/src/save.c index 571a3528..914c668a 100644 --- a/src/save.c +++ b/src/save.c @@ -1970,6 +1970,8 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 if(xctx->hilight_nets && load_symbols) { propagate_hilights(1, 1, XINSERT_NOREPLACE); } + /* warning if two symbols perfectly overlapped */ + warning_overlapped_symbols(); } void clear_undo(void) diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 5534079b..71ce6c6a 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -337,6 +337,8 @@ void global_spice_netlist(int global) /* netlister driver */ if(debug_var==0) xunlink(netl_filename); } + /* warning if two symbols perfectly overlapped */ + warning_overlapped_symbols(); /* preserve current level instance flags before descending hierarchy for netlisting, restore later */ stored_flags = my_calloc(146, xctx->instances, sizeof(unsigned int)); for(i=0;iinstances;i++) stored_flags[i] = xctx->inst[i].color; diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index 6d26c8dd..0bbb1074 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -172,6 +172,8 @@ void global_tedax_netlist(int global) /* netlister driver */ fprintf(fd, "end netlist\n"); + /* warning if two symbols perfectly overlapped */ + warning_overlapped_symbols(); /* preserve current level instance flags before descending hierarchy for netlisting, restore later */ stored_flags = my_calloc(149, xctx->instances, sizeof(unsigned int)); for(i=0;iinstances;i++) stored_flags[i] = xctx->inst[i].color; @@ -238,4 +240,3 @@ void global_tedax_netlist(int global) /* netlister driver */ xctx->netlist_count = 0; } - diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 8cb90f81..c266184c 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -324,6 +324,8 @@ void global_verilog_netlist(int global) /* netlister driver */ if(debug_var==0) xunlink(netl_filename); } + /* warning if two symbols perfectly overlapped */ + warning_overlapped_symbols(); /* preserve current level instance flags before descending hierarchy for netlisting, restore later */ stored_flags = my_calloc(150, xctx->instances, sizeof(unsigned int)); for(i=0;iinstances;i++) stored_flags[i] = xctx->inst[i].color; diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index fbe9fa81..ef771868 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -419,6 +419,8 @@ void global_vhdl_netlist(int global) /* netlister driver */ } xctx->netlist_count++; + /* warning if two symbols perfectly overlapped */ + warning_overlapped_symbols(); /* preserve current level instance flags before descending hierarchy for netlisting, restore later */ stored_flags = my_calloc(151, xctx->instances, sizeof(unsigned int)); for(i=0;iinstances;i++) stored_flags[i] = xctx->inst[i].color; diff --git a/src/xschem.h b/src/xschem.h index f16ab503..3a150104 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1365,6 +1365,7 @@ extern void display_hilights(char **str); extern void redraw_hilights(int clear); extern void set_tcl_netlist_type(void); extern void prepare_netlist_structs(int for_netlist); +extern int warning_overlapped_symbols(); extern void free_simdata(void); extern void delete_netlist_structs(void); extern void delete_inst_node(int i);