예제 #1
0
파일: vcd2lxt2.c 프로젝트: Pidbip/egtkwave
/*
 * alias vs normal symbol adding
 */
static void alias_vs_normal_symadd(struct vcdsymbol *v, struct vcdsymbol *root_v)
{
if(!root_v) 
	{
	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));
		}
	}
	else
	{
	if((v->vartype==V_INTEGER)||(v->vartype==V_REAL))
		{
		lxt2_wr_symbol_alias(lt, root_v->name, v->name, v->msi, v->lsi);
		}
		else
		{
		char bufold[65537], buf[65537];
		if(v->msi==v->lsi)
			{
			sprintf(bufold, "%s[%d]", root_v->name, root_v->msi);
			sprintf(buf, "%s[%d]", v->name, v->msi);
			}
			else
			{
			sprintf(bufold, "%s[%d:%d]", root_v->name, root_v->msi, root_v->lsi);
			sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi);
			}
		lxt2_wr_symbol_alias(lt, bufold, buf, v->msi, v->lsi);
		}
	}
}
예제 #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;

      /* list of types to iterate upon */
      int i;
      static int types[] = {
	    /* Value */
	    vpiNet,
	    vpiReg,
	    vpiVariables,
	    /* Scope */
	    vpiFunction,
	    vpiModule,
	    vpiNamedBegin,
	    vpiNamedFork,
	    vpiTask,
	    -1
      };

      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("LXT2 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 = new_vcd_info();

		  info->item  = item;
		  info->sym   = lxt2_wr_symbol_add(dump_file, ident,
		                                   0 /* array rows */,
		                                   vpi_get(vpiLeftRange, item),
		                                   vpi_get(vpiRightRange, item),
		                                   LXT2_WR_SYM_F_BITS);
		  info->dmp_next = 0;

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

		  info->cb    = vpi_register_cb(&cb);

	    } else {
		  char *n = create_full_name(name);
		  lxt2_wr_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 = new_vcd_info();

	    info->item = item;
	    info->sym  = lxt2_wr_symbol_add(dump_file, ident,
	                                    0 /* array rows */,
	                                    vpi_get(vpiSize, item)-1,
	                                    0, LXT2_WR_SYM_F_DOUBLE);
	    info->dmp_next = 0;

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

	    info->cb    = vpi_register_cb(&cb);

	    break;

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

	    if (depth > 0) {
		  int nskip;
		  vpiHandle argv;

		  const char* fullname =
			vpi_get_str(vpiFullName, item);

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

		  if (!nskip)
			vcd_scope_names_add(fullname);
		  else
		    vpi_printf("LXT2 warning: ignoring signals in "
		               "previously scanned scope %s\n", fullname);

		  name = vpi_get_str(vpiName, item);

                  push_scope(name);

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

                  pop_scope();
	    }
	    break;

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

}
예제 #3
0
파일: vcd2lxt2.c 프로젝트: Pidbip/egtkwave
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"));
		}
	}
}
예제 #4
0
/*************************************************
  lxt2_add
    - add object to file
 ************************************************/
static void lxt2_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 = LXT2_WR_SYM_F_BITS;
	event = 1;
	break;
    case accRealVar:
	flags = LXT2_WR_SYM_F_DOUBLE;
        real = 1;
	break;
    case accIntegerVar:
    case accNet:
    case accPort:
    case accReg:
    case accTimeVar:
    case accParameter:
	flags = LXT2_WR_SYM_F_BITS;
	break;
    case accStatement:
    case accTask:
    case accModule:
	term = null;
	while(1) {
	    term = acc_next( filter, object, term );
	    if( term == null ) {
		break;
	    }
	    lxt2_add( term, depth );
	} 
	if( depth == 1 ) {
	    return;
	}
	block = null;
	while(1) {
	    block = acc_next_child( object, block );
	    if( block == null ) {
		break;
	    }
	    lxt2_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 = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else if( event ) {
    	info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, 0, 0, flags );
    } else {
    	acc_fetch_range( object, &msb, &lsb );
#if DEBUG
	io_printf( "lxt2_add: %s [ %d : %d ]\n", 
		info->name, msb, lsb );
#endif
    	info->symbol = lxt2_wr_symbol_add( lxt.t, info->name, 0, msb, lsb, flags );
    }
    acc_vcl_add( object, lxt2_changed, (char*)info, vcl_verilog_logic );
#if DEBUG
    io_printf( "lxt2_recordvars: adding %p %s\n", info->symbol, info->name );
#endif
}