Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/* For system tasks/functions that take a single numeric argument. */
PLI_INT32 sys_one_numeric_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 numeric. */
      if (argv == 0) {
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s requires a single numeric argument.\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 argument must be numeric.\n", name);
            vpi_control(vpiFinish, 1);
      }

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

      return 0;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/* For system tasks/functions that take two numeric arguments. */
PLI_INT32 sys_two_numeric_args_compiletf(ICARUS_VPI_CONST 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. */
      check_for_extra_args(argv, callh, name, "two numeric arguments", 0);

      return 0;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/* For system tasks/functions that take a single optional numeric argument. */
PLI_INT32 sys_one_opt_numeric_arg_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

      /* The argument is optional so just return if none are found. */
      if (argv == 0) 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 argument must be numeric.\n", name);
            vpi_control(vpiFinish, 1);
      }

      /* Make sure there are no extra arguments. */
      check_for_extra_args(argv, callh, name, "one numeric argument", 1);

      return 0;
}
Exemplo n.º 8
0
/* For system tasks/functions that take a single optional numeric argument. */
PLI_INT32 sys_one_opt_numeric_arg_compiletf(PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);

      /* The argument is optional so just return if none are found. */
      if (argv == 0) 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 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 at most one numeric 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;
}
Exemplo n.º 9
0
/*
 * Check that the given $table_model() call has valid arguments.
 */
static PLI_INT32 sys_table_model_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;
      p_table_mod table = create_table();

	/* See if there are any table model arguments. */
      check_command_line_flags();

	/* 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 two arguments.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

	/* The first N (dimensions) arguments must be numeric. */
      for (arg = vpi_scan(argv);
           arg && is_numeric_obj(arg);
           arg = vpi_scan(argv)) {
	    table->dims += 1;
	    table->indep = (vpiHandle *)realloc(table->indep,
	                                        sizeof(vpiHandle)*table->dims);
	    table->indep[table->dims-1] = arg;
      }

	/* We must have a data file. */
      if (arg == 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;
      }

	/* For now we only allow a constant string (file name). */
      if (! is_const_string_obj(arg)) {
	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
	               (int)vpi_get(vpiLineNo, callh));
	    vpi_printf("%s file name argument must be a constant string.\n",
	               name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }
      table->file.arg = arg;

	/* There may be an optional constant string (control string). */
      arg = vpi_scan(argv);
      if (arg) {
	    if (! is_const_string_obj(arg)) {
		  vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
		            (int)vpi_get(vpiLineNo, callh));
		  vpi_printf("%s control string argument must be a constant "
		             "string.\n", name);
		  vpi_control(vpiFinish, 1);
		  return 0;
	    }
	    check_for_extra_args(argv, callh, name, "N numeric and 1 or 2 "
	                         " constant string arguments", 0);
	    table->control.arg = arg;
      }

	/* Save the table data information. */
      vpi_put_userdata(callh, table);

      return 0;
}
Exemplo n.º 10
0
static PLI_INT32 sys_mem_compiletf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

      /* Check that there is 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 two arguments.\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 first argument must be a file name (string).\n",
	               name);
	    vpi_control(vpiFinish, 1);
      }

      /* Check that there is a memory argument. */
      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 (memory) argument.\n", name);
	    vpi_control(vpiFinish, 1);
	    return 0;
      }

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

      /* Check if there is a starting address argument. */
      arg = vpi_scan(argv);
      if (! arg) 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 third argument must be a start address "
	               "(numeric).\n", name);
	    vpi_control(vpiFinish, 1);
      }

      /* Check if there is a finish address argument. */
      arg = vpi_scan(argv);
      if (! arg) 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 fourth argument must be a finish address "
	               "(numeric).\n", name);
	    vpi_control(vpiFinish, 1);
      }

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

      return 0;
}
Exemplo n.º 11
0
/* $dumpvars takes a variety of arguments. */
PLI_INT32 sys_dumpvars_compiletf(ICARUS_VPI_CONST PLI_BYTE8 *name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

      /* No arguments is OK, dump everything. */
      if (argv == 0) return 0;

      /* The first argument is the numeric level. */
      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 argument must be numeric.\n", name);
            vpi_control(vpiFinish, 1);
      }

      /* The rest of the arguments are either a module or a variable. */
      while ((arg=vpi_scan(argv)) != NULL) {
        switch(vpi_get(vpiType, arg)) {
          case vpiMemoryWord:
/*
 * We need to allow non-constant selects to support the following:
 *
 * for (lp = 0; lp < max ; lp = lp + 1) $dumpvars(0, array[lp]);
 *
 * We need to do a direct callback on the selected element vs using
 * the &A<> structure. The later will not give us what we want.
 * This is implemented in the calltf routine.
 */
#if 0
            if (vpi_get(vpiConstantSelect, arg) == 0) {
		  vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
		             (int)vpi_get(vpiLineNo, callh));
		  vpi_printf("%s cannot dump a non-constant select %s.\n", name,
		             vpi_get_str(vpiType, arg));
		  vpi_control(vpiFinish, 1);
            }
#endif
          /* The module types. */
          case vpiModule:
          case vpiTask:
          case vpiFunction:
          case vpiNamedBegin:
          case vpiNamedFork:
          /* The variable types. */
#if 0
          case vpiParameter: /* A constant! */
#endif
          case vpiNet:
          case vpiReg:
          case vpiIntegerVar:
          case vpiTimeVar:
          case vpiRealVar:
          case vpiNamedEvent:
            break;

          case vpiParameter: /* A constant! */
            vpi_printf("SORRY: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s cannot currently dump a parameter.\n", name);
            break;

          default:
            vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
                       (int)vpi_get(vpiLineNo, callh));
            vpi_printf("%s cannot dump a %s.\n", name,
                       vpi_get_str(vpiType, arg));
            vpi_control(vpiFinish, 1);
        }
      }

      return 0;
}
Exemplo n.º 12
0
static PLI_INT32 sys_fseek_compiletf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;

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

	/* Check that the first argument is numeric. */
      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);
      }

	/* Check that the second argument exists and is numeric. */
      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);
      }

	/* Check that the third argument exists and is numeric. */
      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 third (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 third argument must be numeric.\n", name);
	    vpi_control(vpiFinish, 1);
      }

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

      return 0;
}
Exemplo n.º 13
0
static PLI_INT32 sys_fread_compiletf(PLI_BYTE8*name)
{
      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
      vpiHandle argv = vpi_iterate(vpiArgument, callh);
      vpiHandle arg;
      PLI_INT32 type;

	/* We must have at least two 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 required argument is a register or memory. */
      type = vpi_get(vpiType, vpi_scan(argv));
      if (type != vpiReg && type != vpiMemory) {
	    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 or memory.\n", name);
	    vpi_control(vpiFinish, 1);
      }

	/* Check that the second required argument is numeric (a fd). */
      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 (file descriptor) 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);
      }

	/*
	 * If given check that the third argument is numeric (start).
	 *
	 * Technically you can give the fourth argument (count) with
	 * out a third argument (start), but Icarus does not currently
	 * support missing function arguments!
	 */
      arg = vpi_scan(argv);
      if (arg) {
	    if (! is_numeric_obj(arg)) {
		  vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
		             (int)vpi_get(vpiLineNo, callh));
		  vpi_printf("%s's third argument must be numeric.\n", name);
		  vpi_control(vpiFinish, 1);
	    }

	      /* If given check that the fourth argument is numeric (count). */
	    arg = vpi_scan(argv);
	    if (arg) {
		  if (! is_numeric_obj(arg)) {
			vpi_printf("ERROR: %s:%d: ",
			           vpi_get_str(vpiFile, callh),
			           (int)vpi_get(vpiLineNo, callh));
			vpi_printf("%s's fourth argument must be numeric.\n",
			           name);
			vpi_control(vpiFinish, 1);
		  }

		    /* Make sure there are no extra arguments. */
		  check_for_extra_args(argv, callh, name, "four arguments", 1);
	    }
      }

      return 0;
}