/* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; struct vcdsymbol *root_v; int i; if(numsyms) { vcd_distance = vcd_maxid - vcd_minid + 1; if(vcd_distance <= 8 * 1024 * 1024) { indexed = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); v=vcdsymroot; while(v) { if(!(root_v=indexed[v->nid - vcd_minid])) { indexed[v->nid - vcd_minid] = v; } alias_vs_normal_symadd(v, root_v); v=v->next; } } else { pnt=sorted=(struct vcdsymbol **)calloc_2(numsyms, sizeof(struct vcdsymbol *)); v=vcdsymroot; while(v) { *(pnt++)=v; v=v->next; } qsort(sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymcompare); root_v = NULL; for(i=0;i<numsyms;i++) { if(sorted[i] != root_v) root_v = NULL; alias_vs_normal_symadd(sorted[i], root_v); } } v=vcdsymroot; while(v) { free(v->name); v->name = NULL; v=v->next; } } }
void init_filetrans_data(void) { int i; if(!GLOBALS->filesel_filter) { GLOBALS->filesel_filter = calloc_2(FILE_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->xl_file_filter) { GLOBALS->xl_file_filter = calloc_2(FILE_FILTER_MAX+1, sizeof(struct xl_tree_node *)); } for(i=0;i<FILE_FILTER_MAX+1;i++) { GLOBALS->filesel_filter[i] = NULL; GLOBALS->xl_file_filter[i] = NULL; } }
void init_proctrans_data(void) { int i; if(!GLOBALS->procsel_filter) { GLOBALS->procsel_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->proc_filter) { GLOBALS->proc_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(struct pipe_ctx *)); } for(i=0;i<PROC_FILTER_MAX+1;i++) { GLOBALS->procsel_filter[i] = NULL; GLOBALS->proc_filter[i] = NULL; } }
void init_ttrans_data(void) { int i; if(!GLOBALS->ttranssel_filter) { GLOBALS->ttranssel_filter = calloc_2(TTRANS_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->ttrans_filter) { GLOBALS->ttrans_filter = calloc_2(TTRANS_FILTER_MAX+1, sizeof(struct pipe_ctx *)); } for(i=0;i<TTRANS_FILTER_MAX+1;i++) { GLOBALS->ttranssel_filter[i] = NULL; GLOBALS->ttrans_filter[i] = NULL; } }
static struct font_engine_font_t *do_font_load(const char *name) { struct font_engine_font_t *fef = NULL; PangoFontDescription *desc; if( (name) && (desc = pango_font_description_from_string(name)) ) { fef = calloc_2(1, sizeof(struct font_engine_font_t)); fef->desc = desc; fef->font = pango_font_map_load_font( pango_cairo_font_map_get_default(), GLOBALS->fonts_context, fef->desc); fef->metrics=pango_font_get_metrics(fef->font, NULL /*pango_language_get_default()*/ ); fef->ascent = pango_font_metrics_get_ascent(fef->metrics) / 1000; fef->descent = pango_font_metrics_get_descent(fef->metrics) / 1000; fef->is_pango = 1; if(!strncmp(name, "Monospace", 9)) { int i_width = font_engine_string_measure(fef, "i"); fef->mono_width = font_engine_string_measure(fef, "O"); fef->is_mono = (i_width == fef->mono_width); } } return(fef); }
/* * Adds a vector to the display... */ int AddVector( bvptr vec ) { Trptr t; int n; if(!vec) return(0); /* must've passed it a null pointer by mistake */ signalwindow_width_dirty=1; n = vec->nbits; t = (Trptr) calloc_2(1, sizeof( TraceEnt ) ); if( t == NULL ) { fprintf( stderr, "Out of memory, can't add %s to analyzer\n", vec->name ); return( 0 ); } if(!hier_max_level) { t->name = vec->name; } else { t->name = hier_extract(vec->name, hier_max_level); } t->flags = ( n > 3 ) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; t->vector = TRUE; t->n.vec = vec; AddTrace( t ); return( 1 ); }
/* * hash create/destroy */ void sym_hash_initialize(void *g) { #ifdef _WAVE_HAVE_JUDY ((struct Global *)g)->sym_judy = NULL; #else ((struct Global *)g)->sym_hash=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); #endif }
struct tree *talloc_2(size_t siz) { if(GLOBALS->talloc_pool_base) { if((siz + GLOBALS->talloc_idx) <= WAVE_TALLOC_POOL_SIZE) { unsigned char *m = GLOBALS->talloc_pool_base + GLOBALS->talloc_idx; GLOBALS->talloc_idx += siz; return((struct tree *)m); } else if(siz >= WAVE_TALLOC_ALTREQ_SIZE) { return(calloc_2(1, siz)); } } GLOBALS->talloc_pool_base = calloc_2(1, WAVE_TALLOC_POOL_SIZE); GLOBALS->talloc_idx = 0; return(talloc_2(siz)); }
static void *adb_alloc_2(size_t siz) { if(GLOBALS->adb_alloc_pool_base) { if((siz + GLOBALS->adb_alloc_idx) <= WAVE_ADB_ALLOC_POOL_SIZE) { unsigned char *m = GLOBALS->adb_alloc_pool_base + GLOBALS->adb_alloc_idx; GLOBALS->adb_alloc_idx += siz; return((void *)m); } else if(siz >= WAVE_ADB_ALLOC_ALTREQ_SIZE) { return(calloc_2(1, siz)); } } GLOBALS->adb_alloc_pool_base = calloc_2(1, WAVE_ADB_ALLOC_POOL_SIZE); GLOBALS->adb_alloc_idx = 0; return(adb_alloc_2(siz)); }
/* * Free up a trace's mallocs... */ void FreeTrace(Trptr t) { if(straces) { struct strace_defer_free *sd = calloc_2(1, sizeof(struct strace_defer_free)); sd->next = strace_defer_free_head; sd->defer = t; strace_defer_free_head = sd; return; } if(t->vector) { bvptr bv; int i; bv=t->n.vec; for(i=0;i<bv->numregions;i++) { if(bv->vectors[i]) free_2(bv->vectors[i]); } if(bv->bits) { if(bv->bits->name) free_2(bv->bits->name); for(i=0;i<bv->nbits;i++) { DeleteNode(bv->bits->nodes[i]); } free_2(bv->bits); } if(bv->name) free_2(bv->name); if(t->n.vec)free_2(t->n.vec); } else { if(t->n.nd && t->n.nd->expansion) { DeleteNode(t->n.nd); } } if(t->asciivalue) free_2(t->asciivalue); if((t->is_alias)&&(t->name)) free_2(t->name); free_2( t ); }
/* * Add a blank trace to the display... */ static char *precondition_string(char *s) { int len=0; char *s2; if(!s) return(NULL); s2=s; while((*s2)&&((*s2)!='\n')&&((*s2)!='\r')) /* strip off ending CR/LF */ { len++; s2++; } if(!len) return(NULL); s2=(char *)calloc_2(1,len+1); memcpy(s2,s,len); return(s2); }
static struct font_engine_font_t *font_engine_gdk_font_load(const char *string) { GdkFont *f = gdk_font_load(string); if(f) { struct font_engine_font_t *fef = calloc_2(1, sizeof(struct font_engine_font_t)); fef->gdkfont = f; fef->ascent = f->ascent; fef->descent = f->descent; return(fef); } else { return(NULL); } }
/* * Insert a blank [or comment] trace into the display... */ int InsertBlankTrace(char *comment) { TempBuffer tb; char *comm; Trptr t; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't insert blank trace to analyzer\n"); return( 0 ); } t->flags=TR_BLANK; if((comm=precondition_string(comment))) { t->name=comm; t->is_alias=1; } if(!traces.first) { traces.first=traces.last=t; traces.total=1; return(1); } else { tb.buffer=traces.buffer; tb.bufferlast=traces.bufferlast; tb.buffercount=traces.buffercount; traces.buffer=traces.bufferlast=t; traces.buffercount=1; PasteBuffer(); traces.buffer=tb.buffer; traces.bufferlast=tb.bufferlast; traces.buffercount=tb.buffercount; return(1); } }
int AddBlankTrace(char *commentname) { Trptr t; char *comment; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add blank trace to analyzer\n"); return( 0 ); } AddTrace(t); t->flags=TR_BLANK; if((comment=precondition_string(commentname))) { t->name=comment; t->is_alias=1; } return(1); }
void append_vcd_slisthier(char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); }
/* * pre-import many traces at once so function above doesn't have to iterate... */ void ae2_set_fac_process_mask(nptr np) { AE2_FACREF *f; int txidx; int r, nr; if(!(f=(AE2_FACREF *)(np->mv.mvlfac))) return; /* already imported */ txidx = f - GLOBALS->ae2_fr; if((1)||(f->row <= 1)) /* sorry, arrays not supported */ { aet2_rd_set_fac_process_mask(txidx); nr = f->row; if(!nr) nr=1; GLOBALS->ae2_lx2_table[txidx] = calloc_2(nr, sizeof(struct lx2_entry)); for(r=0;r<nr;r++) { GLOBALS->ae2_lx2_table[txidx][r].np = &np[r]; } } }
xl_Tree * xl_insert(char *i, xl_Tree * t, char *trans) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ xl_Tree * n; int dir; n = (xl_Tree *) calloc_2(1, sizeof (xl_Tree)); if (n == NULL) { fprintf(stderr, "xl_insert: ran out of memory, exiting.\n"); exit(255); } n->item = strcpy(malloc_2(strlen(i)+1), i); if(trans) n->trans = strcpy(malloc_2(strlen(trans)+1), trans); if (t == NULL) { n->left = n->right = NULL; return n; } t = xl_splay(i,t); dir = strcasecmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ if(n->trans) free_2(n->trans); free_2(n->item); free_2(n); return t; } }
/* * Add a trace to the display... */ static void AddTrace( Trptr t ) { if(default_flags&TR_NUMMASK) t->flags=default_flags; else t->flags=(t->flags&TR_NUMMASK)|default_flags; if(shift_timebase_default_for_add) t->shift=shift_timebase_default_for_add; if(!shadow_active) { if( traces.first == NULL ) { t->next = t->prev = NULL; traces.first = traces.last = t; } else { t->next = NULL; t->prev = traces.last; traces.last->next = t; traces.last = t; } traces.total++; } else /* hide offscreen */ { struct strace *st = calloc_2(1, sizeof(struct strace)); st->next = shadow_straces; st->value = shadow_type; st->trace = t; st->string = shadow_string; /* copy string over */ shadow_string = NULL; shadow_straces = st; } }
static vcdsav_Tree * vcdsav_insert(void *i, vcdsav_Tree * t, int val, unsigned char flags, hptr h) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ vcdsav_Tree * n; int dir; n = (vcdsav_Tree *) calloc_2(1, sizeof (vcdsav_Tree)); if (n == NULL) { fprintf(stderr, "vcdsav_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; n->flags = flags; n->hist = h; if (t == NULL) { n->left = n->right = NULL; return n; } t = vcdsav_splay(i,t); dir = vcdsav_cmp_l(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free_2(n); return t; } }
static ghw_Tree * ghw_insert(void *i, ghw_Tree * t, int val, struct symbol *sym) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ ghw_Tree * n; int dir; n = (ghw_Tree *) calloc_2(1, sizeof (ghw_Tree)); if (n == NULL) { fprintf(stderr, "ghw_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val_old = val; n->sym = sym; if (t == NULL) { n->left = n->right = NULL; return n; } t = ghw_splay(i,t); dir = ghw_cmp_l(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free_2(n); return t; } }
/* * mainline */ TimeType ae2_main(char *fname, char *skip_start, char *skip_end) { int i; int match_idx; struct Node *n; struct symbol *s; TimeType first_cycle, last_cycle /* , total_cycles */; /* scan-build */ int total_rows = 0; int mono_row_offset = 0; struct Node *monolithic_node = NULL; struct symbol *monolithic_sym = NULL; #ifdef AET2_ALIASDB_IS_PRESENT unsigned long kw = 0; unsigned char *missing = NULL; #endif char buf[AE2_MAX_NAME_LENGTH+1]; ae2_read_set_max_section_cycle(65536); ae2_initialize(error_fn, msg_fn, alloc_fn, free_fn); if ( (!(GLOBALS->ae2_f=fopen(fname, "rb"))) || (!(GLOBALS->ae2 = ae2_read_initialize(GLOBALS->ae2_f))) ) { if(GLOBALS->ae2_f) { fclose(GLOBALS->ae2_f); GLOBALS->ae2_f = NULL; } return(LLDescriptor(0)); /* look at GLOBALS->ae2 in caller for success status... */ } GLOBALS->time_dimension = 'n'; if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } init_facility_pack(); /* SPLASH */ splash_create(); sym_hash_initialize(GLOBALS); #ifdef AET2_ALIASDB_IS_PRESENT if(!GLOBALS->disable_ae2_alias) { kw = ae2_read_locate_keyword(GLOBALS->ae2, "aliasdb"); } if(kw) { GLOBALS->adb_alias_stream_file = ae2_read_keyword_stream(GLOBALS->ae2, kw); GLOBALS->adb = adb_open_embed(GLOBALS->adb_alias_stream_file, NULL, alloc_fn, free_fn, adb_msg_fn, error_fn); if(GLOBALS->adb) { unsigned long fn; GLOBALS->ae2_num_aliases = adb_num_aliases(GLOBALS->adb); GLOBALS->adb_max_terms = adb_max_alias_terms(GLOBALS->adb); GLOBALS->adb_terms = calloc_2(GLOBALS->adb_max_terms + 1, sizeof(ADB_TERM)); GLOBALS->adb_aliases = calloc_2(GLOBALS->ae2_num_aliases, sizeof(ADB_TERM *)); GLOBALS->adb_num_terms = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); GLOBALS->adb_idx_first = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); GLOBALS->adb_idx_last = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); fn = adb_map_ids (GLOBALS->adb, symbol_fn, GLOBALS->ae2); /* iteratively replaces all .id with FACIDX */ fprintf(stderr, AET2_RDLOAD"Encountered %lu aliases referencing %lu facs.\n", GLOBALS->ae2_num_aliases, fn); } } #endif GLOBALS->ae2_num_sections=ae2_read_num_sections(GLOBALS->ae2); GLOBALS->ae2_num_facs = ae2_read_num_symbols(GLOBALS->ae2); GLOBALS->numfacs = GLOBALS->ae2_num_facs + GLOBALS->ae2_num_aliases; GLOBALS->ae2_process_mask = calloc_2(1, GLOBALS->numfacs/8+1); GLOBALS->ae2_fr=calloc_2(GLOBALS->numfacs, sizeof(AE2_FACREF)); GLOBALS->ae2_lx2_table=(struct lx2_entry **)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry *)); match_idx = 0; for(i=0;i<GLOBALS->ae2_num_facs;i++) { int idx = i+1; GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].s = idx; GLOBALS->ae2_fr[match_idx].row = ae2_read_symbol_rows(GLOBALS->ae2, idx); if(GLOBALS->ae2_fr[match_idx].row > AE2_MAX_ROWS) { GLOBALS->ae2_fr[match_idx].row = AE2_MAX_ROWS; ae2_read_find_symbol(GLOBALS->ae2, buf, &GLOBALS->ae2_fr[match_idx]); fprintf(stderr, AET2_RDLOAD"Warning: Reduced array %s to %d rows.\n", buf, AE2_MAX_ROWS); } total_rows += (GLOBALS->ae2_fr[match_idx].row > 0) ? GLOBALS->ae2_fr[match_idx].row : 1; if(GLOBALS->ae2_fr[match_idx].row == 1) GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].length = ae2_read_symbol_length(GLOBALS->ae2, idx); GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; match_idx++; } #ifdef AET2_ALIASDB_IS_PRESENT missing = calloc_2(1, (GLOBALS->ae2_num_aliases + 7 + 1) / 8); /* + 1 to mirror idx value */ for(i=0;i<GLOBALS->ae2_num_aliases;i++) { unsigned long numTerms; int idx = i+1; int ii; int midx, mbit; int mcnt; total_rows++; if((numTerms = adb_load_alias_def(GLOBALS->adb, idx, GLOBALS->adb_terms))) { if(GLOBALS->adb_terms[0].first > GLOBALS->adb_terms[0].last) { GLOBALS->ae2_fr[match_idx].length = GLOBALS->adb_terms[0].first - GLOBALS->adb_terms[0].last + 1; } else { GLOBALS->ae2_fr[match_idx].length = GLOBALS->adb_terms[0].last - GLOBALS->adb_terms[0].first + 1; } GLOBALS->adb_idx_first[i] = GLOBALS->adb_terms[0].first; GLOBALS->adb_idx_last[i] = GLOBALS->adb_terms[0].last; GLOBALS->ae2_fr[match_idx].s = idx + GLOBALS->ae2_num_facs; /* bias aliases after regular facs */ GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; GLOBALS->adb_num_terms[i] = numTerms; GLOBALS->adb_aliases[i] = adb_alloc_2(numTerms * sizeof(ADB_TERM)); mcnt = 0; for(ii=0;ii<(numTerms);ii++) { GLOBALS->adb_aliases[i][ii].id = GLOBALS->adb_terms[ii+1].id; if(!GLOBALS->adb_aliases[i][ii].id) { mcnt++; } GLOBALS->adb_aliases[i][ii].first = GLOBALS->adb_terms[ii+1].first; GLOBALS->adb_aliases[i][ii].last = GLOBALS->adb_terms[ii+1].last; } if(mcnt) { midx = idx / 8; mbit = idx & 7; missing[midx] |= (1 << mbit); } } else { unsigned long id = GLOBALS->adb_terms[0].id; if(id) { memcpy(&GLOBALS->ae2_fr[match_idx], &GLOBALS->ae2_fr[id-1], sizeof(AE2_FACREF)); GLOBALS->adb_idx_first[i] = 0; GLOBALS->adb_idx_last[i] = GLOBALS->ae2_fr[match_idx].length - 1; } else /* not in model */ { midx = idx / 8; mbit = idx & 7; missing[midx] |= (1 << mbit); GLOBALS->ae2_fr[match_idx].length = 1; GLOBALS->adb_idx_first[i] = 0; GLOBALS->adb_idx_last[i] = 0; GLOBALS->ae2_fr[match_idx].s = idx + GLOBALS->ae2_num_facs; /* bias aliases after regular facs */ GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; GLOBALS->adb_num_terms[i] = 0; } } match_idx++; } #endif monolithic_node = calloc_2(total_rows, sizeof(struct Node)); monolithic_sym = calloc_2(match_idx, sizeof(struct symbol)); fprintf(stderr, AET2_RDLOAD"Finished building %d facs.\n", match_idx); /* SPLASH */ splash_sync(1, 5); first_cycle = (TimeType) ae2_read_start_cycle(GLOBALS->ae2); last_cycle = (TimeType) ae2_read_end_cycle(GLOBALS->ae2); /* total_cycles = last_cycle - first_cycle + 1; */ /* scan-build */ /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } match_idx = 0; for(i=0;i<GLOBALS->numfacs;i++) { char *str; int idx; int typ; unsigned long len, clen; int row_iter, mx_row, mx_row_adjusted; #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { idx = i+1; len = ae2_read_symbol_name(GLOBALS->ae2, idx, buf); typ = (GLOBALS->ae2_fr[match_idx].row <= 1) ? ND_GEN_NET : ND_VCD_ARRAY; } #ifdef AET2_ALIASDB_IS_PRESENT else { idx = i - GLOBALS->ae2_num_facs + 1; typ = (missing[idx/8] & (1 << (idx & 7))) ? ND_GEN_MISSING : ND_GEN_ALIAS; len = adb_alias_name(GLOBALS->adb, idx, buf) - 1; /* it counts the null character */ } #endif if(GLOBALS->ae2_fr[match_idx].length>1) { int len2; #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { len2 = sprintf_2_1d(buf+len, GLOBALS->ae2_fr[match_idx].length-1); } #ifdef AET2_ALIASDB_IS_PRESENT else { len2 = sprintf_2_2d(buf+len, GLOBALS->adb_idx_first[i - GLOBALS->ae2_num_facs], GLOBALS->adb_idx_last[i - GLOBALS->ae2_num_facs]); } #endif clen = (len + len2 + 1); if(!GLOBALS->do_hier_compress) { str=malloc_2(clen); } else { str = buf; } if(clen > GLOBALS->longestname) GLOBALS->longestname = clen; if(!GLOBALS->alt_hier_delimeter) { if(!GLOBALS->do_hier_compress) strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s = &monolithic_sym[match_idx]; symadd_name_exists_sym_exists(s, str,0); } else { clen = (len+1); if(!GLOBALS->do_hier_compress) { str=malloc_2(clen); } else { str = buf; } if(clen > GLOBALS->longestname) GLOBALS->longestname = clen; if(!GLOBALS->alt_hier_delimeter) { if(!GLOBALS->do_hier_compress) strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s = &monolithic_sym[match_idx]; symadd_name_exists_sym_exists(s, str,0); } mx_row = (GLOBALS->ae2_fr[match_idx].row < 1) ? 1 : GLOBALS->ae2_fr[match_idx].row; mx_row_adjusted = (mx_row < 2) ? 0 : mx_row; n=&monolithic_node[mono_row_offset]; s->n = n; mono_row_offset += mx_row; if(GLOBALS->do_hier_compress) { s->name = compress_facility((unsigned char *)str, clen - 1); } for(row_iter = 0; row_iter < mx_row; row_iter++) { n[row_iter].vartype = typ; n[row_iter].nname=s->name; n[row_iter].mv.mvlfac = (struct fac *)(GLOBALS->ae2_fr+match_idx); /* to keep from having to allocate duplicate mvlfac struct */ /* use the info in the AE2_FACREF array instead */ n[row_iter].array_height = mx_row_adjusted; n[row_iter].this_row = row_iter; if(GLOBALS->ae2_fr[match_idx].length>1) { #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { n[row_iter].msi = 0; n[row_iter].lsi = GLOBALS->ae2_fr[match_idx].length-1; } #ifdef AET2_ALIASDB_IS_PRESENT else { n[row_iter].msi = GLOBALS->adb_idx_first[i - GLOBALS->ae2_num_facs]; n[row_iter].lsi = GLOBALS->adb_idx_last[i - GLOBALS->ae2_num_facs]; } #endif n[row_iter].extvals = 1; } n[row_iter].head.time=-1; /* mark 1st node as negative time */ n[row_iter].head.v.h_val=AN_X; } match_idx++; } #ifdef AET2_ALIASDB_IS_PRESENT if(GLOBALS->adb_idx_last) { free_2(GLOBALS->adb_idx_last); GLOBALS->adb_idx_last = NULL; } if(GLOBALS->adb_idx_first) { free_2(GLOBALS->adb_idx_first); GLOBALS->adb_idx_first = NULL; } if(missing) { free_2(missing); missing = NULL; } #endif freeze_facility_pack(); /* SPLASH */ splash_sync(2, 5); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); if(GLOBALS->fast_tree_sort) { for(i=0;i<GLOBALS->numfacs;i++) { GLOBALS->facs[i]=&monolithic_sym[i]; } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, AET2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;i<GLOBALS->numfacs;i++) { int was_packed = HIER_DEPACK_STATIC; /* no need to free_2() afterward then */ char *sb = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); build_tree_from_name(sb, i); } /* SPLASH */ splash_sync(4, 5); treegraft(&GLOBALS->treeroot); fprintf(stderr, AET2_RDLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(5, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); GLOBALS->facs_are_sorted=1; } else { for(i=0;i<GLOBALS->numfacs;i++) { #ifdef WAVE_HIERFIX char *subst; char ch; #endif GLOBALS->facs[i]=&monolithic_sym[i]; #ifdef WAVE_HIERFIX while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, AET2_RDLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;i<GLOBALS->numfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, AET2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;i<GLOBALS->numfacs;i++) { build_tree_from_name(GLOBALS->facs[i]->name, i); } /* SPLASH */ splash_sync(5, 5); treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); } if(GLOBALS->ae2_time_xlate) /* GLOBALS->ae2_time_xlate is currently unused, but could be again in the future */ { GLOBALS->min_time = GLOBALS->ae2_time_xlate[0]; GLOBALS->max_time = GLOBALS->ae2_time_xlate[last_cycle - first_cycle]; } else { GLOBALS->min_time = first_cycle; GLOBALS->max_time=last_cycle; } GLOBALS->ae2_start_cyc = GLOBALS->ae2_start_limit_cyc = first_cycle; GLOBALS->ae2_end_cyc = GLOBALS->ae2_end_limit_cyc = last_cycle; GLOBALS->is_lx2 = LXT2_IS_AET2; if(skip_start || skip_end) { TimeType b_start, b_end; TimeType lim_idx; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_start<GLOBALS->min_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_end<GLOBALS->min_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; if(GLOBALS->ae2_time_xlate) /* GLOBALS->ae2_time_xlate is currently unused, but could be again in the future */ { for(lim_idx = first_cycle; lim_idx <= last_cycle; lim_idx++) { if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] <= GLOBALS->min_time) { GLOBALS->ae2_start_limit_cyc = lim_idx; } if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] >= GLOBALS->min_time) { break; } } for(; lim_idx <= last_cycle; lim_idx++) { if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] >= GLOBALS->max_time) { GLOBALS->ae2_end_limit_cyc = lim_idx; break; } } } } fprintf(stderr, AET2_RDLOAD"["TTFormat"] start time.\n"AET2_RDLOAD"["TTFormat"] end time.\n", GLOBALS->min_time, GLOBALS->max_time); /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); }
int ae2_iterator(uint64_t start_cycle, uint64_t end_cycle) { unsigned int i, j, r; uint64_t cyc, ecyc, step_cyc; struct ae2_ncycle_autosort *deadlist=NULL; struct ae2_ncycle_autosort *autofacs=NULL; char buf[AE2_MAXFACLEN+1]; autofacs = calloc_2(GLOBALS->numfacs, sizeof(struct ae2_ncycle_autosort)); for(i=0;i<GLOBALS->numfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(!nr) nr = 1; for(r=0;r<nr;r++) { nptr np = GLOBALS->ae2_lx2_table[i][r].np; np->mv.value = calloc_2(1, GLOBALS->ae2_fr[i].length+1); } } } for(j=0;j<GLOBALS->ae2_num_sections;j++) { struct ae2_ncycle_autosort **autosort = NULL; const uint64_t *ith_range = ae2_read_ith_section_range(GLOBALS->ae2, j); cyc = *ith_range; ecyc = *(ith_range+1); if(ecyc<start_cycle) continue; if(cyc>end_cycle) break; if((ecyc<cyc)||(ecyc==~ULLDescriptor(0))) continue; autosort = calloc_2(ecyc - cyc + 1, sizeof(struct ae2_ncycle_autosort *)); for(i=0;i<GLOBALS->numfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr<2) { nptr np = GLOBALS->ae2_lx2_table[i][0].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, 0); } } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc); if(rows) { for(r=1;r<rows+1;r++) { nptr np; uint64_t row = ae2_read_ith_sparse_row(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc, r); GLOBALS->ae2_fr[i].row = row; np = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, row); } } } } else { int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(rows) { for(r=0;r<rows;r++) { nptr np; uint64_t row = r; GLOBALS->ae2_fr[i].row = row; np = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, row); } } } } } } } deadlist=NULL; for(i=0;i<GLOBALS->numfacs;i++) { uint64_t ncyc; nptr np; int nr; if(!aet2_rd_get_fac_process_mask(i)) continue; nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr < 2) { np = GLOBALS->ae2_lx2_table[i][0].np; ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, np->mv.value); } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc); uint64_t mxcyc = end_cycle+1; for(r=1;r<rows+1;r++) { /* nptr np; */ uint64_t row = ae2_read_ith_sparse_row(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc, r); GLOBALS->ae2_fr[i].row = row; /* np = GLOBALS->ae2_lx2_table[i][row].np; */ ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if((ncyc > cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = cyc; } } else { int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); uint64_t mxcyc = end_cycle+1; for(r=0;r<rows;r++) { /* nptr np; */ uint64_t row = r; GLOBALS->ae2_fr[i].row = row; /* np = GLOBALS->ae2_lx2_table[i][row].np; */ ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if((ncyc > cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = cyc; } } } if(ncyc!=cyc) { int offset = ncyc-cyc; struct ae2_ncycle_autosort *t = autosort[offset]; autofacs[i].next = t; autosort[offset] = autofacs+i; } else { struct ae2_ncycle_autosort *t = deadlist; autofacs[i].next = t; deadlist = autofacs+i; } } for(step_cyc = cyc+1 ; step_cyc <= ecyc ; step_cyc++) { int offset = step_cyc-cyc; struct ae2_ncycle_autosort *t = autosort[offset]; if(step_cyc > end_cycle) break; if(t) { while(t) { uint64_t ncyc; struct ae2_ncycle_autosort *tn = t->next; nptr np; int nr; i = t-autofacs; nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr<2) { np = GLOBALS->ae2_lx2_table[i][0].np; ae2_callback(&step_cyc, &i, &np->mv.value, 0); ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, np->mv.value); } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, step_cyc); uint64_t mxcyc = end_cycle+1; for(r=1;r<rows+1;r++) { nptr npr; uint64_t row = ae2_read_ith_sparse_row(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, step_cyc, r); GLOBALS->ae2_fr[i].row = row; npr = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if(strcmp(buf, npr->mv.value)) { strcpy(npr->mv.value, buf); ae2_callback(&step_cyc, &i, &npr->mv.value, row); } ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if((ncyc > step_cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = step_cyc; } } else { int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); uint64_t mxcyc = end_cycle+1; for(r=0;r<rows;r++) { nptr npr; uint64_t row = r; GLOBALS->ae2_fr[i].row = row; npr = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if(strcmp(buf, npr->mv.value)) { strcpy(npr->mv.value, buf); ae2_callback(&step_cyc, &i, &npr->mv.value, row); } ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if((ncyc > step_cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = step_cyc; } } } if(ncyc!=step_cyc) { int offset2 = ncyc-cyc; struct ae2_ncycle_autosort *ta = autosort[offset2]; autofacs[i].next = ta; autosort[offset2] = autofacs+i; } else { struct ae2_ncycle_autosort *ta = deadlist; autofacs[i].next = ta; deadlist = autofacs+i; } t = tn; } } } if(autosort) free_2(autosort); } for(i=0;i<GLOBALS->numfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(!nr) nr = 1; for(r=0;r<nr;r++) { nptr np = GLOBALS->ae2_lx2_table[i][r].np; free_2(np->mv.value); np->mv.value = NULL; } } } free_2(autofacs); return(0); }
TimeType vcd_main(char *fname, char *lxname) { #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST struct vcdsymbol *v, *v2; #endif vcd_hier_delimeter[0]=hier_delimeter; errno=0; /* reset in case it's set for some reason */ yytext=(char *)malloc_2(T_MAX_STR+1); if((strlen(fname)>2)&&(!strcmp(fname+strlen(fname)-3,".gz"))) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=(char *)wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); vcd_handle=popen(str,"r"); vcd_is_compressed=~0; } else { if(strcmp("-",fname)) { vcd_handle=fopen(fname,"rb"); } else { vcd_handle=stdin; } vcd_is_compressed=0; } if(!vcd_handle) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", vcd_is_compressed?"compressed":"", fname); exit(1); } lt=lxt2_wr_init(lxname); if(!lt) { fprintf(stderr, "Problem opening output file '%s'\n", lxname); perror("Why"); exit(255); } if(opt_partial_mode>=0) { lxt2_wr_set_partial_on(lt, opt_partial_mode); } if((opt_checkpoint_disable)&&(!opt_break_size)) { lxt2_wr_set_checkpoint_off(lt); } lxt2_wr_set_compression_depth(lt, opt_depth); lxt2_wr_set_break_size(lt, (off_t)opt_break_size); lxt2_wr_set_maxgranule(lt, opt_maxgranule); lxt2_wr_symbol_bracket_stripping(lt, 1); /* this is intentional */ sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); printf("\nConverting VCD File '%s' to LXT2 file '%s'...\n\n",(vcd_handle!=stdin)?fname:"from stdin", lxname); build_slisthier(); vcd_parse(); if(varsplit) { free_2(varsplit); varsplit=NULL; } add_tail_histents(); printf("["TTFormat"] start time.\n["TTFormat"] end time.\n\n", start_time, end_time); lxt2_wr_close(lt); lt=NULL; min_time=start_time*time_scale; max_time=end_time*time_scale; if((min_time==max_time)||(max_time==0)) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); exit(1); } if(vcd_handle!=stdin) { fclose(vcd_handle); vcd_handle=NULL; } free(yytext); yytext=NULL; if(indexed) { free(indexed); indexed=NULL; } if(sorted) { free(sorted); sorted=NULL; } #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST v=vcdsymroot; while(v) { if(v->name) { free(v->name); v->name=NULL; } if(v->id) { free(v->id); v->id=NULL; } if(v->value) { free(v->value); v->value=NULL; } if(v->narray) { int i; for(i=0;i<v->size;i++) { struct HistEnt *h1, *h2; if((h1 = v->narray[i]->head.next)) { h1 = v->narray[i]->head.next; while(h1) { h2 = h1->next; free(h1); h1 = h2; } } free(v->narray[i]); v->narray[i]=NULL; } free(v->narray); v->narray=NULL; } v2=v->next; free(v); v=v2; } vcdsymroot=vcdsymcurr=NULL; #endif free(sym); sym=NULL; if(slisthier) { free(slisthier); slisthier=NULL; } return(max_time); }
/* * this function doesn't do anything useful anymore except for to mark * statistics on the various nets... */ void add_histent(TimeType t_time, struct Node *n, char ch, int regadd, char *vector) { struct HistEnt *he; if(!vector) { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.val=1; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { /* if(regadd) { t_time*=(time_scale); } */ /* scan-build : never read */ if(toupper((int)(unsigned char)ch)!=deadchar) n->notdead=1; n->numtrans++; } } else { if(ch=='g') /* real number */ { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { n->notdead=1; n->numtrans++; } } else { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { int i, nlen; nlen = strlen(vector); if(nlen) { n->numtrans++; for(i=0;i<nlen;i++) { if(toupper((int)(unsigned char)vector[i])!=deadchar) { n->notdead=1; return; } } } } } } }
static void vcd_parse(void) { int tok; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_zero=atoi_64(yytext); lxt2_wr_set_timezero(lt, time_zero); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; int timelogadjust = 0; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_scale=atoi_64(yytext); if(!time_scale) time_scale=1; else if (time_scale == 10) timelogadjust = +1; else if (time_scale == 100) timelogadjust = +2; for(i=0;i<yylen;i++) { if((yytext[i]<'0')||(yytext[i]>'9')) { prefix=yytext[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=yytext[0]; } switch(prefix) { case 's': case ' ': lxt2_wr_set_timescale(lt, 0+timelogadjust); break; case 'm': lxt2_wr_set_timescale(lt, -3+timelogadjust); break; case 'u': lxt2_wr_set_timescale(lt, -6+timelogadjust); break; case 'n': lxt2_wr_set_timescale(lt, -9+timelogadjust); break; case 'p': lxt2_wr_set_timescale(lt, -12+timelogadjust); break; case 'f': lxt2_wr_set_timescale(lt, -15+timelogadjust); break; default: /* unknown */ lxt2_wr_set_timescale(lt, -9+timelogadjust); break; } sync_end(NULL); } break; case T_SCOPE: T_GET; T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=yylen; s->str=(char *)malloc_2(yylen+1); strcpy(s->str,yytext); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(slistroot) { struct slist *s; s=slistroot; if(!s->next) { free_2(s->str); free_2(s); slistroot=slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_VAR: { int vtok; struct vcdsymbol *v=NULL; var_prevch=0; if(varsplit) { free_2(varsplit); varsplit=NULL; } vtok=get_vartoken(1); if(vtok>V_PORT) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(yytext); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(yytext); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { v->vartype = V_REAL; } /* MTI fix */ if(v->vartype==V_REAL) { v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; for(i=0;i<v->size;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.val=1; } } if(v->vartype==V_EVENT) { struct queuedevent *q; v->ev=q=(struct queuedevent *)calloc_2(1,sizeof(struct queuedevent)); q->sym=v; q->last_event_time=-1; q->next=queuedevents; queuedevents=q; } if(!vcdsymroot) { vcdsymroot=vcdsymcurr=v; } else { vcdsymcurr->next=v; vcdsymcurr=v; } numsyms++; #if 0 if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = lxt2_wr_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = lxt2_wr_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } #endif DEBUG(fprintf(stderr,"VAR %s %d %s %s[%d:%d]\n", vartypes[v->vartype], v->size, v->id, v->name, v->msi, v->lsi)); goto bail; err: if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: if(!header_over) { header_over=1; /* do symbol table management here */ create_sorted_table(); if((!sorted)&&(!indexed)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(1); } } break; case T_STRING: if(header_over) { /* catchall for events when header over */ if(yytext[0]=='#') { TimeType t_time; t_time=atoi_64(yytext+1); if(start_time<0) { start_time=t_time; } if(t_time < current_time) /* avoid backtracking time counts which can happen on malformed files */ { t_time = current_time; } current_time=t_time; if(end_time<t_time) end_time=t_time; /* in case of malformed vcd files */ lxt2_wr_set_time64(lt, current_time); DEBUG(fprintf(stderr,"#"TTFormat"\n",t_time)); } else { parse_valuechange(); } } break; case T_DUMPALL: /* dump commands modify vals anyway so */ case T_DUMPPORTSALL: break; /* just loop through.. */ case T_DUMPOFF: case T_DUMPPORTSOFF: dumping_off=1; lxt2_wr_set_dumpoff(lt); break; case T_DUMPON: case T_DUMPPORTSON: dumping_off=0; lxt2_wr_set_dumpon(lt); break; case T_DUMPVARS: case T_DUMPPORTS: if(current_time<0) { start_time=current_time=end_time=0; /* lxt2_wr_set_time(lt, current_time); */ } break; case T_VCDCLOSE: sync_end("VCDCLOSE:"); break; /* next token will be '#' time related followed by $end */ case T_END: /* either closure for dump commands or */ break; /* it's spurious */ case T_UNKNOWN_KEY: sync_end(NULL); /* skip over unknown keywords */ break; case T_EOF: return; default: DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n")); } } }
static struct tree * build_hierarchy (struct ghw_handler *h, struct ghw_hie *hie) { struct tree *t; struct tree *t_ch; struct tree *prev; struct ghw_hie *ch; unsigned char ttype; switch (hie->kind) { case ghw_hie_design: case ghw_hie_block: case ghw_hie_instance: case ghw_hie_generate_for: case ghw_hie_generate_if: case ghw_hie_package: /* Convert kind. */ switch(hie->kind) { case ghw_hie_design: ttype = TREE_VHDL_ST_DESIGN; break; case ghw_hie_block: ttype = TREE_VHDL_ST_BLOCK; break; case ghw_hie_instance: ttype = TREE_VHDL_ST_INSTANCE; break; case ghw_hie_generate_for: ttype = TREE_VHDL_ST_GENFOR; break; case ghw_hie_generate_if: ttype = TREE_VHDL_ST_GENIF; break; case ghw_hie_package: default: ttype = TREE_VHDL_ST_PACKAGE; break; } /* For iterative generate, add the index. */ if (hie->kind == ghw_hie_generate_for) { char buf[128]; int name_len, buf_len; char *n; ghw_get_value (buf, sizeof (buf), hie->u.blk.iter_value, hie->u.blk.iter_type); name_len = strlen (hie->name); buf_len = strlen (buf); t = (struct tree *) calloc_2(1, sizeof (struct tree) + (2 + buf_len + name_len + 1)); t->kind = ttype; n = t->name; memcpy (n, hie->name, name_len); n += name_len; *n++ = '['; memcpy (n, buf, buf_len); n += buf_len; *n++ = ']'; *n = 0; } else { if(hie->name) { t = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(hie->name) + 1); t->kind = ttype; strcpy(t->name, (char *)hie->name); } else { t = (struct tree *) calloc_2(1, sizeof (struct tree) + 1); t->kind = ttype; } } t->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; /* Recurse. */ prev = NULL; for (ch = hie->u.blk.child; ch != NULL; ch = ch->brother) { t_ch = build_hierarchy (h, ch); if (t_ch != NULL) { if (prev == NULL) t->child = t_ch; else prev->next = t_ch; prev = t_ch; } } return t; case ghw_hie_process: return NULL; case ghw_hie_signal: case ghw_hie_port_in: case ghw_hie_port_out: case ghw_hie_port_inout: case ghw_hie_port_buffer: case ghw_hie_port_linkage: { unsigned int *ptr = hie->u.sig.sigs; /* Convert kind. */ switch(hie->kind) { case ghw_hie_signal: ttype = TREE_VHDL_ST_SIGNAL; break; case ghw_hie_port_in: ttype = TREE_VHDL_ST_PORTIN; break; case ghw_hie_port_out: ttype = TREE_VHDL_ST_PORTOUT; break; case ghw_hie_port_inout: ttype = TREE_VHDL_ST_PORTINOUT; break; case ghw_hie_port_buffer: ttype = TREE_VHDL_ST_BUFFER; break; case ghw_hie_port_linkage: default: ttype = TREE_VHDL_ST_LINKAGE; break; } /* Convert type. */ t = build_hierarchy_type (h, hie->u.sig.type, hie->name, &ptr); if (*ptr != 0) abort (); if(t) { t->kind = ttype; } return t; } default: fprintf (stderr, "ghw: build_hierarchy: cannot handle hie %d\n", hie->kind); abort (); } }
static struct tree * build_hierarchy_type (struct ghw_handler *h, union ghw_type *t, const char *pfx, unsigned int **sig) { struct tree *res; struct symbol *s; switch (t->kind) { case ghdl_rtik_subtype_scalar: return build_hierarchy_type (h, t->ss.base, pfx, sig); case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: case ghdl_rtik_type_f64: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: s = calloc_2(1, sizeof(struct symbol)); if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->nbr_sig_ref_ghw_c_1++; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = *(*sig)++; s->n = GLOBALS->nxp_ghw_c_1[res->t_which]; return res; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: { struct tree *r; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; r = res; build_hierarchy_array (h, t, 0, "", &res, sig); r->child = r->next; r->next = NULL; return r; } case ghdl_rtik_type_record: { struct tree *last; struct tree *c; int i; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; last = NULL; for (i = 0; i < t->rec.nbr_fields; i++) { c = build_hierarchy_type (h, t->rec.el[i].type, t->rec.el[i].name, sig); if (last == NULL) res->child = c; else last->next = c; last = c; } return res; } default: fprintf (stderr, "build_hierarchy_type: unhandled type %d\n", t->kind); abort (); } }
TimeType ghw_main(char *fname) { struct ghw_handler handle; int i; int rc; if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } handle.flag_verbose = 0; if ((rc=ghw_open (&handle, fname)) < 0) { fprintf (stderr, "Error opening ghw file '%s', rc=%d.\n", fname, rc); return(LLDescriptor(0)); /* look at return code in caller for success status... */ } GLOBALS->time_scale = 1; GLOBALS->time_dimension = 'f'; GLOBALS->asbuf = malloc_2(4097); if (ghw_read_base (&handle) < 0) { free_2(GLOBALS->asbuf); GLOBALS->asbuf = NULL; fprintf (stderr, "Error in ghw file '%s'.\n", fname); return(LLDescriptor(0)); /* look at return code in caller for success status... */ } GLOBALS->min_time = 0; GLOBALS->max_time = 0; GLOBALS->nbr_sig_ref_ghw_c_1 = 0; GLOBALS->nxp_ghw_c_1 =(struct Node **)calloc_2(handle.nbr_sigs, sizeof(struct Node *)); for(i=0;i<handle.nbr_sigs;i++) { GLOBALS->nxp_ghw_c_1[i] = (struct Node *)calloc_2(1,sizeof(struct Node)); } GLOBALS->treeroot = build_hierarchy (&handle, handle.hie); /* GHW does not contains a 'top' name. FIXME: should use basename of the file. */ create_facs (&handle); read_traces (&handle); add_tail (&handle); set_fac_name (&handle); free_2(GLOBALS->nxp_ghw_c_1); GLOBALS->nxp_ghw_c_1 = NULL; /* fix up names on aliased nodes via cloning... */ for(i=0;i<GLOBALS->numfacs;i++) { if(strcmp(GLOBALS->facs[i]->name, GLOBALS->facs[i]->n->nname)) { struct Node *n = malloc_2(sizeof(struct Node)); memcpy(n, GLOBALS->facs[i]->n, sizeof(struct Node)); GLOBALS->facs[i]->n = n; n->nname = GLOBALS->facs[i]->name; } } /* treeroot->name = "top"; */ { const char *base_hier = "top"; struct tree *t = calloc_2(1, sizeof(struct tree) + strlen(base_hier) + 1); memcpy(t, GLOBALS->treeroot, sizeof(struct tree)); strcpy(t->name, base_hier); /* scan-build false warning here, thinks name[1] is total length */ #ifndef WAVE_TALLOC_POOL_SIZE free_2(GLOBALS->treeroot); /* if using tree alloc pool, can't deallocate this */ #endif GLOBALS->treeroot = t; } ghw_close (&handle); rechain_facs(); /* vectorize bitblasted nets */ ghw_sortfacs(); /* sort nets as ghw is unsorted ... also fix hier tree (it should really be built *after* facs are sorted!) */ #if 0 treedebug(GLOBALS->treeroot,""); facs_debug(); #endif GLOBALS->is_ghw = 1; fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->min_time*GLOBALS->time_scale, GLOBALS->max_time*GLOBALS->time_scale); if(GLOBALS->num_glitches_ghw_c_1) fprintf(stderr, "Warning: encountered %d glitch%s across %d glitch region%s.\n", GLOBALS->num_glitches_ghw_c_1, (GLOBALS->num_glitches_ghw_c_1!=1)?"es":"", GLOBALS->num_glitch_regions_ghw_c_1, (GLOBALS->num_glitch_regions_ghw_c_1!=1)?"s":""); return GLOBALS->max_time; }
/* * output scopedata for a given name if needed, return pointer to name string */ char *output_hier(int is_trans, char *name) { char *pnt, *pnt2; char *s; int len; struct namehier *nh_head=NULL, *nh_curr=NULL, *nhtemp; pnt=pnt2=name; for(;;) { if(*pnt2 == '\\') { while(*pnt2) pnt2++; } else { /* while((*pnt2!='.')&&(*pnt2)) pnt2++; ... does not handle dot at end of name */ while(*pnt2) { if(*pnt2!='.') { pnt2++; continue; } else { if(!*(pnt2+1)) /* if dot is at end of name */ { pnt2++; continue; } else { break; } } } } s=(char *)calloc_2(1,(len=pnt2-pnt)+1); memcpy(s, pnt, len); nhtemp=(struct namehier *)calloc_2(1,sizeof(struct namehier)); nhtemp->name=s; if(!nh_curr) { nh_head=nh_curr=nhtemp; } else { nh_curr->next=nhtemp; nh_curr->not_final=1; nh_curr=nhtemp; } if(!*pnt2) break; pnt=(++pnt2); } diff_hier(is_trans, nh_head, GLOBALS->nhold_vcd_saver_c_1); free_hier(); GLOBALS->nhold_vcd_saver_c_1=nh_head; { char *mti_sv_patch = strstr(nh_curr->name, "]["); /* case is: #implicit-var###VarElem:ram_di[0.0] [63:0] */ if(mti_sv_patch) { char *t = calloc_2(1, strlen(nh_curr->name) + 1 + 1); *mti_sv_patch = 0; sprintf(t, "%s] %s", nh_curr->name, mti_sv_patch+1); free_2(nh_curr->name); nh_curr->name = t; } if((nh_curr->name[0] == '\\') && (nh_curr->name[1] == '#')) { return(nh_curr->name+1); } } return(nh_curr->name); }
/* * mainline */ int save_nodes_to_export_generic(FILE *trans_file, Trptr trans_head, const char *fname, int export_typ) { Trptr t = trans_head ? trans_head : GLOBALS->traces.first; int nodecnt = 0; vcdsav_Tree *vt = NULL; vcdsav_Tree **hp_clone = GLOBALS->hp_vcd_saver_c_1; nptr n; /* ExtNode *e; */ /* int msi, lsi; */ int i; TimeType prevtime = LLDescriptor(-1); time_t walltime; struct strace *st = NULL; int strace_append = 0; int max_len = 1; char *row_data = NULL; struct lt_trace *lt = NULL; int lxt = (export_typ == WAVE_EXPORT_LXT); int is_trans = (export_typ == WAVE_EXPORT_TRANS); if(export_typ == WAVE_EXPORT_TIM) { return(do_timfile_save(fname)); } errno = 0; if(lxt) { lt = lt_init(fname); if(!lt) { return(VCDSAV_FILE_ERROR); } } else { if(export_typ != WAVE_EXPORT_TRANS) { GLOBALS->f_vcd_saver_c_1 = fopen(fname, "wb"); } else { if(!trans_head) /* scan-build : is programming error to get here */ { return(VCDSAV_FILE_ERROR); } GLOBALS->f_vcd_saver_c_1 = trans_file; } if(!GLOBALS->f_vcd_saver_c_1) { return(VCDSAV_FILE_ERROR); } } while(t) { if(!t->vector) { if(t->n.nd) { n = t->n.nd; if(n->expansion) n = n->expansion->parent; vt = vcdsav_splay(n, vt); if(!vt || vt->item != n) { unsigned char flags = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } vt = vcdsav_insert(n, vt, ++nodecnt, flags, &n->head); } } } else { bvptr b = t->n.vec; if(b) { bptr bt = b->bits; if(bt) { for(i=0;i<bt->nnbits;i++) { if(bt->nodes[i]) { n = bt->nodes[i]; if(n->expansion) n = n->expansion->parent; vt = vcdsav_splay(n, vt); if(!vt || vt->item != n) { unsigned char flags = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } vt = vcdsav_insert(n, vt, ++nodecnt, flags, &n->head); } } } } } } if(export_typ == WAVE_EXPORT_TRANS) { break; } if(!strace_append) { t=t->t_next; if(t) continue; } else { st = st->next; t = st ? st->trace : NULL; if(t) { continue; } else { swap_strace_contexts(); } } strace_concat: GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = strace_append]; strace_append++; if(strace_append == WAVE_NUM_STRACE_WINDOWS) break; if(!GLOBALS->strace_ctx->shadow_straces) { goto strace_concat; } swap_strace_contexts(); st = GLOBALS->strace_ctx->straces; t = st ? st->trace : NULL; if(!t) {swap_strace_contexts(); goto strace_concat; } } if(!nodecnt) return(VCDSAV_EMPTY); /* header */ if(lxt) { int dim; lt_set_chg_compress(lt); lt_set_clock_compress(lt); lt_set_initial_value(lt, 'x'); lt_set_time64(lt, 0); lt_symbol_bracket_stripping(lt, 1); switch(GLOBALS->time_dimension) { case 'm': dim = -3; break; case 'u': dim = -6; break; case 'n': dim = -9; break; case 'p': dim = -12; break; case 'f': dim = -15; break; default: dim = 0; break; } lt_set_timescale(lt, dim); } else { if(export_typ != WAVE_EXPORT_TRANS) { time(&walltime); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$date\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "\t%s",asctime(localtime(&walltime))); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$end\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$version\n\t"WAVE_VERSION_INFO"\n$end\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$timescale\n\t%d%c%s\n$end\n", (int)GLOBALS->time_scale, GLOBALS->time_dimension, (GLOBALS->time_dimension=='s') ? "" : "s"); if(GLOBALS->global_time_offset) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$timezero\n\t"TTFormat"\n$end\n",GLOBALS->global_time_offset); } } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment data_start %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment name %s $end\n", trans_head->name ? trans_head->name : "UNKNOWN"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$timescale %d%c%s $end\n", (int)GLOBALS->time_scale, GLOBALS->time_dimension, (GLOBALS->time_dimension=='s') ? "" : "s"); if(GLOBALS->global_time_offset) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$timezero "TTFormat" $end\n",GLOBALS->global_time_offset); } w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment min_time "TTFormat" $end\n", GLOBALS->min_time / GLOBALS->time_scale); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment max_time "TTFormat" $end\n", GLOBALS->max_time / GLOBALS->time_scale); } } if(export_typ == WAVE_EXPORT_TRANS) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment max_seqn %d $end\n", nodecnt); if(t && t->transaction_args) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment args \"%s\" $end\n", t->transaction_args); } } /* write out netnames here ... */ hp_clone = GLOBALS->hp_vcd_saver_c_1 = calloc_2(nodecnt, sizeof(vcdsav_Tree *)); recurse_build(vt, &hp_clone); for(i=0;i<nodecnt;i++) { int was_packed = HIER_DEPACK_STATIC; char *hname = hier_decompress_flagged(GLOBALS->hp_vcd_saver_c_1[i]->item->nname, &was_packed); char *netname = lxt ? hname : output_hier(is_trans, hname); if(export_typ == WAVE_EXPORT_TRANS) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment seqn %d %s $end\n", GLOBALS->hp_vcd_saver_c_1[i]->val, hname); } if(GLOBALS->hp_vcd_saver_c_1[i]->flags & (HIST_REAL|HIST_STRING)) { if(lxt) { GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, 0, 0, GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING ? LT_SYM_F_STRING : LT_SYM_F_DOUBLE); } else { const char *typ = (GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING) ? "string" : "real"; int tlen = (GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING) ? 0 : 1; w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$var %s %d %s %s $end\n", typ, tlen, vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } } else { int msi = -1, lsi = -1; if(GLOBALS->hp_vcd_saver_c_1[i]->item->extvals) { msi = GLOBALS->hp_vcd_saver_c_1[i]->item->msi; lsi = GLOBALS->hp_vcd_saver_c_1[i]->item->lsi; } if(msi==lsi) { if(lxt) { int strand_idx = strand_pnt(netname); if(strand_idx >= 0) { msi = lsi = atoi(netname + strand_idx + 1); } GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, msi, lsi, LT_SYM_F_BITS); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$var wire 1 %s %s $end\n", vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } } else { int len = (msi < lsi) ? (lsi - msi + 1) : (msi - lsi + 1); if(lxt) { GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, msi, lsi, LT_SYM_F_BITS); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$var wire %d %s %s $end\n", len, vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } GLOBALS->hp_vcd_saver_c_1[i]->len = len; if(len > max_len) max_len = len; } } /* if(was_packed) { free_2(hname); } ...not needed for HIER_DEPACK_STATIC */ } row_data = malloc_2(max_len + 1); if(!lxt) { output_hier(is_trans, ""); free_hier(); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$enddefinitions $end\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$dumpvars\n"); } /* value changes */ for(i=(nodecnt/2-1);i>0;i--) /* build nodes into having heap property */ { heapify(i,nodecnt); } for(;;) { heapify(0, nodecnt); if(!GLOBALS->hp_vcd_saver_c_1[0]->hist) break; if(GLOBALS->hp_vcd_saver_c_1[0]->hist->time > GLOBALS->max_time) break; if((GLOBALS->hp_vcd_saver_c_1[0]->hist->time != prevtime) && (GLOBALS->hp_vcd_saver_c_1[0]->hist->time >= LLDescriptor(0))) { TimeType tnorm = GLOBALS->hp_vcd_saver_c_1[0]->hist->time; if(GLOBALS->time_scale != 1) { tnorm /= GLOBALS->time_scale; } if(lxt) { lt_set_time64(lt, tnorm); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "#"TTFormat"\n", tnorm); } prevtime = GLOBALS->hp_vcd_saver_c_1[0]->hist->time; } if(GLOBALS->hp_vcd_saver_c_1[0]->hist->time >= LLDescriptor(0)) { if(GLOBALS->hp_vcd_saver_c_1[0]->flags & (HIST_REAL|HIST_STRING)) { if(GLOBALS->hp_vcd_saver_c_1[0]->flags & HIST_STRING) { char *vec = GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector ? GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector : "UNDEF"; if(lxt) { lt_emit_value_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, vec); } else { int vec_slen = strlen(vec); char *vec_escaped = malloc_2(vec_slen*4 + 1); /* worst case */ int vlen = fstUtilityBinToEsc((unsigned char *)vec_escaped, (unsigned char *)vec, vec_slen); vec_escaped[vlen] = 0; if(vlen) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "s%s %s\n", vec_escaped, vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "s\\000 %s\n", vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } free_2(vec_escaped); } } else { #ifdef WAVE_HAS_H_DOUBLE double *d = &GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_double; #else double *d = (double *)GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector; #endif double value; if(!d) { sscanf("NaN", "%lg", &value); } else { value = *d; } if(lxt) { lt_emit_value_double(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, value); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "r%.16g %s\n", value, vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } } else if(GLOBALS->hp_vcd_saver_c_1[0]->len) { if(GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector) { for(i=0;i<GLOBALS->hp_vcd_saver_c_1[0]->len;i++) { row_data[i] = analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector[i]); } } else { for(i=0;i<GLOBALS->hp_vcd_saver_c_1[0]->len;i++) { row_data[i] = 'x'; } } row_data[i] = 0; if(lxt) { lt_emit_value_bit_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, row_data); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "b%s %s\n", vcd_truncate_bitvec(row_data), vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } else { if(lxt) { row_data[0] = analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_val); row_data[1] = 0; lt_emit_value_bit_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, row_data); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "%c%s\n", analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_val), vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } } GLOBALS->hp_vcd_saver_c_1[0]->hist = GLOBALS->hp_vcd_saver_c_1[0]->hist->next; } if(prevtime < GLOBALS->max_time) { if(lxt) { lt_set_time64(lt, GLOBALS->max_time / GLOBALS->time_scale); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "#"TTFormat"\n", GLOBALS->max_time / GLOBALS->time_scale); } } for(i=0;i<nodecnt;i++) { free_2(GLOBALS->hp_vcd_saver_c_1[i]); } free_2(GLOBALS->hp_vcd_saver_c_1); GLOBALS->hp_vcd_saver_c_1 = NULL; free_2(row_data); row_data = NULL; if(lxt) { lt_close(lt); lt = NULL; } else { if(export_typ != WAVE_EXPORT_TRANS) { fclose(GLOBALS->f_vcd_saver_c_1); } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment data_end %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ #if !defined _MSC_VER && !defined __MINGW32__ fflush(GLOBALS->f_vcd_saver_c_1); #endif } GLOBALS->f_vcd_saver_c_1 = NULL; } return(VCDSAV_OK); }