예제 #1
0
파일: lxt.c 프로젝트: SnookEE/nvc
void lxt_restart(void)
{
   if (trace == NULL)
      return;

   lt_set_timescale(trace, -15);
   lt_symbol_bracket_stripping(trace, 0);
   lt_set_clock_compress(trace);

   const int ndecls = tree_decls(lxt_top);
   for (int i = 0; i < ndecls; i++) {
      tree_t d = tree_decl(lxt_top, i);
      if (tree_kind(d) != T_SIGNAL_DECL)
         continue;
      else if (!wave_should_dump(d))
         continue;

      type_t type = tree_type(d);

      int rows, msb, lsb;
      if (type_is_array(type)) {
         rows = type_dims(type) - 1;
         if ((rows > 0) || type_is_array(type_elem(type))) {
            warn_at(tree_loc(d), "cannot emit arrays of greater than one "
                    "dimension or arrays of arrays in LXT yet");
            continue;
         }

         range_t r = type_dim(type, 0);
         msb = assume_int(r.left);
         lsb = assume_int(r.right);
      }
      else {
         rows = 0;
         msb = lsb = -1;
      }

      lxt_data_t *data = xmalloc(sizeof(lxt_data_t));
      memset(data, '\0', sizeof(lxt_data_t));

      int flags = 0;

      if (type_is_array(type)) {
         // Only arrays of CHARACTER, BIT, STD_ULOGIC are supported
         type_t elem = type_base_recur(type_elem(type));
         if ((type_kind(elem) != T_ENUM)
             || !lxt_can_fmt_enum_chars(elem, data, &flags)) {
            warn_at(tree_loc(d), "cannot represent arrays of type %s "
                    "in LXT format", type_pp(elem));
            free(data);
            continue;
         }

         data->dir = type_dim(type, 0).kind;
      }
      else {
         type_t base = type_base_recur(type);
         switch (type_kind(base)) {
         case T_INTEGER:
            data->fmt = lxt_fmt_int;
            flags = LT_SYM_F_INTEGER;
            break;

         case T_ENUM:
            if (!lxt_can_fmt_enum_chars(base, data, &flags)) {
               data->fmt = lxt_fmt_enum;
               flags = LT_SYM_F_STRING;
            }
            break;

         default:
            warn_at(tree_loc(d), "cannot represent type %s in LXT format",
                    type_pp(type));
            free(data);
            continue;
         }
      }

      char *name = lxt_fmt_name(d);
      data->sym = lt_symbol_add(trace, name, rows, msb, lsb, flags);
      free(name);

      tree_add_attr_ptr(d, lxt_data_i, data);

      watch_t *w = rt_set_event_cb(d, lxt_event_cb, data, true);

      (*data->fmt)(d, w, data);
   }

   last_time = (lxttime_t)-1;
}
예제 #2
0
static void scan_item(unsigned depth, vpiHandle item, int skip)
{
      struct t_cb_data cb;
      struct vcd_info* info;

      const char* name;
      const char* ident;
      int nexus_id;

      switch (vpi_get(vpiType, item)) {

	  case vpiMemoryWord:
	    if (vpi_get(vpiConstantSelect, item) == 0) {
		    /* Turn a non-constant array word select into a
		     * constant word select. */
		  vpiHandle array = vpi_handle(vpiParent, item);
		  PLI_INT32 idx = vpi_get(vpiIndex, item);
		  item = vpi_handle_by_index(array, idx);
	    }
	  case vpiIntegerVar:
	  case vpiBitVar:
	  case vpiByteVar:
	  case vpiShortIntVar:
	  case vpiIntVar:
	  case vpiLongIntVar:
	  case vpiTimeVar:
	  case vpiReg:
	  case vpiNet:

	      /* An array word is implicitly escaped so look for an
	       * escaped identifier that this could conflict with. */
            if (vpi_get(vpiType, item) == vpiMemoryWord &&
                vpi_handle_by_name(vpi_get_str(vpiFullName, item), 0)) {
		  vpi_printf("LXT warning: dumping array word %s will "
		             "conflict with an escaped identifier.\n",
		             vpi_get_str(vpiFullName, item));
            }

            if (skip || vpi_get(vpiAutomatic, item)) break;

	    name = vpi_get_str(vpiName, item);
	    nexus_id = vpi_get(_vpiNexusId, item);
	    if (nexus_id) {
		  ident = find_nexus_ident(nexus_id);
	    } else {
		  ident = 0;
	    }

	    if (!ident) {
		  char*tmp = create_full_name(name);
		  ident = strdup_sh(&name_heap, tmp);
		  free(tmp);

		  if (nexus_id) set_nexus_ident(nexus_id, ident);

		  info = malloc(sizeof(*info));

		  info->time.type = vpiSimTime;
		  info->item  = item;
		  info->sym   = lt_symbol_add(dump_file, ident,
		                              0 /* array rows */,
		                              vpi_get(vpiLeftRange, item),
		                              vpi_get(vpiRightRange, item),
		                              LT_SYM_F_BITS);
		  info->scheduled = 0;

		  cb.time      = &info->time;
		  cb.user_data = (char*)info;
		  cb.value     = NULL;
		  cb.obj       = item;
		  cb.reason    = cbValueChange;
		  cb.cb_rtn    = variable_cb_1;

		  info->next  = vcd_list;
		  vcd_list    = info;

		  info->cb    = vpi_register_cb(&cb);

	    } else {
		  char *n = create_full_name(name);
		  lt_symbol_alias(dump_file, ident, n,
				  vpi_get(vpiSize, item)-1, 0);
		  free(n);
            }

	    break;

	  case vpiRealVar:

            if (skip || vpi_get(vpiAutomatic, item)) break;

	    name = vpi_get_str(vpiName, item);
	    { char*tmp = create_full_name(name);
	      ident = strdup_sh(&name_heap, tmp);
	      free(tmp);
	    }
	    info = malloc(sizeof(*info));

	    info->time.type = vpiSimTime;
	    info->item = item;
	    info->sym  = lt_symbol_add(dump_file, ident,
	                               0 /* array rows */,
	                               vpi_get(vpiSize, item)-1,
	                               0, LT_SYM_F_DOUBLE);
	    info->scheduled = 0;

	    cb.time      = &info->time;
	    cb.user_data = (char*)info;
	    cb.value     = NULL;
	    cb.obj       = item;
	    cb.reason    = cbValueChange;
	    cb.cb_rtn    = variable_cb_1;

	    info->next  = vcd_list;
	    vcd_list    = info;

	    info->cb    = vpi_register_cb(&cb);

	    break;

	  case vpiModule:
	  case vpiGenScope:
	  case vpiFunction:
	  case vpiTask:
	  case vpiNamedBegin:
	  case vpiNamedFork:

	    if (depth > 0) {
		  const char* fullname = vpi_get_str(vpiFullName, item);
		  /* list of types to iterate upon */
		  static int types[] = {
			/* Value */
			/* vpiNamedEvent, */
			vpiNet,
			/* vpiParameter, */
			vpiReg,
			vpiVariables,
			/* Scope */
			vpiFunction,
			vpiGenScope,
			vpiModule,
			vpiNamedBegin,
			vpiNamedFork,
			vpiTask,
			-1
		  };
		  int i;
		  int nskip = (vcd_names_search(&lxt_tab, fullname) != 0);

#if 0
		  vpi_printf("LXT info: scanning scope %s, %u levels\n",
		             fullname, depth);
#endif

		  if (nskip) {
			vpi_printf("LXT warning: ignoring signals in "
			           "previously scanned scope %s\n", fullname);
		  } else {
			vcd_names_add(&lxt_tab, fullname);
		  }

		  name = vpi_get_str(vpiName, item);

                  push_scope(name);

		  for (i=0; types[i]>0; i++) {
			vpiHandle hand;
			vpiHandle argv = vpi_iterate(types[i], item);
			while (argv && (hand = vpi_scan(argv))) {
			      scan_item(depth-1, hand, nskip);
			}
		  }

                  pop_scope();
	    }
	    break;

	  default:
	    vpi_printf("LXT warning: $dumpvars: Unsupported parameter "
	               "type (%s)\n", vpi_get_str(vpiType, item));
      }

}
예제 #3
0
/*************************************************
  lxt_incinit
    - close current file and open a new one
      maintaining the same trace info
 ************************************************/
static void lxt_incinit()
{
    char* filename;
    char* dot;
    info_p info;
#if DEBUG
    io_printf( "lxt_incinit: %p\n", lxt.t );
#endif
    /*
     * pinch off old file
     */
    lxt_timemarker();
    lt_close( lxt.t );

    /*
     * create new filename
     */
    lxt.hunk++;
    filename = (char*)malloc( strlen(lxt.filename)+10+1 );
    dot = rindex( lxt.filename, '.' );
    *dot = 0;
    if( lxt.hunk > 1 ) {
	dot = rindex( lxt.filename, '-' );
	*dot = 0;
    }
    sprintf( filename, "%s-%d.lxt", lxt.filename, lxt.hunk );
    free( lxt.filename );
    lxt.filename = filename;

    /*
     * open new wave file
     */
    lxt.t = lt_init( filename );
    if( !lxt.t ) {
	tf_error( "could not create file '%s'", filename );
        tf_dofinish();
	return;
    }
    lt_set_clock_compress( lxt.t );
    if( lxt.compress ) {
//	lt_set_chg_compress( lxt.t ); 
    }
    lxt.updateList = 0;
    lxt.eventList  = 0;
    lt_set_initial_value( lxt.t, 'x' );
    lt_symbol_bracket_stripping( lxt.t, 1 );
    lt_set_timescale( lxt.t, acc_fetch_precision() );
    lxt_timemarker(); 

    /*
     * add existing objects to new file
     */
    info = lxt.objectList;
    while( info ) {
	int flags;
	int msb;
	int lsb;
	if( info->real ) {
	    flags = LT_SYM_F_DOUBLE;
	} else {
	    flags = LT_SYM_F_BITS;
	}
	if( info->real ) {
	   info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
	} else if( info->event ) {
	   	info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
	} else {
	    acc_fetch_range( info->object, &msb, &lsb );
	    info->symbol = lt_symbol_add( lxt.t, info->name, 0, msb, lsb, flags );
	}
	info = info->next;
    }
    if( lxt.compress ) {
	lt_set_no_interlace( lxt.t );
    }
    lxt_dump( lxt.objectList, 1 );
}
예제 #4
0
파일: vcd_saver.c 프로젝트: acklinr/gtkwave
/*
 * 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);
}
예제 #5
0
/*************************************************
  lxt_add
    - add object to file
 ************************************************/
static void lxt_add( handle object, int depth )
{
    int	   real  = 0;
    int	   event = 0;
    int	   flags;
    int    msb;
    int	   lsb;
    info_p info;
    handle block;
    handle term;
    static int filter[] = {
	accIntegerVar,
	accNamedEvent,
	accNet,
	accRealVar,
	accRegister,
	accTimeVar,
	0
    };

    switch( acc_fetch_type(object) ) {
    case accNamedEvent:
	flags = LT_SYM_F_BITS;
	event = 1;
	break;
    case accRealVar:
	flags = LT_SYM_F_DOUBLE;
        real = 1;
	break;
    case accIntegerVar:
    case accNet:
    case accPort:
    case accReg:
    case accTimeVar:
    case accParameter:
	flags = LT_SYM_F_BITS;
	break;
    case accStatement:
    case accTask:
    case accModule:
	term = null;
	while(1) {
	    term = acc_next( filter, object, term );
	    if( term == null ) {
		break;
	    }
	    lxt_add( term, depth );
	} 
	if( depth == 1 ) {
	    return;
	}
	block = null;
	while(1) {
	    block = acc_next_child( object, block );
	    if( block == null ) {
		break;
	    }
	    lxt_add( block, (depth==0) ? 0 : depth-1 );
	} 
	return;
    default:
	return;
    }	
    info = (info_p)malloc( sizeof(info_t) );
    if( !info ) {
	tf_error( "cannot allocate memory" );
        tf_dofinish();
	return;
    }
    info->object     = object;
    info->name       = strdup( acc_fetch_fullname(object) );
    info->next       = lxt.objectList;
    lxt.objectList   = info;
    info->sequence   = lxt.sequence;
    info->event      = event;
    info->real	     = real;
    info->updateNext = 0;

    if( real ) {
    	info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else if( event ) {
    	info->symbol = lt_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else {
    	acc_fetch_range( object, &msb, &lsb );
#if DEBUG
	io_printf( "lxt_add: %s [ %d : %d ]\n", 
		info->name, msb, lsb );
#endif
    	info->symbol = lt_symbol_add( lxt.t, info->name, 0, msb, lsb, flags );
    }
    acc_vcl_add( object, lxt_changed, (char*)info, vcl_verilog_logic );
#if DEBUG
    io_printf( "lxt_recordvars: adding %p %s\n", info->symbol, info->name );
#endif
}