allow nets with no label pass thru symbols with duplicated pins. named nets will propagate through duplicated pins

This commit is contained in:
Stefan Frederik 2022-10-04 12:34:09 +02:00
parent 2e4d1e39a1
commit 9c29324c8a
11 changed files with 145 additions and 16 deletions

View File

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

View File

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

View File

@ -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;i<instances;i++) {
dbg(1, "instance %d: %s\n", i, inst[i].instname);
if(inst[i].ptr<0) continue;
my_strdup(1565, &type, (inst[i].ptr + xctx->sym)->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;j<rects;j++) {
rct=(inst[i].ptr+ xctx->sym)->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;j<rects;j++) */
/* 2nd loop: if unnamed nets, get name from duplicated pins */
for (j=0;j<rects;j++) {
rct=(inst[i].ptr+ xctx->sym)->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;j<rects;j++) */
} /* if ((rects = (inst[i].ptr+ xctx->sym)->rects[PINLAYER]) > 0) */
} /* if (type && !IS_LABEL_OR_PIN(type) ) */
str_hash_free(table);
} /* for (i=0;i<instances;i++) */
} while(changed);
my_free(1570, &type);
my_free(1571, &type2);
xctx->hash_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;i<instances;i++)
{
@ -810,6 +927,7 @@ void prepare_netlist_structs(int for_netlist)
} /* if(type && ... */
} /* for(i=0;i<instances... */
name_pass_through_nets(); /* name nets that are attached to symbols with duplicated pins. */
/* name nets that do not touch ipin opin alias instances */
dbg(2, "prepare_netlist_structs(): naming nets that dont touch labels\n");
@ -1061,6 +1179,7 @@ int warning_overlapped_symbols(int sel)
char str[2048];
char s[512];
xctx->hash_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);

View File

@ -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 : "<NULL>");
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 *));

View File

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

View File

@ -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;i<HASHSIZE; i++) {
for(i=0;i<xctx->hash_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;i<HASHSIZE;i++)
for(i=0;i<xctx->hash_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;i<HASHSIZE;i++)
for(i=0;i<xctx->hash_size;i++)
{
int_hash_free_entry( table[i] );
table[i] = NULL;

View File

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

View File

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

View File

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

View File

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

View File

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