Catch duplicate $dumpvars of symbols (ajb)

This commit is contained in:
steve 2000-04-09 04:18:16 +00:00
parent f6959ba09e
commit 7307deb3a9
1 changed files with 100 additions and 4 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) && !defined(macintosh) #if !defined(WINNT) && !defined(macintosh)
#ident "$Id: sys_vcd.c,v 1.8 2000/04/08 05:28:39 steve Exp $" #ident "$Id: sys_vcd.c,v 1.9 2000/04/09 04:18:16 steve Exp $"
#endif #endif
/* /*
@ -39,6 +39,7 @@ struct vcd_info {
vpiHandle cb; vpiHandle cb;
struct t_vpi_time time; struct t_vpi_time time;
char*ident; char*ident;
char*fullname;
struct vcd_info*next; struct vcd_info*next;
}; };
@ -63,6 +64,26 @@ static void gen_new_vcd_id(void)
static struct vcd_info*vcd_list = 0; static struct vcd_info*vcd_list = 0;
unsigned long vcd_cur_time = 0; unsigned long vcd_cur_time = 0;
static char *truncate_bitvec(char *s)
{
char l, r;
r=*s;
if(r=='1')
return s;
else
s += 1;
for(;;s++) {
l=r; r=*s;
if(!r) return (s-1);
if(l!=r)
return(((l=='0')&&(r='1'))?s:s-1);
}
}
static void show_this_item(struct vcd_info*info) static void show_this_item(struct vcd_info*info)
{ {
s_vpi_value value; s_vpi_value value;
@ -74,7 +95,67 @@ static void show_this_item(struct vcd_info*info)
} else { } else {
value.format = vpiBinStrVal; value.format = vpiBinStrVal;
vpi_get_value(info->item, &value); vpi_get_value(info->item, &value);
fprintf(dump_file, "b%s %s\n", value.value.str, info->ident); fprintf(dump_file, "b%s %s\n",
truncate_bitvec(value.value.str),
info->ident);
}
}
/*
* managed qsorted list of vcd_info structs for duplicates bsearching
*/
static int nident=0, old_nident=0;
static struct vcd_info **vcd_info_name_sorted=NULL;
static int vcd_info_name_bsearch_compare(const void *s1, const void *s2)
{
char *v1;
struct vcd_info *v2;
v1=(char *)s1;
v2=*((struct vcd_info **)s2);
return(strcmp(v1, v2->fullname));
}
static struct vcd_info *bsearch_vcd_info(char *key)
{
struct vcd_info **v;
v=(struct vcd_info **)bsearch(key, vcd_info_name_sorted, old_nident,
sizeof(struct vcd_info *), vcd_info_name_bsearch_compare);
return(v ? (*v) : NULL);
}
static int vcd_info_name_compare(const void *s1, const void *s2)
{
struct vcd_info *v1, *v2;
v1=*((struct vcd_info **)s1);
v2=*((struct vcd_info **)s2);
return(strcmp(v1->fullname, v2->fullname));
}
void vcd_info_post_process(void)
{
if(nident) {
struct vcd_info **l, *r;
if (vcd_info_name_sorted) free(vcd_info_name_sorted);
old_nident+=nident;
nident=0;
l=vcd_info_name_sorted=(struct vcd_info **)malloc(old_nident*(sizeof(struct vcd_info *)));
r=vcd_list;
while(r) {
*(l++)=r;
r=r->next;
}
qsort(vcd_info_name_sorted, old_nident, sizeof(struct vcd_info *), vcd_info_name_compare);
} }
} }
@ -192,10 +273,15 @@ static void scan_scope(unsigned depth, vpiHandle argv)
for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) { for (item = vpi_scan(argv) ; item ; item = vpi_scan(argv)) {
const char*type; const char*type;
char*fullname;
switch (vpi_get(vpiType, item)) { switch (vpi_get(vpiType, item)) {
case vpiNet: case vpiNet:
case vpiReg: case vpiReg:
fullname=vpi_get_str(vpiFullName, item);
if((old_nident)&&(fullname)&&(bsearch_vcd_info(fullname)))
continue;
type = "wire"; type = "wire";
if (vpi_get(vpiType, item) == vpiReg) if (vpi_get(vpiType, item) == vpiReg)
type = "reg"; type = "reg";
@ -207,19 +293,23 @@ static void scan_scope(unsigned depth, vpiHandle argv)
cb.obj = item; cb.obj = item;
info->item = item; info->item = item;
info->ident = strdup(vcdid); info->ident = strdup(vcdid);
info->fullname = fullname;
info->cb = vpi_register_cb(&cb); info->cb = vpi_register_cb(&cb);
info->next = vcd_list; info->next = vcd_list;
vcd_list = info; vcd_list = info;
fprintf(dump_file, "$var %s %u %s %s $end\n", fprintf(dump_file, "$var %s %u %s %s $end\n",
type, vpi_get(vpiSize, item), info->ident, type, vpi_get(vpiSize, item), info->ident,
vpi_get_str(vpiFullName, item)); info->fullname);
gen_new_vcd_id(); gen_new_vcd_id();
nident += 1;
break; break;
case vpiModule: case vpiModule:
sublist = vpi_iterate(vpiInternalScope, item); sublist = vpi_iterate(vpiInternalScope, item);
if (sublist && (depth > 0)) if (sublist && (depth > 0)) {
vcd_info_post_process();
scan_scope(depth-1, sublist); scan_scope(depth-1, sublist);
}
break; break;
default: default:
@ -227,6 +317,9 @@ static void scan_scope(unsigned depth, vpiHandle argv)
} }
} }
/* close + sort this level so parent collisions are found */
vcd_info_post_process();
} }
static int sys_dumpvars_calltf(char*name) static int sys_dumpvars_calltf(char*name)
@ -288,6 +381,9 @@ void sys_vcd_register()
/* /*
* $Log: sys_vcd.c,v $ * $Log: sys_vcd.c,v $
* Revision 1.9 2000/04/09 04:18:16 steve
* Catch duplicate $dumpvars of symbols (ajb)
*
* Revision 1.8 2000/04/08 05:28:39 steve * Revision 1.8 2000/04/08 05:28:39 steve
* Revamped VCD id generation and duplicates removal. (ajb) * Revamped VCD id generation and duplicates removal. (ajb)
* *