Example #1
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;
}
Example #2
0
static PLI_INT32 sys_rtoi_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
    vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
    vpiHandle arg  = (vpiHandle) vpi_get_userdata(callh);
    s_vpi_value value;
    static struct t_vpi_vecval res;
    double val;

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

    /* get value */
    value.format = vpiRealVal;
    vpi_get_value(arg, &value);

    /* If the value is NaN or +/- infinity then return 'bx */
    val = value.value.real;
    if (val != val || (val && (val == 0.5*val))) {
	res.aval = ~(PLI_INT32)0;
	res.bval = ~(PLI_INT32)0;
    } else {
	/* This is not 100% correct since large real values may break this
	 * code. See the verinum code for a more rigorous implementation. */
	if (val >= 0.0) res.aval = (PLI_UINT64) val;
	else res.aval = - (PLI_UINT64) -val;
	res.bval = 0;
    }

    value.format = vpiVectorVal;
    value.value.vector = &res;

    /* return converted value */
    vpi_put_value(callh, &value, 0, vpiNoDelay);

    return 0;
}
Example #3
0
static PLI_INT32 sys_realtobits_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
    vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
    vpiHandle arg  = (vpiHandle) vpi_get_userdata(callh);
    s_vpi_value value;
    static struct t_vpi_vecval res[2];

    PLI_UINT32 bits[2];

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

    /* get value */
    value.format = vpiRealVal;
    vpi_get_value(arg, &value);

    /* convert */
    double2bits(value.value.real, bits);

    res[0].aval = bits[0];
    res[0].bval = 0;
    res[1].aval = bits[1];
    res[1].bval = 0;

    value.format = vpiVectorVal;
    value.value.vector = res;

    /* return converted value */
    vpi_put_value(callh, &value, 0, vpiNoDelay);

    return 0;
}
Example #4
0
static PLI_INT32 sys_bitstoreal_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
    vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
    vpiHandle arg  = (vpiHandle) vpi_get_userdata(callh);
    s_vpi_value value;

    PLI_UINT32 bits[2];

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

    /* get value */
    value.format = vpiVectorVal;
    vpi_get_value(arg, &value);

    /* convert */
    bits[0] = (value.value.vector[0]).aval;
    bits[1] = (value.value.vector[1]).aval;
    value.value.real = bits2double(bits);
    value.format = vpiRealVal;

    /* return converted value */
    vpi_put_value(callh, &value, 0, vpiNoDelay);

    return 0;
}
PLI_INT32 tf_isetrealdelay(double dly, void*obj)
{
      vpiHandle sys = (vpiHandle)obj;
      p_pli_data pli = vpi_get_userdata(sys);
      s_cb_data cb;
      s_vpi_time ti = {vpiSimTime};

      /* Scale delay to SimTime */
      ivl_u64_t delay = ((dly
			 / pow(10, tf_gettimeunit() - tf_gettimeprecision()))
			 + 0.5);
      ti.high = delay >> 32 & 0xffffffff;
      ti.low = delay & 0xffffffff;

      cb.reason = cbAfterDelay;
      cb.cb_rtn = callback;
      cb.obj = sys;
      cb.time = &ti;
      cb.user_data = (char *)pli;

      vpi_register_cb(&cb);

      if (pli_trace)
	    fprintf(pli_trace, "tf_isetrealdelay(%f, %p) --> %d\n",
		  dly, obj, 0);

      return 0;
}
static int sys_random_calltf(char*name)
{
      s_vpi_value val;
      vpiHandle call_handle;
      vpiHandle argv;
      vpiHandle seed = 0;
      int i_seed = 0;
      struct context_s *context;

      call_handle = vpi_handle(vpiSysTfCall, 0);
      assert(call_handle);

	/* Get the argument list and look for a seed. If it is there,
	   get the value and reseed the random number generator. */
      argv = vpi_iterate(vpiArgument, call_handle);
      if (argv) {
	    seed = vpi_scan(argv);
	    vpi_free_object(argv);

	    val.format = vpiIntVal;
	    vpi_get_value(seed, &val);
	    i_seed = val.value.integer;

	      /* Since there is a seed use the current 
	         context or create a new one */
	    context = (struct context_s *)vpi_get_userdata(call_handle);
	    if (!context) {
		  context = (struct context_s *)calloc(1, sizeof(*context));
		  context->mti = NP1;
		  assert(context);

		    /* squrrel away context */
		  vpi_put_userdata(call_handle, (void *)context);
	    }

	      /* If the argument is not the Icarus cookie, then
		 reseed context */
	    if (i_seed != COOKIE)
	          sgenrand(context, i_seed);
      } else {
	    /* use global context */
          context = &global_context;
      }

      val.format = vpiIntVal;
      val.value.integer = genrand(context);

      vpi_put_value(call_handle, &val, 0, vpiNoDelay);

        /* mark seed with cookie */
      if (seed && i_seed != COOKIE) {
	    val.format = vpiIntVal;
	    val.value.integer = COOKIE;		
	    vpi_put_value(seed, &val, 0, vpiNoDelay);
      }

      return 0;
}
Example #7
0
static PLI_INT32 sys_mti_random_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
      vpiHandle callh, argv, seed = 0;
      s_vpi_value val;
      int i_seed = COOKIE;
      struct context_s *context;

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

	/* Get the argument list and look for a seed. If it is there,
	   get the value and reseed the random number generator. */
      callh = vpi_handle(vpiSysTfCall, 0);
      argv = vpi_iterate(vpiArgument, callh);
      val.format = vpiIntVal;
      if (argv) {
	    seed = vpi_scan(argv);
	    vpi_free_object(argv);
	    vpi_get_value(seed, &val);
	    i_seed = val.value.integer;

	      /* Since there is a seed use the current
	         context or create a new one */
	    context = (struct context_s *)vpi_get_userdata(callh);
	    if (!context) {
		  context = (struct context_s *)calloc(1, sizeof(*context));
		  context->mti = NP1;

		    /* squirrel away context */
		  vpi_put_userdata(callh, (void *)context);
	    }

	      /* If the argument is not the Icarus cookie, then
		 reseed context */
	    if (i_seed != COOKIE) sgenrand(context, i_seed);
      } else {
	    /* use global context */
          context = &global_context;
      }

        /* Calculate and return the result */
      val.value.integer = genrand(context);
      vpi_put_value(callh, &val, 0, vpiNoDelay);

        /* mark seed with cookie */
      if (seed && i_seed != COOKIE) {
	    val.value.integer = COOKIE;
	    vpi_put_value(seed, &val, 0, vpiNoDelay);
      }

      return 0;
}
PLI_INT32 tf_irosynchronize(void*obj)
{
      vpiHandle sys = (vpiHandle)obj;
      p_pli_data pli = vpi_get_userdata(sys);
      s_cb_data cb;
      s_vpi_time ti = {vpiSuppressTime, 0, 0};

      cb.reason = cbReadOnlySynch;
      cb.cb_rtn = callback;
      cb.obj = sys;
      cb.time = &ti;
      cb.user_data = (char *)pli;

      vpi_register_cb(&cb);

      if (pli_trace)
	    fprintf(pli_trace, "tf_irosynchronize(%p) --> %d\n", obj, 0);

      return 0;
}
Example #9
0
/*
 * Routine to implement the single argument math functions.
 */
static PLI_INT32 va_single_argument_calltf(ICARUS_VPI_CONST PLI_BYTE8 *ud)
{
    vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
    s_vpi_value val;
    va_single_t* fun_data;

    (void) ud;  /* Not used! */

    /* Retrieve the function and argument data. */
    fun_data = vpi_get_userdata(callh);

    /* Calculate the result */
    val.format = vpiRealVal;
    vpi_get_value(fun_data->arg, &val);
    val.value.real = (fun_data->func)(val.value.real);

    /* Return the result */
    vpi_put_value(callh, &val, 0, vpiNoDelay);

    return 0;
}
Example #10
0
static PLI_INT32 sys_itor_calltf(ICARUS_VPI_CONST PLI_BYTE8*name)
{
    vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
    vpiHandle arg  = (vpiHandle) vpi_get_userdata(callh);
    s_vpi_value value;

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

    /* get value */
    value.format = vpiIntVal;
    vpi_get_value(arg, &value);

    /* convert */
    value.value.real = value.value.integer;
    value.format = vpiRealVal;

    /* return converted value */
    vpi_put_value(callh, &value, 0, vpiNoDelay);

    return 0;
}
Example #11
0
static PLI_INT32 ivlh_attribute_event_calltf(ICARUS_VPI_CONST PLI_BYTE8*data)
{
      event_type_t type = (event_type_t) data;
      vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
      struct t_vpi_value rval;
      struct monitor_data*mon;

      rval.format = vpiScalarVal;

      mon = (struct monitor_data*) (vpi_get_userdata(sys));

      if (mon->last_event.type == 0) {
	    rval.value.scalar = vpi0;

      } else {
	    struct t_vpi_time tnow;
	    tnow.type = vpiSimTime;
	    vpi_get_time(0, &tnow);

	    rval.value.scalar = vpi1;

	    // Detect if change occured in this moment
	    if (mon->last_event.high != tnow.high)
		  rval.value.scalar = vpi0;
	    if (mon->last_event.low != tnow.low)
		  rval.value.scalar = vpi0;

	    // Determine the edge, if required
	    if (type == RISING_EDGE && mon->last_value.value.scalar != vpi1)
		  rval.value.scalar = vpi0;
	    else if (type == FALLING_EDGE && mon->last_value.value.scalar != vpi0)
		  rval.value.scalar = vpi0;
      }

      vpi_put_value(sys, &rval, 0, vpiNoDelay);

      return 0;
}