sys_tasks.c File Reference

#include <limits.h>
#include <stdlib.h>
#include "defines.h"
#include "link.h"
#include "profiler.h"
#include "vector.h"

Defines

#define UNIFORM_MAX   LONG_MAX
#define UNIFORM_MIN   LONG_MIN

Functions

static double sys_task_uniform (long *seed, long start, long end)
long sys_task_dist_uniform (long *seed, long start, long end)
void sys_task_srandom (long seed)
 Performs $srandom system task call.
long sys_task_random (long *seed)
 Performs $random system task call.
unsigned long sys_task_urandom (long *seed)
 Performs $urandom system task call.
unsigned long sys_task_urandom_range (unsigned long max, unsigned long min)
 Performs $urandom_range system task call.
uint64 sys_task_realtobits (double real)
 Converts a 64-bit real value to a 64-bit unsigned value.
double sys_task_bitstoreal (uint64 u64)
 Converts a 64-bit value to a 64-bit real.
uint32 sys_task_shortrealtobits (float real)
 Converts a 32-bit real value to a 32-bit unsigned value.
float sys_task_bitstoshortreal (uint32 u32)
 Converts a 32-bit value to a 32-bit real.
double sys_task_itor (int ival)
 Returns a real representation of the specified integer value.
int sys_task_rtoi (double real)
 Returns an integer representation of the specified real value (value is truncated).
void sys_task_store_plusarg (const char *arg)
 Scans command-line for plusargs.
ulong sys_task_test_plusargs (const char *arg)
 Returns 1 if the specified plusarg was found; otherwise, returns 0.
ulong sys_task_value_plusargs (const char *arg, vector *vec)
 Parses command-line for value plusargs, assigns the specified vector the found value and returns 1 (if found).
void sys_task_dealloc ()
 Deallocates any memory allocated within this file.

Variables

static long random_seed = 0
static str_linksim_plusargs_head = NULL
static str_linksim_plusargs_tail = NULL

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
10/2/2008
Note:
The contents of this file came from Icarus Verilog source code and should be attributed to this group. Only the format of this code has been modified.

Define Documentation

#define UNIFORM_MAX   LONG_MAX

Referenced by sys_task_dist_uniform().

#define UNIFORM_MIN   LONG_MIN

Referenced by sys_task_dist_uniform().


Function Documentation

double sys_task_bitstoreal ( uint64  u64  ) 

Converts a 64-bit value to a 64-bit real.

Returns:
Returns a 64-bit real representation of the specified 64-bit value.

Converts a 64-bit value to a 64-bit real.

Parameters:
u64 64-bit value to convert to a real

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__bitstoreal(), and reentrant_restore_data_bits().

00316   { PROFILE(SYS_TASK_BITSTOREAL);
00317 
00318   union {
00319     double real;
00320     uint64 u64;
00321   } conversion;
00322 
00323   conversion.u64 = u64;
00324 
00325   PROFILE_END;
00326 
00327   return( conversion.real );
00328 
00329 }

float sys_task_bitstoshortreal ( uint32  u32  ) 

Converts a 32-bit value to a 32-bit real.

Returns:
Returns a 32-bit real representation of the specified 32-bit value.

Converts a 32-bit value to a 32-bit real.

Parameters:
u32 32-bit value to convert to a real

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__bitstoshortreal().

00360   { PROFILE(SYS_TASK_BITSTOSHORTREAL);
00361 
00362   union {
00363     float  real;
00364     uint32 u32;
00365   } conversion;
00366 
00367   conversion.u32 = u32;
00368 
00369   PROFILE_END;
00370 
00371   return( conversion.real );
00372 
00373 }

void sys_task_dealloc (  ) 

Deallocates any memory allocated within this file.

Deallocates all memory allocated by any of the above functions.

References PROFILE, PROFILE_END, and str_link_delete_list().

Referenced by command_score(), and covered_end_of_sim().

00488                         { PROFILE(SYS_TASK_DEALLOC);
00489 
00490   /* Delete simulation plusarg list */
00491   str_link_delete_list( sim_plusargs_head );
00492 
00493   PROFILE_END;
00494 
00495 }

long sys_task_dist_uniform ( long *  seed,
long  start,
long  end 
)
Returns:
Returns a randomly generated integer value that is uniformly distributed.
Note:
Copied from IEEE1364-2001, with slight modifications for 64bit machines. This code is taken from Icarus Verilog.
Parameters:
seed Pointer to seed value to use and store new seed value to
start Starting range of random value
end Ending range of random value

References PROFILE, PROFILE_END, sys_task_uniform(), UNIFORM_MAX, and UNIFORM_MIN.

Referenced by sys_task_random(), sys_task_urandom(), and sys_task_urandom_range().

00121   { PROFILE(SYS_TASK_RTL_DIST_UNIFORM);
00122 
00123   double r;
00124   long   i;
00125 
00126   if( start >= end ) {
00127 
00128     i = start;
00129 
00130   } else {
00131 
00132     /*
00133      NOTE: The cast of r to i can overflow and generate strange
00134      values, so cast to unsigned long first. This eliminates
00135      the underflow and gets the twos complement value. That in
00136      turn can be cast to the long value that is expected.
00137     */
00138 
00139     if( end != UNIFORM_MAX ) {
00140 
00141       end++;
00142       r = sys_task_uniform( seed, start, end );
00143       if( r >= 0 ) {
00144         i = (unsigned long) r;
00145       } else {
00146         i = - ( (unsigned long) (-(r - 1)) );
00147       }
00148       if( i < start ) i = start;
00149       if( i >= end ) i = end - 1;
00150 
00151     } else if( start != UNIFORM_MIN ) {
00152 
00153       start--;
00154       r = sys_task_uniform( seed, start, end ) + 1.0;
00155       if( r >= 0 ) {
00156         i = (unsigned long) r;
00157       } else {
00158         i = - ( (unsigned long) (-(r - 1)) );
00159       }
00160       if( i <= start ) i = start + 1;
00161       if( i > end ) i = end;
00162 
00163     } else {
00164 
00165       r = (sys_task_uniform( seed, start, end ) + 2147483648.0) / 4294967295.0;
00166       r = r * 4294967296.0 - 2147483648.0;
00167 
00168       if( r >= 0 ) {
00169         i = (unsigned long) r;
00170       } else {
00171         /*
00172          At least some compilers will notice that (r-1)
00173          is <0 when castling to unsigned long and
00174          replace the result with a zero. This causes
00175          much wrongness, so do the casting to the
00176          positive version and invert it back.
00177         */
00178         i = - ( (unsigned long) (-(r - 1)) );
00179       }
00180 
00181     }
00182 
00183   }
00184 
00185   PROFILE_END;
00186 
00187   return( i );
00188 
00189 }

double sys_task_itor ( int  ival  ) 

Returns a real representation of the specified integer value.

Returns:
Returns a real representation of the specified integer value.
Parameters:
ival Integer value to convert to real value

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__itor().

00380   { PROFILE(SYS_TASK_ITOR);
00381 
00382   double real = (double)ival;
00383 
00384   PROFILE_END;
00385 
00386   return( real );
00387 
00388 }

long sys_task_random ( long *  seed  ) 

Performs $random system task call.

Returns:
Returns a randomly generated signed value
Parameters:
seed Pointer to seed value to use and store new information to

References PROFILE, PROFILE_END, random_seed, and sys_task_dist_uniform().

Referenced by expression_op_func__random().

00210   { PROFILE(SYS_TASK_RANDOM);
00211 
00212   long result;
00213   
00214   if( seed != NULL ) {
00215     random_seed = *seed;
00216   }
00217 
00218   result = sys_task_dist_uniform( &random_seed, INT_MIN, INT_MAX );
00219 
00220   if( seed != NULL ) {
00221     *seed = random_seed;
00222   }
00223 
00224   PROFILE_END;
00225 
00226   return( result );
00227 
00228 }

uint64 sys_task_realtobits ( double  real  ) 

Converts a 64-bit real value to a 64-bit unsigned value.

Returns:
Returns a 64-bit bit representation of the specified double value.

Converts a 64-bit real value to a 64-bit unsigned value.

Parameters:
real Real value to convert to bits

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__realtobits(), and reentrant_store_data_bits().

00294   { PROFILE(SYS_TASK_REALTOBITS);
00295 
00296   union {
00297     double real;
00298     uint64 u64;
00299   } conversion;
00300 
00301   conversion.real = real;
00302 
00303   PROFILE_END;
00304 
00305   return( conversion.u64 );
00306 
00307 }

int sys_task_rtoi ( double  real  ) 

Returns an integer representation of the specified real value (value is truncated).

Returns:
Returns an integer representation of the specified real value (value is truncated).
Parameters:
real Real value to convert to integer

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__rtoi().

00395   { PROFILE(SYS_TASK_RTOI);
00396 
00397   int ival = (int)real;
00398 
00399   PROFILE_END;
00400 
00401   return( ival );
00402 
00403 }

uint32 sys_task_shortrealtobits ( float  real  ) 

Converts a 32-bit real value to a 32-bit unsigned value.

Returns:
Returns a 32-bit bit representation of the specified double value.

Converts a 32-bit real value to a 32-bit unsigned value.

Parameters:
real Real value to convert to bits

References PROFILE, and PROFILE_END.

Referenced by expression_op_func__shortrealtobits().

00338   { PROFILE(SYS_TASK_SHORTREALTOBITS);
00339 
00340   union {
00341     float  real;
00342     uint32 u32;
00343   } conversion;
00344 
00345   conversion.real = real;
00346 
00347   PROFILE_END;
00348 
00349   return( conversion.u32 );
00350 
00351 }

void sys_task_srandom ( long  seed  ) 

Performs $srandom system task call.

Sets the global seed value to the specified value.

Parameters:
seed User-specified seed to set global seed value to

References PROFILE, PROFILE_END, and random_seed.

Referenced by expression_op_func__srandom().

00197   { PROFILE(SYS_TASK_SRANDOM);
00198 
00199   random_seed = seed;
00200 
00201   PROFILE_END;
00202 
00203 }

void sys_task_store_plusarg ( const char *  arg  ) 

Scans command-line for plusargs.

This function is called by the score command argument parser or the VPI command-line parser and performs the task of adding plusarg options from the score command or VPI for later usage during simulation.

Parameters:
arg Plusarg from the score command or VPI code minus the initial '+' character

References PROFILE, PROFILE_END, str_link_add(), and strdup_safe.

Referenced by covered_sim_calltf(), and score_parse_args().

00412   { PROFILE(SYS_TASK_STORE_PLUSARGS);
00413 
00414   str_link_add( strdup_safe( arg ), &sim_plusargs_head, &sim_plusargs_tail );
00415 
00416   PROFILE_END;
00417 
00418 }

ulong sys_task_test_plusargs ( const char *  arg  ) 

Returns 1 if the specified plusarg was found; otherwise, returns 0.

Returns:
Returns 1 if the specified plusarg was found; otherwise, returns 0.
Parameters:
arg Plusarg to find

References PROFILE, PROFILE_END, and str_link_find().

Referenced by expression_op_func__test_plusargs().

00425   { PROFILE(SYS_TASK_TEST_PLUSARG);
00426 
00427   /* Scan the simulation argument list for matching values */
00428   ulong retval = (str_link_find( arg, sim_plusargs_head ) != NULL) ? 1 : 0;
00429 
00430   PROFILE_END;
00431 
00432   return( retval );
00433 
00434 }

static double sys_task_uniform ( long *  seed,
long  start,
long  end 
) [static]
Returns:
Returns a randomly generated number that is uniformly distributed.
Parameters:
seed Pointer to seed value to use and store new seed in
start Beginning range
end Ending range

References PROFILE, and PROFILE_END.

Referenced by sys_task_dist_uniform().

00063   { PROFILE(SYS_TASK_UNIFORM);
00064 
00065   double        d = 0.00000011920928955078125;
00066   double        a, b, c;
00067   unsigned long oldseed, newseed;
00068 
00069   oldseed = *seed;
00070 
00071   if( oldseed == 0 )
00072     oldseed = 259341593;
00073 
00074   if( start >= end ) {
00075     a = 0.0;
00076     b = 2147483647.0;
00077   } else {
00078     a = (double)start;
00079     b = (double)end;
00080   }
00081 
00082   /* Original routine used signed arithmetic, and the (frequent)
00083    * overflows trigger "Undefined Behavior" according to the
00084    * C standard (both c89 and c99).  Using unsigned arithmetic
00085    * forces a conforming C implementation to get the result
00086    * that the IEEE-1364-2001 committee wants.
00087    */
00088   newseed = 69069 * oldseed + 1;
00089 
00090   /* Emulate a 32-bit unsigned long, even if the native machine
00091    * uses wider words.
00092    */
00093 #if ULONG_MAX > 4294967295UL
00094   newseed = newseed & 4294967295UL;
00095 #endif
00096   *seed = newseed;
00097 
00098   /* Equivalent conversion without assuming IEEE 32-bit float */
00099   /* constant is 2^(-23) */
00100   c = 1.0 + (newseed >> 9) * 0.00000011920928955078125;
00101   c = c + (c*d);
00102   c = ((b - a) * (c - 1.0)) + a;
00103 
00104   PROFILE_END;
00105 
00106   return( c );
00107 
00108 }

unsigned long sys_task_urandom ( long *  seed  ) 

Performs $urandom system task call.

Returns:
Returns a randomly generated unsigned value within a given range
Note:
From System Verilog 3.1a. This code is from the Icarus Verilog project.
Parameters:
seed Pointer to seed value to use and store new information to

References PROFILE, random_seed, and sys_task_dist_uniform().

Referenced by expression_op_func__urandom().

00238   { PROFILE(SYS_TASK_URANDOM);
00239 
00240   unsigned long result;
00241 
00242   if( seed != NULL ) {
00243     random_seed = *seed;
00244   }
00245 
00246   result = sys_task_dist_uniform( &random_seed, INT_MIN, INT_MAX ) - INT_MIN;
00247 
00248   if( seed != NULL ) {
00249     *seed = random_seed;
00250   }
00251 
00252   return( result );
00253 
00254 }

unsigned long sys_task_urandom_range ( unsigned long  max,
unsigned long  min 
)

Performs $urandom_range system task call.

Returns:
Returns a randomly generated unsigned value within a given range
Note:
From System Verilog 3.1a. This code is from the Icarus Verilog project.
Parameters:
max Maximum range value
min Minimum range value

References PROFILE, random_seed, and sys_task_dist_uniform().

Referenced by expression_op_func__urandom_range().

00265   { PROFILE(SYS_TASK_URANDOM_RANGE);
00266 
00267   unsigned long result;
00268   long          max_i, min_i;
00269 
00270   /* If the max value is less than the min value, swap the two values */
00271   if( max < min ) {
00272     unsigned long tmp;
00273     tmp = max;
00274     max = min;
00275     min = tmp;
00276   }
00277 
00278   max_i = max + INT_MIN;
00279   min_i = min + INT_MIN;
00280 
00281   result = sys_task_dist_uniform( &random_seed, min_i, max_i ) - INT_MIN;
00282 
00283   return( result );
00284 
00285 }

ulong sys_task_value_plusargs ( const char *  arg,
vector vec 
)

Parses command-line for value plusargs, assigns the specified vector the found value and returns 1 (if found).

Parameters:
arg Plusarg to find
vec Pointer to vector to populate with found value

References str_link_s::next, PROFILE, PROFILE_END, str_link_s::str, vector_from_real64(), vector_from_string_fixed(), and vector_from_uint64().

Referenced by expression_op_func__value_plusargs().

00443   { PROFILE(SYS_TASK_VALUE_PLUSARGS);
00444 
00445   ulong     retval = 0;
00446   str_link* strl;
00447   char*     ptr;
00448 
00449   /* Find the percent character in the argument string */
00450   ptr = strchr( arg, '%' );
00451   assert( ptr != NULL );
00452 
00453   /* See if the plusarg even exists on the command-line */
00454   strl = sim_plusargs_head;
00455   while( (strl != NULL) && (strncmp( arg, strl->str, (ptr - arg) ) != 0) ) {
00456     strl = strl->next;
00457   }
00458 
00459   /* If the argument exists on the command-line, continue */
00460   if( strl != NULL ) {
00461 
00462     switch( *(ptr + 1) ) {
00463       case 'b' :  vector_from_uint64( vec, strtoull( (strl->str + (ptr - arg)), 0, 2 ) );  break;
00464       case 'o' :  vector_from_uint64( vec, strtoull( (strl->str + (ptr - arg)), 0, 8 ) );  break;
00465       case 'd' :  vector_from_uint64( vec, strtoull( (strl->str + (ptr - arg)), 0, 10 ) );  break;
00466       case 'h' :  vector_from_uint64( vec, strtoull( (strl->str + (ptr - arg)), 0, 16 ) );  break;
00467       case 'e' :
00468       case 'f' :
00469       case 'g' :  vector_from_real64( vec, strtod( (strl->str + (ptr - arg)), 0 ) );  break;
00470       case 's' :  vector_from_string_fixed( vec, (strl->str + (ptr - arg)) );  break;
00471       default  :  assert( 0 );  break;
00472     }
00473 
00474     /* Specify that we have found and converted the value */
00475     retval = 1;
00476 
00477   }
00478 
00479   PROFILE_END;
00480 
00481   return( retval );
00482 
00483 }


Variable Documentation

long random_seed = 0 [static]
str_link* sim_plusargs_head = NULL [static]

Pointer to the head of the list of simulation plusargs.

str_link* sim_plusargs_tail = NULL [static]

Pointer to the tail of the list of simulation plusargs.

Generated on Sun Nov 21 00:55:41 2010 for Covered by  doxygen 1.6.3