Beispiel #1
0
static PLI_INT32 simbus_connect_compiletf(char*my_name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

      /* Check that there is an argument and that it is a string. */
      if (argv == 0) {
            vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s requires a single string argument.\n", my_name);
            vpi_control(vpiFinish, 1);
            return 0;
      }

      if (! is_string_obj(vpi_scan(argv))) {
            vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s's argument must be a constant string.\n", my_name);
            vpi_control(vpiFinish, 1);
      }

      /* Make sure there are no extra arguments. */
      while (vpi_scan(argv)) { ; }

      return 0;
}
Beispiel #2
0
static PLI_INT32 one_darray_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv;
      vpiHandle arg;

      argv = vpi_iterate(vpiArgument, callh);
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires a string argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      arg =  vpi_scan(argv);
      if (arg == 0) return 0;

      arg = vpi_scan(argv);
      if (arg != 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s has too many arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      return 0;
}
Beispiel #3
0
static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data)
{
  vpiHandle reg_iter, reg_handle;
  s_vpi_time verilog_time_s;
  char buf[MAXLINE];
  char s[MAXWIDTH];
  int n;

  static int from_myhdl_flag = 0;

  if (from_myhdl_flag) {
    vpi_printf("ERROR: $from_myhdl called more than once\n");
    vpi_control(vpiFinish, 1);  /* abort simulation */
    return(0);
  }
  from_myhdl_flag = 1;

  init_pipes();

  verilog_time_s.type = vpiSimTime;
  vpi_get_time(NULL, &verilog_time_s);
  verilog_time = timestruct_to_time(&verilog_time_s);
  if (verilog_time != 0) {
    vpi_printf("ERROR: $from_myhdl should be called at time 0\n");
    vpi_control(vpiFinish, 1);  /* abort simulation */
    return(0);
  }
  sprintf(buf, "FROM 0 ");
  pli_time = 0;
  delta = 0;

  from_myhdl_systf_handle = vpi_handle(vpiSysTfCall, NULL);
  reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle);
  while ((reg_handle = vpi_scan(reg_iter)) != NULL) {
    if (vpi_get(vpiType, reg_handle) != vpiReg) {
      vpi_printf("ERROR: $from_myhdl argument %s should be a reg\n",
		 vpi_get_str(vpiName, reg_handle));
      vpi_control(vpiFinish, 1);  /* abort simulation */
      return(0);
    }
    strcat(buf, vpi_get_str(vpiName, reg_handle));
    strcat(buf, " ");
    sprintf(s, "%d ", vpi_get(vpiSize, reg_handle));
    strcat(buf, s);
    vpi_free_object(reg_handle);
  }
  //vpi_free_object(reg_iter);

  n = write(wpipe, buf, strlen(buf));  

  if ((n = read(rpipe, buf, MAXLINE)) == 0) {
    vpi_printf("Info: MyHDL simulator down\n");
    vpi_control(vpiFinish, 1);  /* abort simulation */
    return(0);
  }
  assert(n > 0);
  buf[n] = '\0';

  return(0);
}
Beispiel #4
0
static int init_pipes()
{
  char *w;
  char *r;

  static int init_pipes_flag = 0;

  if (init_pipes_flag) {
    return(0);
  }

  if ((w = getenv("MYHDL_TO_PIPE")) == NULL) {
    vpi_printf("ERROR: no write pipe to myhdl\n");
    vpi_control(vpiFinish, 1);  /* abort simulation */
    return(0);
  }
  if ((r = getenv("MYHDL_FROM_PIPE")) == NULL) {
    vpi_printf("ERROR: no read pipe from myhdl\n");
    vpi_control(vpiFinish, 1);  /* abort simulation */
    return(0);
  }
  wpipe = atoi(w);
  rpipe = atoi(r);
  init_pipes_flag = 1;
  return (0);
}
Beispiel #5
0
static PLI_INT32 sys_fscanf_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

	/* Check that there are arguments. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires at least three argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* The first argument must be a file descriptor. */
      if (! is_numeric_obj(vpi_scan(argv))) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's first argument (fd) must be numeric.\n", name);
	    vpi_control(vpiFinish, 1);
	    vpi_free_object(argv);
	    return 0;
      }

      if (sys_check_args(callh, argv, name)) vpi_control(vpiFinish, 1);
      return 0;
}
Beispiel #6
0
static PLI_INT32 sys_sdf_annotate_compiletf(PLI_BYTE8*name)
{
      check_command_line_args();

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

      vpiHandle path = vpi_scan(argv);
      if (path == 0) {
	    vpi_printf("SDF ERROR: First argument of %s is required.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      assert(path);

      vpiHandle scope = vpi_scan(argv);
      if (scope == 0)
	    return 0;

      if (vpi_get(vpiType,scope) != vpiModule) {
	    vpi_printf("SDF ERROR: The second argument of %s"
		       " must be a module instance.\n", name);
	    vpi_control(vpiFinish, 1);
      }

      vpi_free_object(argv);

      return 0;
}
Beispiel #7
0
static PLI_INT32 simbus_poll_compiletf(char*my_name)
{
      vpiHandle sys  = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, sys);

      vpiHandle bus_h = vpi_scan(argv);
      if (bus_h == 0) {
	    vpi_printf("%s:%d: Missing argument to $simbus_poll function\n",
		       vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys));
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      vpiHandle trig = vpi_scan(argv);
      if (trig == 0) {
	    vpi_printf("%s:%d: Missing argument to $simbus_poll function\n",
		       vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys));
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      if (vpi_get(vpiType, trig) != vpiReg || vpi_get(vpiSize, trig) != 1) {
	    vpi_printf("%s:%d: Trigger argument to $simbus_poll must be a single-bit reg.\n",
		       vpi_get_str(vpiFile, sys), (int)vpi_get(vpiLineNo, sys));
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      vpi_free_object(argv);

      return 0;
}
Beispiel #8
0
/* For system tasks/functions that take a single string argument. */
PLI_INT32 sys_one_string_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

      /* Check that there is an argument and that it is a string. */
      if (argv == 0) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s requires a single string argument.\n", name);
            vpi_control(vpiFinish, 1);
            return 0;
      }
      if (! is_string_obj(vpi_scan(argv))) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s's argument must be a string.\n", name);
            vpi_control(vpiFinish, 1);
      }

      /* Make sure there are no extra arguments. */
      check_for_extra_args(argv, callh, name, "a single string argument", 0);

      return 0;
}
Beispiel #9
0
static PLI_INT32 sys_finish_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh, argv;
      s_vpi_value val;
      long diag_msg = 1;

      /* Get the argument list and look for the diagnostic message level. */
      callh = vpi_handle(vpiSysTfCall, 0);
      argv = vpi_iterate(vpiArgument, callh);
      if (argv) {
            vpiHandle arg = vpi_scan(argv);
            vpi_free_object(argv);
            val.format = vpiIntVal;
            vpi_get_value(arg, &val);
            diag_msg = val.value.integer;
      }

      if (strcmp((const char*)name, "$stop") == 0) {
	    vpi_control(vpiStop, diag_msg);
	    return 0;
      }

      vpi_control(vpiFinish, diag_msg);
      return 0;
}
Beispiel #10
0
/* For system tasks/functions that take two numeric arguments. */
PLI_INT32 sys_two_numeric_args_compiletf(PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

      /* Check that there are two argument and that they are numeric. */
      if (argv == 0) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s requires two numeric arguments.\n", name);
            vpi_control(vpiFinish, 1);
            return 0;
      }

      if (! is_numeric_obj(vpi_scan(argv))) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s's first argument must be numeric.\n", name);
            vpi_control(vpiFinish, 1);
      }

      arg = vpi_scan(argv);
      if (! arg) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s requires a second (numeric) argument.\n", name);
            vpi_control(vpiFinish, 1);
            return 0;
      }

      if (! is_numeric_obj(arg)) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s's second argument must be numeric.\n", name);
            vpi_control(vpiFinish, 1);
      }

      /* Make sure there are no extra arguments. */
      if (vpi_scan(argv) != 0) {
	    char msg [64];
	    unsigned argc;

	    snprintf(msg, 64, "ERROR: %s:%d:",
	             vpi_get_str(vpiFile, callh),
	             (int)vpi_get(vpiLineNo, callh));

	    argc = 1;
	    while (vpi_scan(argv)) argc += 1;

            vpi_printf("%s %s takes two numeric arguments.\n", msg, name);
            vpi_printf("%*s Found %u extra argument%s.\n",
	               (int) strlen(msg), " ", argc, argc == 1 ? "" : "s");
            vpi_control(vpiFinish, 1);
      }

      return 0;
}
Beispiel #11
0
static PLI_INT32 ivlh_attribute_event_compiletf(ICARUS_VPI_CONST PLI_BYTE8*data)
{
      event_type_t type = (event_type_t) data;
      vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, sys);
      vpiHandle arg;
      struct monitor_data*mon;
      struct t_cb_data cb;
      struct t_vpi_time tb;
      struct t_vpi_value vb;

	/* Check that there are arguments. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys),
	               (int)vpi_get(vpiLineNo, sys));
	    vpi_printf("(compiler error) %s requires a single argument.\n",
	               func_names[type]);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Icarus either returns 0 above or has one argument. */
      arg = vpi_scan(argv);
      assert(arg);

      mon = malloc(sizeof(struct monitor_data));
	/* Add this to the list of data. */
      mdata_count += 1;
      mdata = (struct monitor_data **) realloc(mdata,
                                               sizeof(struct monitor_data **) *
                                               mdata_count);
      mdata[mdata_count-1] = mon;

      tb.type = vpiSimTime;
      vb.format = vpiScalarVal;
      cb.reason = cbValueChange;
      cb.cb_rtn = monitor_events;
      cb.obj = arg;
      cb.time = &tb;
      cb.value = &vb;
      cb.user_data = (char*) (mon);
      vpi_register_cb(&cb);
      vpi_put_userdata(sys, mon);

	/* Check that there is no more than one argument. */
      arg = vpi_scan(argv);
      if (arg != 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, sys),
	               (int)vpi_get(vpiLineNo, sys));
	    vpi_printf("(compiler error) %s only takes a single argument.\n",
	               func_names[type]);
	    vpi_free_object(argv);
	    vpi_control(vpiFinish, 1);
      }

      return 0;
}
Beispiel #12
0
static PLI_INT32 sys_value_plusargs_compiletf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

	/* Check that there are arguments. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires two arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Check that the first argument is a string. */
      arg = vpi_scan(argv);
      assert(arg != 0);
      if ( ! is_string_obj(arg)) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's first argument must be a string.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      arg = vpi_scan(argv);
      if (! arg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's requires a second variable argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      switch (vpi_get(vpiType, arg)) {

	  case vpiReg:
	  case vpiIntegerVar:
	  case vpiRealVar:
	  case vpiTimeVar:
	    break;

	  default:
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's second argument must be a variable, found a %s.\n",
		       name, vpi_get_str(vpiType, arg));
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Make sure there are no extra arguments. */
      check_for_extra_args(argv, callh, name, "two arguments", 0);

      return 0;
}
Beispiel #13
0
/*
 * Implement the $fopen system function.
 */
static PLI_INT32 sys_fopen_compiletf(PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv;
      vpiHandle arg;
      assert(callh != 0);
      argv = vpi_iterate(vpiArgument, callh);

	/* Check that there is a file name argument and that it is a string. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires a string file name argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }
      if (! is_string_obj(vpi_scan(argv))) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's file name argument must be a string.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* The type argument is optional. */
      arg = vpi_scan(argv);
      if (arg == 0) return 0;

	/* When provided, the type argument must be a string. */
      if (! is_string_obj(arg)) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's type argument must be a string.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* Make sure there are no extra arguments. */
      if (vpi_scan(argv) != 0) {
	    char msg [64];
	    unsigned argc;

	    snprintf(msg, 64, "ERROR: %s:%d:",
	             vpi_get_str(vpiFile, callh),
	             (int)vpi_get(vpiLineNo, callh));

	    argc = 1;
	    while (vpi_scan(argv)) argc += 1;

	    vpi_printf("%s %s takes at most two string arguments.\n",
	               msg, name);
	    vpi_printf("%*s Found %u extra argument%s.\n",
	               (int) strlen(msg), " ", argc, argc == 1 ? "" : "s");
	    vpi_control(vpiFinish, 1);
      }

      return 0;
}
Beispiel #14
0
/*
 * Implement the $ferror system function.
 */
static PLI_INT32 sys_ferror_compiletf(PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv;
      vpiHandle arg;

      argv = vpi_iterate(vpiArgument, callh);

	/*
	 * Check that there are two arguments and that the first is
	 * numeric and that the second is a 640 bit or larger register.
	 *
	 * The parser requires that a function have at least one argument,
	 * so argv should always be defined with one argument.
	 */
      assert(argv);

      if (! is_numeric_obj(vpi_scan(argv))) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's fd (first) argument must be numeric.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* Check that the second argument is given and that it is a 640 bit
	 * or larger register. */
      arg = vpi_scan(argv);
      if (! arg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires a second (register) argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      if (vpi_get(vpiType, arg) != vpiReg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's second argument must be a reg (>=640 bits).\n",
	                name);
	    vpi_control(vpiFinish, 1);
      } else if (vpi_get(vpiSize, arg) < 640) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's second argument must have 640 bit or more.\n",
	               name);
	    vpi_control(vpiFinish, 1);
      }

	/* Make sure there are no extra arguments. */
      check_for_extra_args(argv, callh, name, "two arguments", 0);

      return 0;
}
Beispiel #15
0
/*
 * Standard error message routine. The format string must take one
 * string argument (the name of the function).
 */
static void va_error_message(vpiHandle callh, const char *format,
                             const char *name) {
    vpi_printf("%s:%d: error: ", vpi_get_str(vpiFile, callh),
               (int)vpi_get(vpiLineNo, callh));
    vpi_printf(format, name);
    vpi_control(vpiFinish, 1);
}
Beispiel #16
0
static PLI_INT32 number_compiletf(PLI_BYTE8 *x)
#endif
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;
      char *name;

      s_vpi_value var;

      (void)x;  /* Parameter is not used. */

      if (argv == 0) {
	    vpi_printf("ERROR: missing required numeric argument.\n"),
	    vpi_control(vpiFinish, 1);
	    return 0;
      }
      arg = vpi_scan(argv);

	/* Check to see what vpi_get_value does during compiletf. */
      name = vpi_get_str(vpiName, arg);
      vpi_printf("vpi_get_value (%s):\n", name ? name : "<N/A>");
      var.format = vpiObjTypeVal;
      vpi_get_value(arg, &var);
      vpi_printf("  format = %d\n", (int) var.format);
      var.format = vpiDecStrVal;
      vpi_get_value(arg, &var);
      vpi_printf("   value = %s\n", var.value.str);

      vpi_free_object(argv);
      return 0;
}
Beispiel #17
0
static void error_message(vpiHandle callh, const char* msg)
{
    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
               (int)vpi_get(vpiLineNo, callh));
    vpi_printf(msg, vpi_get_str(vpiName, callh));
    vpi_control(vpiFinish, 1);
}
Beispiel #18
0
/*
 * Routine to return the current hierarchical path (implements %m).
 */
static int scan_format_module_path(vpiHandle callh, vpiHandle argv,
                                   unsigned suppress_flag, PLI_BYTE8 *name)
{
      vpiHandle scope, arg;
      char *module_path;
      s_vpi_value val;

	/* If this format code is being suppressed then just return that no
	 * arguments were used. */
      if (suppress_flag) return -1;

	/* We must have a variable to put the hierarchical path into. */
      arg = vpi_scan(argv);
      if (! arg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s() ran out of variables for %%m format code.", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Get the current hierarchical path. */
      scope = vpi_handle(vpiScope, callh);
      assert(scope);
      module_path = vpi_get_str(vpiFullName, scope);

	/* Put the hierarchical path into the variable. */
      val.format = vpiStringVal;
      val.value.str = module_path;
      vpi_put_value(arg, &val, 0, vpiNoDelay);

	/* We always consume one variable if it is available. */
      return 1;
}
Beispiel #19
0
/* For system tasks/functions that do not take an argument. */
PLI_INT32 sys_no_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

      /* Make sure there are no arguments. */
      if (argv != 0) {
	    char msg[64];
	    unsigned argc;

	    snprintf(msg, sizeof(msg), "ERROR: %s:%d:",
	             vpi_get_str(vpiFile, callh),
	             (int)vpi_get(vpiLineNo, callh));
	    msg[sizeof(msg)-1] = 0;

	    argc = 0;
	    while (vpi_scan(argv)) argc += 1;

            vpi_printf("%s %s does not take an argument.\n", msg, name);
            vpi_printf("%*s Found %u extra argument%s.\n",
	               (int) strlen(msg), " ", argc, argc == 1 ? "" : "s");
            vpi_control(vpiFinish, 1);
      }

      return 0;
}
Beispiel #20
0
/*
 * Runtime routine for the $table_model().
 */
static PLI_INT32 sys_table_model_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      s_vpi_value val;
      p_table_mod table;
      unsigned idx;
      double result;

	/* Retrieve the table data. */
      table = vpi_get_userdata(callh);

	/* If this is the first call then build the data structure. */
      if ((table->have_fname == 0) &&
          initialize_table_model(callh, name, table)) {
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Load the current argument values into the table structure. */
      for (idx = 0; idx < table->dims; idx += 1) {
	    val.format = vpiRealVal;
	    vpi_get_value(table->indep[idx], &val);
	    table->indep_val[idx] = val.value.real;
      }

	/* Interpolate/extrapolate the data structure to find the value. */
      result = eval_table_model(callh, table);

	/* Return the calculated value. */
      val.format = vpiRealVal;
      val.value.real = result;
      vpi_put_value(callh, &val, 0, vpiNoDelay);

      return 0;
}
Beispiel #21
0
/*
 * Check to see if an argument is a variable.
 */
static void check_var_arg(vpiHandle arg, vpiHandle callh, const char *name,
                          const char *arg_name)
{
      assert(arg);

      switch (vpi_get(vpiType, arg)) {
	  case vpiPartSelect:
            if (vpi_get(vpiType, vpi_handle(vpiParent, arg)) == vpiNet)
                  break;
	  case vpiMemoryWord:
	  case vpiBitVar:
	  case vpiReg:
	  case vpiIntegerVar:
	  case vpiIntVar:
	  case vpiLongIntVar:
	  case vpiTimeVar:
	    return;
	  default:
            break;
      }
      vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                 (int)vpi_get(vpiLineNo, callh));
      vpi_printf("%s's %s argument must be a variable.\n",
                 name, arg_name);
      vpi_control(vpiFinish, 1);
}
Beispiel #22
0
static int s1AssemblerCompiletf(char*user_data)
{
  vpiHandle systf_handle;
  vpiHandle arg_itr;
  vpiHandle arg_handle;
  PLI_INT32 tfarg_type;
  int err_flag = 0;

  systf_handle = vpi_handle(vpiSysTfCall, NULL);
  arg_itr = vpi_iterate(vpiArgument, systf_handle);
  if (arg_itr == NULL) {
    vpi_printf("ERROR: $s1Assember requires 1 argument. has none.\n");
    err_flag = 1;
  }
  arg_handle = vpi_scan(arg_itr);
  tfarg_type = vpi_get(vpiType, arg_handle);
  if (tfarg_type != vpiConstant &&
      tfarg_type != vpiStringVal &&
      tfarg_type != vpiReg) {
    vpi_printf("$s1Assember argument must be a string.\n");
    vpi_printf("            tfarg_type is %0d\n", tfarg_type);
    err_flag = 1;
  }
  if (vpi_scan(arg_itr) != NULL) {
    vpi_printf("ERROR: $s1Assember requires 1 argument. has too many.\n");
  }

  if (err_flag) {
    vpi_control(vpiFinish, 1);
  }

  return 0;
}
Beispiel #23
0
static void open_dumpfile(vpiHandle callh)
{
      if (dump_path == 0) dump_path = strdup("dump.lxt");

      dump_file = lt_init(dump_path);

      if (dump_file == 0) {
	    vpi_printf("LXT Error: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("Unable to open %s for output.\n", dump_path);
	    vpi_control(vpiFinish, 1);
	    return;
      } else {
	    int prec = vpi_get(vpiTimePrecision, 0);

	    vpi_printf("LXT info: dumpfile %s opened for output.\n",
	               dump_path);

	    assert(prec >= -15);
	    lt_set_timescale(dump_file, prec);

	    lt_set_initial_value(dump_file, 'x');
	    lt_set_clock_compress(dump_file);

            atexit((void(*)(void))close_dumpfile);
      }
}
Beispiel #24
0
/*
 * Check that the function is called with the correct argument.
 */
static PLI_INT32 sys_clog2_compiletf(PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv, arg;

      assert(callh != 0);
      argv = vpi_iterate(vpiArgument, callh);
      (void) name;  /* Not used! */

	/* We must have an argument. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("$clog2 requires one numeric argument.\n");
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* The argument must be numeric. */
      arg = vpi_scan(argv);
      if (! is_numeric_obj(arg)) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("The first argument to $clog2 must be numeric.\n");
	    vpi_control(vpiFinish, 1);
      }

	/* We can have a maximum of one argument. */
      if (vpi_scan(argv) != 0) {
	    char msg [64];
	    unsigned argc;

	    snprintf(msg, 64, "ERROR: %s:%d:",
	             vpi_get_str(vpiFile, callh),
	             (int)vpi_get(vpiLineNo, callh));

	    argc = 1;
	    while (vpi_scan(argv)) argc += 1;

            vpi_printf("%s $clog2 takes at most one argument.\n", msg);
            vpi_printf("%*s Found %u extra argument%s.\n",
	               (int) strlen(msg), " ", argc, argc == 1 ? "" : "s");
            vpi_control(vpiFinish, 1);
      }

      return 0;
}
Beispiel #25
0
static PLI_INT32 to_vec_compiletf(ICARUS_VPI_CONST PLI_BYTE8*user_data)
{
      (void) user_data; /* Parameter is not used. */

      vpiHandle systf_handle, arg_iterator, arg_handle;
      PLI_INT32 arg_type[2];

      /* obtain a handle to the system task instance */
      systf_handle = vpi_handle(vpiSysTfCall, NULL);
      if (systf_handle == NULL) {
          vpi_printf("ERROR: $ivl_darray_method$to_vec failed to obtain systf handle\n");
          vpi_control(vpiFinish,0); /* abort simulation */
          return 0;
      }

      /* obtain handles to system task arguments */
      arg_iterator = vpi_iterate(vpiArgument, systf_handle);
      if (arg_iterator == NULL) {
          vpi_printf("ERROR: $ivl_darray_method$to_vec requires 2 arguments\n");
          vpi_control(vpiFinish, 0);
          return 0;
      }

      /* check the type of object in system task arguments */
      arg_handle = vpi_scan(arg_iterator);
      for(int i = 0; i < 2; ++i) {
          arg_type[i] = vpi_get(vpiType, arg_handle);
          arg_handle = vpi_scan(arg_iterator);
      }

      if (arg_handle != NULL) {       /* are there more arguments? */
          vpi_printf("ERROR: $ivl_darray_method$to_vec can only have 2 arguments\n");
          vpi_free_object(arg_iterator);
          vpi_control(vpiFinish, 0);
          return 0;
      }

      if ((arg_type[0] != vpiRegArray) ||
          (arg_type[1] != vpiNet && arg_type[1] != vpiReg && arg_type[1] != vpiBitVar)) {
          vpi_printf("ERROR: $ivl_darray_method$to_vec value arguments must be a dynamic array and a net or reg\n");
          vpi_free_object(arg_iterator);
          vpi_control(vpiFinish, 0);
          return 0;
      }

      return 0;
}
Beispiel #26
0
static PLI_INT32 sys_fgets_compiletf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

	/*
	 * Check that there are two arguments and that the first is a
	 * register and that the second is numeric.
	 */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires two arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      if (vpi_get(vpiType, vpi_scan(argv)) != vpiReg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's first argument must be a reg.\n", name);
	    vpi_control(vpiFinish, 1);
      }

      arg = vpi_scan(argv);
      if (! arg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires a second (numeric) argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      if (! is_numeric_obj(arg)) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's second argument must be numeric.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* Make sure there are no extra arguments. */
      check_for_extra_args(argv, callh, name, "two arguments", 0);

      return 0;
}
Beispiel #27
0
static PLI_INT32 sys_deposit_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle target, value;

      /* Check that there are arguments. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires two arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      /* Check that there are at least two arguments. */
      target = vpi_scan(argv);  /* This should never be zero. */
      value = vpi_scan(argv);
      if (value == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires two arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

      assert(target);

      /* Check the targets type. It must be a net or a register. */
      switch (vpi_get(vpiType, target)) {
            case vpiNet:
            case vpiReg:
                  break;
            default:
		  vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
		             (int)vpi_get(vpiLineNo, callh));
		  vpi_printf("invalid target type (%s) for %s.\n",
		             vpi_get_str(vpiType, target), name);
		  vpi_control(vpiFinish, 1);
      }

      /* Check that there is at most two arguments. */
      check_for_extra_args(argv, callh, name, "two arguments", 0);

      return 0;
}
Beispiel #28
0
static PLI_INT32 sys_sdf_annotate_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall,0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle module;

      check_command_line_args();

	/* Check that we have a file name argument. */
      if (argv == 0) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s requires a file name argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }
      if (! is_string_obj(vpi_scan(argv))) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's file name must be a string.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* The module argument is optional. */
      module = vpi_scan(argv);
      if (module == 0) return 0;
      if (vpi_get(vpiType, module) != vpiModule) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s's second argument must be a module instance.\n",
	               name);
	    vpi_control(vpiFinish, 1);
      }

	/* Warn the user that we only use the first two arguments. */
      if (vpi_scan(argv) != 0) {
	    vpi_printf("WARNING: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s currently only uses the first two argument.\n",
	               name);
	    vpi_free_object(argv);
      }

      return 0;
}
Beispiel #29
0
/*
 * Routine to return a floating point value scaled and rounded to the
 * current time scale and precision (implements %t).
 *
 * Return: 1 for a match, 0 for no match/variable and -1 for a
 *         suppressed match. No variable is fatal.
 */
static int scan_format_float_time(vpiHandle callh, vpiHandle argv,
				  struct byte_source*src, unsigned width,
                                  unsigned suppress_flag, PLI_BYTE8 *name)
{
      vpiHandle scope = vpi_handle(vpiScope, callh);
      int time_units = vpi_get(vpiTimeUnit, scope);
      vpiHandle arg;
      int match;
      s_vpi_value val;
      double result;
      double scale;

	/* Get the raw real value. */
      result = get_float(src, width, &match);

	/* Nothing was matched. */
      if (match == 0) return 0;

	/* If this match is being suppressed then return after consuming
	 * the digits and report that no arguments were used. */
      if (suppress_flag) return -1;

	/* Round the raw value to the specified precision. Handle this
	   by shifting the decimal point to the precision where we want
	   to round, do the rounding, then shift the decimal point back */
      scale = pow(10.0, timeformat_info.prec);
      result = round(result*scale) / scale;

	/* Scale the value from the timeformat units to the current
	 * timescale units. To minimize the error keep the scale an
	 * integer value. */
      if (timeformat_info.units >= time_units) {
	    scale = pow(10.0, timeformat_info.units - time_units);
	    result *= scale;
      } else {
	    scale = pow(10.0, time_units - timeformat_info.units);
	    result /= scale;
      }

	/* We must have a variable to put the double value into. */
      arg = vpi_scan(argv);
      if (! arg) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s() ran out of variables for %%t format code.", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* Put the value into the variable. */
      val.format = vpiRealVal;
      val.value.real = result;
      vpi_put_value(arg, &val, 0, vpiNoDelay);

	/* We always consume one variable if it is available. */
      return 1;
}
Beispiel #30
0
static PLI_INT32 one_arg_array_compiletf(ICARUS_VPI_CONST PLI_BYTE8*user_data)
{
    (void) user_data; /* Parameter is not used. */

    vpiHandle systf_handle, arg_iterator, arg_handle;
    PLI_INT32 arg_type;

    /* obtain a handle to the system task instance */
    systf_handle = vpi_handle(vpiSysTfCall, NULL);
    if (systf_handle == NULL) {
        vpi_printf("ERROR: $display_array failed to obtain systf handle\n");
        vpi_control(vpiFinish,0); /* abort simulation */
        return 0;
    }

    /* obtain handles to system task arguments */
    arg_iterator = vpi_iterate(vpiArgument, systf_handle);
    if (arg_iterator == NULL) {
        vpi_printf("ERROR: $display_array requires exactly 1 argument\n");
        vpi_control(vpiFinish, 0);
        return 0;
    }

    /* check the type of object in system task arguments */
    arg_handle = vpi_scan(arg_iterator);
    if (vpi_scan(arg_iterator) != NULL) {       /* are there more arguments? */
        vpi_printf("ERROR: $display_array takes only 1 argument\n");
        vpi_free_object(arg_iterator);
        vpi_control(vpiFinish, 0);
        return 0;
    }

    arg_type = vpi_get(vpiType, arg_handle);
    if (arg_type != vpiArrayType && arg_type != vpiRegArray &&
            arg_type != vpiMemory) {
        vpi_printf("%d", arg_type); // TODO remove
        vpi_printf("ERROR: $display_array works only with arrays\n");
        vpi_free_object(arg_iterator);
        vpi_control(vpiFinish, 0);
        return 0;
    }

    return 0;
}