Пример #1
0
/*
 * Implement $fclose system function
 */
static PLI_INT32 sys_fclose_calltf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle fd = vpi_scan(argv);
      s_vpi_value val;
      PLI_UINT32 fd_mcd;
      errno = 0;

      vpi_free_object(argv);

	/* Get the file/MC descriptor and verify that it is valid. */
      val.format = vpiIntVal;
      vpi_get_value(fd, &val);
      fd_mcd = val.value.integer;

      if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
          ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) ||
          (! fd_mcd)) {
	    vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
	               (unsigned int)fd_mcd, name);
	    errno = EBADF;
	    return 0;
      }

	/* We need to cancel any active $fstrobe()'s for this FD/MCD.
	 * For now we check in the strobe callback and skip the output
	 * generation when needed. */
      vpi_mcd_close(fd_mcd);

      return 0;
}
inline static int install_dumpvars_callback(void)
{
      struct t_cb_data cb;
      static struct t_vpi_time time;

      if (dumpvars_status == 1)
	    return 0;

      if (dumpvars_status == 2) {
	    vpi_mcd_printf(1, "VCD Error:"
			   " $dumpvars ignored,"
			   " previously called at simtime %" PLI_UINT64_FMT "\n",
			   dumpvars_time);
	    return 1;
      }

      time.type = vpiSimTime;
      cb.time = &time;
      cb.reason = cbReadOnlySynch;
      cb.cb_rtn = dumpvars_cb;
      cb.user_data = 0x0;
      cb.obj = 0x0;

      vpi_register_cb(&cb);

      dumpvars_status = 1;
      return 0;
}
Пример #3
0
int _mon_check_mcd() {
    PLI_INT32 status;

    PLI_UINT32 mcd;
    PLI_BYTE8* filename = (PLI_BYTE8*)"obj_dir/t_vpi_var/mcd_open.tmp";
    mcd = vpi_mcd_open(filename);
    CHECK_RESULT_NZ(mcd);

    {   // Check it got written
        FILE* fp = fopen(filename,"r");
        CHECK_RESULT_NZ(fp);
        fclose(fp);
    }

    status = vpi_mcd_printf(mcd, (PLI_BYTE8*)"hello %s", "vpi_mcd_printf");
    CHECK_RESULT(status, strlen("hello vpi_mcd_printf"));

    status = vpi_mcd_flush(mcd);
    CHECK_RESULT(status, 0);

    status = vpi_mcd_close(mcd);
    CHECK_RESULT(status, 0);

    status = vpi_flush();
    CHECK_RESULT(status, 0);

    return 0;
}
static void open_dumpfile(void)
{
      if (dump_path == 0) {
	    dump_path = strdup("dump.vcd");
      }

      dump_file = fopen(dump_path, "w");

      if (dump_file == 0) {
	    vpi_mcd_printf(1, 
			   "VCD Error: Unable to open %s for output.\n", 
			   dump_path);
	    return;
      } else {
	    int prec = vpi_get(vpiTimePrecision, 0);
	    unsigned scale = 1;
	    unsigned udx = 0;
	    time_t walltime;

	    vpi_mcd_printf(1, 
			   "VCD info: dumpfile %s opened for output.\n", 
			   dump_path);
	    
	    time(&walltime);

	    assert(prec >= -15);
	    while (prec < 0) {
		  udx += 1;
		  prec += 3;
	    }
	    while (prec > 0) {
		  scale *= 10;
		  prec -= 1;
	    }

	    fprintf(dump_file, "$date\n");
	    fprintf(dump_file, "\t%s",asctime(localtime(&walltime)));
	    fprintf(dump_file, "$end\n");
	    fprintf(dump_file, "$version\n");
	    fprintf(dump_file, "\tIcarus Verilog\n");
	    fprintf(dump_file, "$end\n");
	    fprintf(dump_file, "$timescale\n");
	    fprintf(dump_file, "\t%u%s\n", scale, units_names[udx]);
	    fprintf(dump_file, "$end\n");
      }
}
static int sys_dumpfile_compiletf(char*name)
{
      vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, sys);
      vpiHandle item;

      char*path;

      if (argv && (item = vpi_scan(argv))) {
	    s_vpi_value value;

	    if (vpi_get(vpiType, item) != vpiConstant
		|| vpi_get(vpiConstType, item) != vpiStringConst) {
		  vpi_mcd_printf(1, 
				 "VCD Error:"
				 " %s parameter must be a string constant\n", 
				 name);
		  return 0;
	    }

	    value.format = vpiStringVal;
	    vpi_get_value(item, &value);
	    path = strdup(value.value.str);

	    vpi_free_object(argv);

      } else {
	    path = strdup("dump.vcd");
      }

      if (dump_path) {
	    vpi_mcd_printf(1, "VCD Warning:"
			   " Overriding dumpfile path %s with %s\n",
			   dump_path, path);
	    free(dump_path);
      }

      dump_path = path;

      return 0;
}
static void open_dumpfile(const char*path)
{
      dump_file = fopen(path, "w");

      if (dump_file == 0) {
	    vpi_mcd_printf(6, 
			   "VCD Error: Unable to open %s for output.\n", 
			   path);
	    return;
      } else {
	    fprintf(dump_file, "VCD Dump suppressed.\n");
      }
}
Пример #7
0
/*
 * Implement $fflush system function
 */
static PLI_INT32 sys_fflush_calltf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;
      s_vpi_value val;
      PLI_UINT32 fd_mcd;
      FILE *fp;
      errno = 0;

	/* If we have no argument then flush all the streams. */
      if (argv == 0) {
	    fflush(NULL);
	    return 0;
      }

	/* Get the file/MC descriptor and verify that it is valid. */
      arg = vpi_scan(argv);
      vpi_free_object(argv);
      val.format = vpiIntVal;
      vpi_get_value(arg, &val);
      fd_mcd = val.value.integer;

	/* If the MCD is zero we have nothing to do so just return. */
      if (fd_mcd == 0) return 0;

      if ((! IS_MCD(fd_mcd) && vpi_get_file(fd_mcd) == NULL) ||
          ( IS_MCD(fd_mcd) && vpi_mcd_printf(fd_mcd, "%s", "") == EOF) ||
          (! fd_mcd)) {
	    vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("invalid file descriptor/MCD (0x%x) given to %s.\n",
	               (unsigned int)fd_mcd, name);
	    errno = EBADF;
	    return 0;
      }

      if (IS_MCD(fd_mcd)) {
	    vpi_mcd_flush(fd_mcd);
      } else {
	      /* If we have a valid file descriptor flush the file. */
	    fp = vpi_get_file(fd_mcd);
	    if (fp) fflush(fp);
      }

      return 0;
}
static int sys_dumpfile_calltf(char*name)
{
      char*path;

      vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, sys);
      vpiHandle item;

      if (argv && (item = vpi_scan(argv))) {
	    s_vpi_value value;

	    if (vpi_get(vpiType, item) != vpiConstant
		|| vpi_get(vpiConstType, item) != vpiStringConst) {
		  vpi_mcd_printf(6, 
				 "VCD Error:"
				 " %s parameter must be a string constant\n", 
				 name);
		  return 0;
	    }

	    value.format = vpiStringVal;
	    vpi_get_value(item, &value);
	    path = strdup(value.value.str);

	    vpi_free_object(argv);

      } else {
	    path = strdup("dumpfile.vcd");
      }

      if (dump_file) {
	    fclose(dump_file);
	    dump_file = 0;
      }

      assert(dump_file == 0);
      open_dumpfile(path);

      free(path);

      return 0;
}
static void scan_item(unsigned depth, vpiHandle item, int skip)
{
      struct t_cb_data cb;
      struct vcd_info* info;

      const char* type;
      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 vpiMemory:
	      /* don't know how to watch memories. */
	    break;

	  case vpiNamedEvent:
	      /* There is nothing in named events to dump. */
	    break;

	  case vpiNet:  type = "wire";    if(0){
	  case vpiIntegerVar:
	  case vpiTimeVar:
	  case vpiReg:  type = "reg";    }

	    if (skip)
		  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) {
		  ident = strdup(vcdid);
		  gen_new_vcd_id();
		  
		  if (nexus_id)
			set_nexus_ident(nexus_id, ident);
		  
		  info = malloc(sizeof(*info));

		  info->time.type = vpiSimTime;
		  info->item  = item;
		  info->ident = ident;
		  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;
		  info->dmp_next  = 0;
		  vcd_list    = info;

		  info->cb    = vpi_register_cb(&cb);
	    }
	    
	    fprintf(dump_file, "$var %s %u %s %s",
		    type, vpi_get(vpiSize, item), ident,
		    name);
      /* FIXME
	    if (vpi_get(vpiVector, item)
      */
	    if (vpi_get(vpiSize, item) > 1
		|| vpi_get(vpiLeftRange, item) != 0) {
		  fprintf(dump_file, "[%i:%i]", vpi_get(vpiLeftRange, item),
			  vpi_get(vpiRightRange, item));
	    }
	    fprintf(dump_file, " $end\n");
	    break;

	  case vpiRealVar:

	    if (skip)
		  break;

	      /* Declare the variable in the VCD file. */
	    name = vpi_get_str(vpiName, item);
	    ident = strdup(vcdid);
	    gen_new_vcd_id();
	    fprintf(dump_file, "$var real 1 %s %s $end\n",
		    ident, name);

	      /* Add a callback for the variable. */
	    info = malloc(sizeof(*info));

	    info->time.type = vpiSimTime;
	    info->item  = item;
	    info->ident = ident;
	    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;
	    info->dmp_next  = 0;
	    vcd_list    = info;

	    info->cb    = vpi_register_cb(&cb);

	    break;

	  case vpiModule:      type = "module";      if(0){
	  case vpiNamedBegin:  type = "begin";      }if(0){
	  case vpiTask:        type = "task";       }if(0){
	  case vpiFunction:    type = "function";   }if(0){
	  case vpiNamedFork:   type = "fork";       }

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

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

#if 0
		  vpi_mcd_printf(1, 
				 "VCD info:"
				 " scanning scope %s, %u levels\n",
				 fullname, depth);
#endif
		  nskip = 0 != vcd_names_search(&vcd_tab, fullname);
		  
		  if (!nskip) 
			vcd_names_add(&vcd_tab, fullname);
		  else 
		    vpi_mcd_printf(1,
				   "VCD warning:"
				   " ignoring signals"
				   " in previously scanned scope %s\n",
				   fullname);

		  name = vpi_get_str(vpiName, item);

		  fprintf(dump_file, "$scope %s %s $end\n", type, 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);
			}
		  }
		  
		  fprintf(dump_file, "$upscope $end\n");
	    }
	    break;
	    
	  default:
	    vpi_mcd_printf(1,
			   "VCD Error: $dumpvars: Unsupported parameter "
			   "type (%d)\n", vpi_get(vpiType, item));
      }
}
Пример #10
0
static void sys_lxt_or_vcd_register()
{
      int idx;
      struct t_vpi_vlog_info vlog_info;

      const char*dumper;

	/* Get the dumper of choice from the IVERILOG_DUMPER
	   environment variable. */
      dumper = getenv("IVERILOG_DUMPER");
      if (dumper) {
	    char*cp = strchr(dumper,'=');
	    if (cp != 0)
		  dumper = cp + 1;

      } else {
	    dumper = "vcd";
      }

	/* Scan the extended arguments, looking for flags that select
	   major features. This can override the environment variable
	   settings. */
      vpi_get_vlog_info(&vlog_info);

      for (idx = 0 ;  idx < vlog_info.argc ;  idx += 1) {

            if (strcmp(vlog_info.argv[idx],"-fst") == 0) {
		  dumper = "fst";

	    } else if (strcmp(vlog_info.argv[idx],"-fst-space") == 0) {
		  dumper = "fst";

	    } else if (strcmp(vlog_info.argv[idx],"-fst-speed") == 0) {
		  dumper = "fst";

	    } else if (strcmp(vlog_info.argv[idx],"-fst-space-speed") == 0) {
		  dumper = "fst";
	    } else if (strcmp(vlog_info.argv[idx],"-fst-speed-space") == 0) {
		  dumper = "fst";

	    } else if (strcmp(vlog_info.argv[idx],"-fst-none") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt") == 0) {
		  dumper = "lxt";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt-space") == 0) {
		  dumper = "lxt";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt-speed") == 0) {
		  dumper = "lxt";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt-none") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt2") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt2-space") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt2-speed") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lxt2-none") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-lx2") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lx2-space") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lx2-speed") == 0) {
		  dumper = "lxt2";

	    } else if (strcmp(vlog_info.argv[idx],"-lx2-none") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-vcd") == 0) {
		  dumper = "vcd";

	    } else if (strcmp(vlog_info.argv[idx],"-vcd-off") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-vcd-none") == 0) {
		  dumper = "none";

	    } else if (strcmp(vlog_info.argv[idx],"-none") == 0) {
		  dumper = "none";

	    }
      }

      if (strcmp(dumper, "vcd") == 0)
	    sys_vcd_register();

      else if (strcmp(dumper, "VCD") == 0)
	    sys_vcd_register();

      else if (strcmp(dumper, "fst") == 0)
	    sys_fst_register();

      else if (strcmp(dumper, "FST") == 0)
	    sys_fst_register();

      else if (strcmp(dumper, "lxt") == 0)
	    sys_lxt_register();

      else if (strcmp(dumper, "LXT") == 0)
	    sys_lxt_register();

      else if (strcmp(dumper, "lxt2") == 0)
	    sys_lxt2_register();

      else if (strcmp(dumper, "LXT2") == 0)
	    sys_lxt2_register();

      else if (strcmp(dumper, "lx2") == 0)
	    sys_lxt2_register();

      else if (strcmp(dumper, "LX2") == 0)
	    sys_lxt2_register();

      else if (strcmp(dumper, "none") == 0)
	    sys_vcdoff_register();

      else if (strcmp(dumper, "NONE") == 0)
	    sys_vcdoff_register();

      else {
	    vpi_mcd_printf(1, "system.vpi: Unknown dumper format: %s,"
		           " using VCD instead.\n", dumper);
	    sys_vcd_register();
      }
}