00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <math.h>
00057 #include <stdio.h>
00058
00059 #include "sysc/kernel/sc_kernel_ids.h"
00060 #include "sysc/kernel/sc_simcontext.h"
00061 #include "sysc/kernel/sc_time.h"
00062 #include "sysc/utils/sc_utils_ids.h"
00063
00064 namespace sc_core {
00065
00066 static
00067 double time_values[] = {
00068 1,
00069 1e3,
00070 1e6,
00071 1e9,
00072 1e12,
00073 1e15
00074 };
00075
00076 static
00077 const char* time_units[] = {
00078 "fs",
00079 "ps",
00080 "ns",
00081 "us",
00082 "ms",
00083 "s"
00084 };
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 sc_time::sc_time( double v, sc_time_unit tu )
00096 : m_value( 0 )
00097 {
00098 if( v != 0 ) {
00099 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00100 double scale_fac = time_values[tu] / time_params->time_resolution;
00101
00102 volatile double tmp = v * scale_fac + 0.5;
00103 m_value = SCAST<sc_dt::int64>( tmp );
00104 time_params->time_resolution_fixed = true;
00105 }
00106 }
00107
00108 sc_time::sc_time( double v, sc_time_unit tu, sc_simcontext* simc )
00109 : m_value( 0 )
00110 {
00111 if( v != 0 ) {
00112 sc_time_params* time_params = simc->m_time_params;
00113 double scale_fac = time_values[tu] / time_params->time_resolution;
00114
00115 volatile double tmp = v * scale_fac + 0.5;
00116 m_value = SCAST<sc_dt::int64>( tmp );
00117 time_params->time_resolution_fixed = true;
00118 }
00119 }
00120
00121 sc_time::sc_time( double v, bool scale )
00122 : m_value( 0 )
00123 {
00124 if( v != 0 ) {
00125 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00126 if( scale ) {
00127 double scale_fac = sc_dt::uint64_to_double(
00128 time_params->default_time_unit );
00129
00130 volatile double tmp = v * scale_fac + 0.5;
00131 m_value = SCAST<sc_dt::int64>( tmp );
00132 } else {
00133
00134 volatile double tmp = v + 0.5;
00135 m_value = SCAST<sc_dt::int64>( tmp );
00136 }
00137 time_params->time_resolution_fixed = true;
00138 }
00139 }
00140
00141 sc_time::sc_time( sc_dt::uint64 v, bool scale )
00142 : m_value( 0 )
00143 {
00144 if( v != 0 ) {
00145 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00146 if( scale ) {
00147 double scale_fac = sc_dt::uint64_to_double(
00148 time_params->default_time_unit );
00149
00150 volatile double tmp = sc_dt::uint64_to_double( v ) *
00151 scale_fac + 0.5;
00152 m_value = SCAST<sc_dt::int64>( tmp );
00153 } else {
00154 m_value = v;
00155 }
00156 time_params->time_resolution_fixed = true;
00157 }
00158 }
00159
00160
00161
00162
00163 double
00164 sc_time::to_default_time_units() const
00165 {
00166 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00167 return ( sc_dt::uint64_to_double( m_value ) /
00168 sc_dt::uint64_to_double( time_params->default_time_unit ) );
00169 }
00170
00171 double
00172 sc_time::to_seconds() const
00173 {
00174 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00175 return ( sc_dt::uint64_to_double( m_value ) *
00176 time_params->time_resolution * 1e-15 );
00177 }
00178
00179 const std::string
00180 sc_time::to_string() const
00181 {
00182 sc_dt::uint64 val = m_value;
00183 if( val == 0 ) {
00184 return std::string( "0 s" );
00185 }
00186 sc_time_params* time_params = sc_get_curr_simcontext()->m_time_params;
00187 sc_dt::uint64 tr = SCAST<sc_dt::int64>( time_params->time_resolution );
00188 int n = 0;
00189 while( ( tr % 10 ) == 0 ) {
00190 tr /= 10;
00191 n ++;
00192 }
00193 assert( tr == 1 );
00194 while( ( val % 10 ) == 0 ) {
00195 val /= 10;
00196 n ++;
00197 }
00198 char buf[BUFSIZ];
00199 #if !defined( _MSC_VER )
00200 std::sprintf( buf, "%llu", val );
00201 #else
00202 std::sprintf( buf, "%I64u", val );
00203 #endif
00204 std::string result( buf );
00205 if( n >= 15 ) {
00206 for( int i = n - 15; i > 0; -- i ) {
00207 result += "0";
00208 }
00209 result += " s";
00210 } else {
00211 for( int i = n % 3; i > 0; -- i ) {
00212 result += "0";
00213 }
00214 result += " ";
00215 result += time_units[n / 3];
00216 }
00217 return result;
00218 }
00219
00220
00221
00222
00223 void
00224 sc_time::print( ::std::ostream& os ) const
00225 {
00226 os << to_string();
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 sc_time_params::sc_time_params()
00237 : time_resolution( 1000 ),
00238 time_resolution_specified( false ),
00239 time_resolution_fixed( false ),
00240 default_time_unit( 1000 ),
00241 default_time_unit_specified( false )
00242 {}
00243
00244 sc_time_params::~sc_time_params()
00245 {}
00246
00247
00248
00249
00250
00251
00252 void
00253 sc_set_time_resolution( double v, sc_time_unit tu )
00254 {
00255
00256
00257
00258 if( v < 0.0 ) {
00259 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "value not positive" );
00260 }
00261
00262
00263 double dummy;
00264 #if defined( __HP_aCC ) || defined(__ppc__)
00265
00266 if( modf( log10( v < 1.0 ? 1.0/v : v ), &dummy ) != 0.0 ) {
00267 #else
00268 if( modf( log10( v ), &dummy ) != 0.0 ) {
00269 #endif
00270 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
00271 "value not a power of ten" );
00272 }
00273
00274 sc_simcontext* simc = sc_get_curr_simcontext();
00275
00276
00277 if( sc_is_running() ) {
00278 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "simulation running" );
00279 }
00280
00281 sc_time_params* time_params = simc->m_time_params;
00282
00283
00284 if( time_params->time_resolution_specified ) {
00285 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_, "already specified" );
00286 }
00287
00288
00289 if( time_params->time_resolution_fixed ) {
00290 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
00291 "sc_time object(s) constructed" );
00292 }
00293
00294
00295 volatile double resolution = v * time_values[tu];
00296 if( resolution < 1.0 ) {
00297 SC_REPORT_ERROR( SC_ID_SET_TIME_RESOLUTION_,
00298 "value smaller than 1 fs" );
00299 }
00300
00301
00302 volatile double time_unit = sc_dt::uint64_to_double(
00303 time_params->default_time_unit ) *
00304 ( time_params->time_resolution / resolution );
00305 if( time_unit < 1.0 ) {
00306 SC_REPORT_WARNING( SC_ID_DEFAULT_TIME_UNIT_CHANGED_, 0 );
00307 time_params->default_time_unit = 1;
00308 } else {
00309 time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
00310 }
00311
00312 time_params->time_resolution = resolution;
00313 time_params->time_resolution_specified = true;
00314 }
00315
00316 sc_time
00317 sc_get_time_resolution()
00318 {
00319 return sc_time( sc_dt::UINT64_ONE, false );
00320 }
00321
00322
00323 void
00324 sc_set_default_time_unit( double v, sc_time_unit tu )
00325 {
00326 static bool warn_default_time_unit=true;
00327 if ( warn_default_time_unit )
00328 {
00329 warn_default_time_unit=false;
00330 SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
00331 "deprecated function: sc_set_default_time_unit");
00332 }
00333
00334
00335
00336
00337 if( v < 0.0 ) {
00338 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "value not positive" );
00339 }
00340
00341
00342 double dummy;
00343 if( modf( log10( v ), &dummy ) != 0.0 ) {
00344 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
00345 "value not a power of ten" );
00346 }
00347
00348 sc_simcontext* simc = sc_get_curr_simcontext();
00349
00350
00351 if( sc_is_running() ) {
00352 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "simulation running" );
00353 }
00354
00355 sc_time_params* time_params = simc->m_time_params;
00356
00357
00358 if( time_params->time_resolution_fixed ) {
00359 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
00360 "sc_time object(s) constructed" );
00361 }
00362
00363
00364 if( time_params->default_time_unit_specified ) {
00365 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_, "already specified" );
00366 }
00367
00368
00369 volatile double time_unit = ( v * time_values[tu] ) /
00370 time_params->time_resolution;
00371 if( time_unit < 1.0 ) {
00372 SC_REPORT_ERROR( SC_ID_SET_DEFAULT_TIME_UNIT_,
00373 "value smaller than time resolution" );
00374 }
00375
00376 time_params->default_time_unit = SCAST<sc_dt::int64>( time_unit );
00377 time_params->default_time_unit_specified = true;
00378 }
00379
00380 sc_time
00381 sc_get_default_time_unit()
00382 {
00383 bool warn_get_default_time_unit = true;
00384 if ( warn_get_default_time_unit )
00385 {
00386 warn_get_default_time_unit=false;
00387 SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_,
00388 "deprecated function: sc_get_default_time_unit");
00389 }
00390 return sc_time( sc_get_curr_simcontext()->m_time_params->default_time_unit,
00391 false );
00392 }
00393
00394
00395
00396
00397 const sc_time SC_ZERO_TIME;
00398
00399
00400 }
00401