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 #ifndef SCFX_IEEE_H
00053 #define SCFX_IEEE_H
00054
00055
00056 #include "sysc/datatypes/fx/sc_fxdefs.h"
00057
00058
00059 namespace sc_dt
00060 {
00061
00062
00063 union ieee_double;
00064 class scfx_ieee_double;
00065 union ieee_float;
00066 class scfx_ieee_float;
00067
00068 #define SCFX_MASK_(Size) \
00069 ((1u << (Size))-1u)
00070
00071
00072
00073
00074
00075
00076
00077 union ieee_double
00078 {
00079
00080 double d;
00081
00082 struct
00083 {
00084 #if defined( SC_BIG_ENDIAN )
00085 unsigned negative:1;
00086 unsigned exponent:11;
00087 unsigned mantissa0:20;
00088 unsigned mantissa1:32;
00089 #elif defined( SC_LITTLE_ENDIAN )
00090 unsigned mantissa1:32;
00091 unsigned mantissa0:20;
00092 unsigned exponent:11;
00093 unsigned negative:1;
00094 #endif
00095 } s;
00096
00097 };
00098
00099
00100 const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U;
00101
00102 const int SCFX_IEEE_DOUBLE_E_MAX = 1023;
00103 const int SCFX_IEEE_DOUBLE_E_MIN = -1022;
00104
00105 const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52;
00106 const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20;
00107 const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32;
00108 const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11;
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 class scfx_ieee_double
00119 {
00120
00121 ieee_double m_id;
00122
00123 public:
00124
00125 scfx_ieee_double();
00126 scfx_ieee_double( double );
00127 scfx_ieee_double( const scfx_ieee_double& );
00128
00129 scfx_ieee_double& operator = ( double );
00130 scfx_ieee_double& operator = ( const scfx_ieee_double& );
00131
00132 operator double() const;
00133
00134 unsigned int negative() const;
00135 void negative( unsigned int );
00136 int exponent() const;
00137 void exponent( int );
00138 unsigned int mantissa0() const;
00139 void mantissa0( unsigned int );
00140 unsigned int mantissa1() const;
00141 void mantissa1( unsigned int );
00142
00143 bool is_zero() const;
00144 bool is_subnormal() const;
00145 bool is_normal() const;
00146 bool is_inf() const;
00147 bool is_nan() const;
00148
00149 void set_inf();
00150 void set_nan();
00151
00152 int msb() const;
00153 int lsb() const;
00154
00155 static const scfx_ieee_double nan();
00156 static const scfx_ieee_double inf( int );
00157
00158 };
00159
00160
00161
00162
00163 inline
00164 scfx_ieee_double::scfx_ieee_double() : m_id()
00165 {
00166 m_id.d = 0.0;
00167 }
00168
00169 inline
00170 scfx_ieee_double::scfx_ieee_double( double d ) : m_id()
00171 {
00172 m_id.d = d;
00173 }
00174
00175 inline
00176 scfx_ieee_double::scfx_ieee_double( const scfx_ieee_double& a ) : m_id(a.m_id)
00177 {
00178
00179 }
00180
00181
00182 inline
00183 scfx_ieee_double&
00184 scfx_ieee_double::operator = ( double d )
00185 {
00186 m_id.d = d;
00187 return *this;
00188 }
00189
00190 inline
00191 scfx_ieee_double&
00192 scfx_ieee_double::operator = ( const scfx_ieee_double& a )
00193 {
00194 m_id.d = a.m_id.d;
00195 return *this;
00196 }
00197
00198
00199 inline
00200 scfx_ieee_double::operator double() const
00201 {
00202 return m_id.d;
00203 }
00204
00205
00206 inline
00207 unsigned int
00208 scfx_ieee_double::negative() const
00209 {
00210 return m_id.s.negative;
00211 }
00212
00213 inline
00214 void
00215 scfx_ieee_double::negative( unsigned int a )
00216 {
00217 m_id.s.negative = a & SCFX_MASK_(1);
00218 }
00219
00220 inline
00221 int
00222 scfx_ieee_double::exponent() const
00223 {
00224 return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS;
00225 }
00226
00227 inline
00228 void
00229 scfx_ieee_double::exponent( int a )
00230 {
00231 m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a)
00232 & SCFX_MASK_(SCFX_IEEE_DOUBLE_E_SIZE);
00233 }
00234
00235 inline
00236 unsigned int
00237 scfx_ieee_double::mantissa0() const
00238 {
00239 return m_id.s.mantissa0;
00240 }
00241
00242 inline
00243 void
00244 scfx_ieee_double::mantissa0( unsigned int a )
00245 {
00246 m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE);
00247 }
00248
00249 inline
00250 unsigned int
00251 scfx_ieee_double::mantissa1() const
00252 {
00253 return m_id.s.mantissa1;
00254 }
00255
00256 inline
00257 void
00258 scfx_ieee_double::mantissa1( unsigned int a )
00259 {
00260 m_id.s.mantissa1 = a;
00261 }
00262
00263
00264 inline
00265 bool
00266 scfx_ieee_double::is_zero() const
00267 {
00268 return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
00269 mantissa0() == 0U && mantissa1() == 0U );
00270 }
00271
00272 inline
00273 bool
00274 scfx_ieee_double::is_subnormal() const
00275 {
00276 return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 &&
00277 ( mantissa0() != 0U || mantissa1() != 0U ) );
00278 }
00279
00280 inline
00281 bool
00282 scfx_ieee_double::is_normal() const
00283 {
00284 return ( exponent() >= SCFX_IEEE_DOUBLE_E_MIN &&
00285 exponent() <= SCFX_IEEE_DOUBLE_E_MAX );
00286 }
00287
00288 inline
00289 bool
00290 scfx_ieee_double::is_inf() const
00291 {
00292 return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
00293 mantissa0() == 0U && mantissa1() == 0U );
00294 }
00295
00296 inline
00297 bool
00298 scfx_ieee_double::is_nan() const
00299 {
00300 return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 &&
00301 ( mantissa0() != 0U || mantissa1() != 0U ) );
00302 }
00303
00304
00305 inline
00306 void
00307 scfx_ieee_double::set_inf()
00308 {
00309 exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 );
00310 mantissa0( 0U );
00311 mantissa1( 0U );
00312 }
00313
00314 inline
00315 void
00316 scfx_ieee_double::set_nan()
00317 {
00318 exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 );
00319 mantissa0( (unsigned int) -1 );
00320 mantissa1( (unsigned int) -1 );
00321 }
00322
00323
00324 #define MSB_STATEMENT(x,n) if( x >> n ) { x >>= n; i += n; }
00325
00326 inline
00327 int
00328 scfx_ieee_double::msb() const
00329 {
00330 unsigned int m0 = mantissa0();
00331 unsigned int m1 = mantissa1();
00332 if( m0 != 0 )
00333 {
00334 int i = 0;
00335 MSB_STATEMENT(m0,16);
00336 MSB_STATEMENT(m0,8);
00337 MSB_STATEMENT(m0,4);
00338 MSB_STATEMENT(m0,2);
00339 MSB_STATEMENT(m0,1);
00340 return ( i - 20 );
00341 }
00342 else if( m1 != 0 )
00343 {
00344 int i = 0;
00345 MSB_STATEMENT(m1,16);
00346 MSB_STATEMENT(m1,8);
00347 MSB_STATEMENT(m1,4);
00348 MSB_STATEMENT(m1,2);
00349 MSB_STATEMENT(m1,1);
00350 return ( i - 52 );
00351 }
00352 else
00353 {
00354 return 0;
00355 }
00356 }
00357
00358 #undef MSB_STATEMENT
00359
00360 #define LSB_STATEMENT(x,n) if( x << n ) { x <<= n; i -= n; }
00361
00362 inline
00363 int
00364 scfx_ieee_double::lsb() const
00365 {
00366 unsigned int m0 = mantissa0();
00367 unsigned int m1 = mantissa1();
00368 if( m1 != 0 )
00369 {
00370 int i = 31;
00371 LSB_STATEMENT(m1,16);
00372 LSB_STATEMENT(m1,8);
00373 LSB_STATEMENT(m1,4);
00374 LSB_STATEMENT(m1,2);
00375 LSB_STATEMENT(m1,1);
00376 return ( i - 52 );
00377 }
00378 else if( m0 != 0 )
00379 {
00380 int i = 31;
00381 LSB_STATEMENT(m0,16);
00382 LSB_STATEMENT(m0,8);
00383 LSB_STATEMENT(m0,4);
00384 LSB_STATEMENT(m0,2);
00385 LSB_STATEMENT(m0,1);
00386 return ( i - 20 );
00387 }
00388 else
00389 {
00390 return 0;
00391 }
00392 }
00393
00394 #undef LSB_STATEMENT
00395
00396
00397 inline
00398 const scfx_ieee_double
00399 scfx_ieee_double::nan()
00400 {
00401 scfx_ieee_double id;
00402 id.set_nan();
00403 return id;
00404 }
00405
00406 inline
00407 const scfx_ieee_double
00408 scfx_ieee_double::inf( int sign )
00409 {
00410 scfx_ieee_double id( sign );
00411 id.set_inf();
00412 return id;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422 union ieee_float
00423 {
00424
00425 float f;
00426
00427 struct
00428 {
00429 #if defined( SC_BIG_ENDIAN )
00430 unsigned negative:1;
00431 unsigned exponent:8;
00432 unsigned mantissa:23;
00433 #elif defined( SC_LITTLE_ENDIAN )
00434 unsigned mantissa:23;
00435 unsigned exponent:8;
00436 unsigned negative:1;
00437 #endif
00438 } s;
00439
00440 };
00441
00442
00443 const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U;
00444
00445 const int SCFX_IEEE_FLOAT_E_MAX = 127;
00446 const int SCFX_IEEE_FLOAT_E_MIN = -126;
00447
00448 const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23;
00449 const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8;
00450
00451
00452
00453
00454
00455
00456
00457
00458 class scfx_ieee_float
00459 {
00460
00461 ieee_float m_if;
00462
00463 public:
00464
00465 scfx_ieee_float();
00466 scfx_ieee_float( float );
00467 scfx_ieee_float( const scfx_ieee_float& );
00468
00469 scfx_ieee_float& operator = ( float );
00470 scfx_ieee_float& operator = ( const scfx_ieee_float& );
00471
00472 operator float() const;
00473
00474 unsigned int negative() const;
00475 void negative( unsigned int );
00476 int exponent() const;
00477 void exponent( int );
00478 unsigned int mantissa() const;
00479 void mantissa( unsigned int );
00480
00481 bool is_zero() const;
00482 bool is_subnormal() const;
00483 bool is_normal() const;
00484 bool is_inf() const;
00485 bool is_nan() const;
00486
00487 void set_inf();
00488 void set_nan();
00489
00490 };
00491
00492
00493
00494
00495 inline
00496 scfx_ieee_float::scfx_ieee_float() : m_if()
00497 {
00498 m_if.f = 0.0;
00499 }
00500
00501 inline
00502 scfx_ieee_float::scfx_ieee_float( float f ) : m_if()
00503 {
00504 m_if.f = f;
00505 }
00506
00507 inline
00508 scfx_ieee_float::scfx_ieee_float( const scfx_ieee_float& a ) : m_if(a.m_if)
00509 {
00510
00511 }
00512
00513
00514 inline
00515 scfx_ieee_float&
00516 scfx_ieee_float::operator = ( float f )
00517 {
00518 m_if.f = f;
00519 return *this;
00520 }
00521
00522 inline
00523 scfx_ieee_float&
00524 scfx_ieee_float::operator = ( const scfx_ieee_float& a )
00525 {
00526 m_if.f = a.m_if.f;
00527 return *this;
00528 }
00529
00530
00531 inline
00532 scfx_ieee_float::operator float() const
00533 {
00534 return m_if.f;
00535 }
00536
00537
00538 inline
00539 unsigned int
00540 scfx_ieee_float::negative() const
00541 {
00542 return m_if.s.negative;
00543 }
00544
00545 inline
00546 void
00547 scfx_ieee_float::negative( unsigned int a )
00548 {
00549 m_if.s.negative = a & SCFX_MASK_(1);
00550 }
00551
00552 inline
00553 int
00554 scfx_ieee_float::exponent() const
00555 {
00556 return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS;
00557 }
00558
00559 inline
00560 void
00561 scfx_ieee_float::exponent( int a )
00562 {
00563 m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a)
00564 & SCFX_MASK_(SCFX_IEEE_FLOAT_E_SIZE);
00565 }
00566
00567 inline
00568 unsigned int
00569 scfx_ieee_float::mantissa() const
00570 {
00571 return m_if.s.mantissa;
00572 }
00573
00574 inline
00575 void
00576 scfx_ieee_float::mantissa( unsigned int a )
00577 {
00578 m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE);
00579 }
00580
00581
00582 inline
00583 bool
00584 scfx_ieee_float::is_zero() const
00585 {
00586 return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U );
00587 }
00588
00589 inline
00590 bool
00591 scfx_ieee_float::is_subnormal() const
00592 {
00593 return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U );
00594 }
00595
00596 inline
00597 bool
00598 scfx_ieee_float::is_normal() const
00599 {
00600 return ( exponent() >= SCFX_IEEE_FLOAT_E_MIN &&
00601 exponent() <= SCFX_IEEE_FLOAT_E_MAX );
00602 }
00603
00604 inline
00605 bool
00606 scfx_ieee_float::is_inf() const
00607 {
00608 return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U );
00609 }
00610
00611 inline
00612 bool
00613 scfx_ieee_float::is_nan() const
00614 {
00615 return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U );
00616 }
00617
00618
00619 inline
00620 void
00621 scfx_ieee_float::set_inf()
00622 {
00623 exponent( SCFX_IEEE_FLOAT_E_MAX + 1 );
00624 mantissa( 0U );
00625 }
00626
00627 inline
00628 void
00629 scfx_ieee_float::set_nan()
00630 {
00631 exponent( SCFX_IEEE_FLOAT_E_MAX + 1 );
00632 mantissa( (unsigned int) -1 );
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642 inline
00643 double scfx_pow2( int exp )
00644 {
00645 scfx_ieee_double r;
00646 if( exp < SCFX_IEEE_DOUBLE_E_MIN )
00647 {
00648 r = 0.0;
00649
00650 exp -= SCFX_IEEE_DOUBLE_E_MIN;
00651 if( ( exp += 20 ) >= 0 )
00652 {
00653 r.mantissa0( 1U << exp );
00654 }
00655 else if( ( exp += 32 ) >= 0 )
00656 {
00657 r.mantissa1( 1U << exp );
00658 }
00659 }
00660 else if( exp > SCFX_IEEE_DOUBLE_E_MAX )
00661 {
00662 r.set_inf();
00663 }
00664 else
00665 {
00666 r = 1.0;
00667 r.exponent( exp );
00668 }
00669 return r;
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 inline
00681 double
00682 uint64_to_double( uint64 a )
00683 {
00684 #if defined( _MSC_VER ) || defined( __clang__ )
00685
00686 double tmp = static_cast<double>( static_cast<int64>( a ) );
00687 return ( tmp >= 0 ) ? tmp : tmp + sc_dt::scfx_pow2( 64 );
00688 #else
00689 return static_cast<double>( a );
00690 #endif
00691 }
00692
00693 }
00694
00695 #undef SCFX_MASK_
00696
00697 #endif
00698
00699