#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_link * | sim_plusargs_head = NULL |
static str_link * | sim_plusargs_tail = NULL |
#define UNIFORM_MAX LONG_MAX |
Referenced by sys_task_dist_uniform().
#define UNIFORM_MIN LONG_MIN |
Referenced by sys_task_dist_uniform().
double sys_task_bitstoreal | ( | uint64 | u64 | ) |
Converts a 64-bit value to a 64-bit real.
Converts a 64-bit value to a 64-bit real.
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.
Converts a 32-bit value to a 32-bit real.
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 | |||
) |
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.
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.
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.
Converts a 64-bit real value to a 64-bit unsigned value.
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).
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.
Converts a 32-bit real value to a 32-bit unsigned value.
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.
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.
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.
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] |
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.
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.
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 }
Parses command-line for value plusargs, assigns the specified vector the found value and returns 1 (if found).
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 }
long random_seed = 0 [static] |
Random seed value.
Referenced by sys_task_random(), sys_task_srandom(), sys_task_urandom(), and sys_task_urandom_range().
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.