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 #include <math.h>
00038
00039 #include "systemc/datatypes/fx/sc_fxnum.h"
00040
00041
00042 namespace sc_dt
00043 {
00044
00045
00046
00047
00048
00049
00050
00051 bool
00052 sc_fxnum_bitref::get() const
00053 {
00054 return m_num.get_bit( m_idx );
00055 }
00056
00057 void
00058 sc_fxnum_bitref::set( bool high )
00059 {
00060 m_num.set_bit( m_idx, high );
00061 }
00062
00063
00064
00065
00066 void
00067 sc_fxnum_bitref::print( ostream& os ) const
00068 {
00069 os << get();
00070 }
00071
00072 void
00073 sc_fxnum_bitref::scan( istream& is )
00074 {
00075 bool b;
00076 is >> b;
00077 *this = b;
00078 }
00079
00080 void
00081 sc_fxnum_bitref::dump( ostream& os ) const
00082 {
00083 os << "sc_fxnum_bitref" << endl;
00084 os << "(" << endl;
00085 os << "num = ";
00086 m_num.dump( os );
00087 os << "idx = " << m_idx << endl;
00088 os << ")" << endl;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098 bool
00099 sc_fxnum_fast_bitref::get() const
00100 {
00101 return m_num.get_bit( m_idx );
00102 }
00103
00104 void
00105 sc_fxnum_fast_bitref::set( bool high )
00106 {
00107 m_num.set_bit( m_idx, high );
00108 }
00109
00110
00111
00112
00113 void
00114 sc_fxnum_fast_bitref::print( ostream& os ) const
00115 {
00116 os << get();
00117 }
00118
00119 void
00120 sc_fxnum_fast_bitref::scan( istream& is )
00121 {
00122 bool b;
00123 is >> b;
00124 *this = b;
00125 }
00126
00127 void
00128 sc_fxnum_fast_bitref::dump( ostream& os ) const
00129 {
00130 os << "sc_fxnum_fast_bitref" << endl;
00131 os << "(" << endl;
00132 os << "num = ";
00133 m_num.dump( os );
00134 os << "idx = " << m_idx << endl;
00135 os << ")" << endl;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 bool
00147 sc_fxnum_subref::get() const
00148 {
00149 return m_num.get_slice( m_from, m_to, m_bv );
00150 }
00151
00152 bool
00153 sc_fxnum_subref::set()
00154 {
00155 return m_num.set_slice( m_from, m_to, m_bv );
00156 }
00157
00158
00159
00160
00161 void
00162 sc_fxnum_subref::print( ostream& os ) const
00163 {
00164 get();
00165 m_bv.print( os );
00166 }
00167
00168 void
00169 sc_fxnum_subref::scan( istream& is )
00170 {
00171 m_bv.scan( is );
00172 set();
00173 }
00174
00175 void
00176 sc_fxnum_subref::dump( ostream& os ) const
00177 {
00178 os << "sc_fxnum_subref" << endl;
00179 os << "(" << endl;
00180 os << "num = ";
00181 m_num.dump( os );
00182 os << "from = " << m_from << endl;
00183 os << "to = " << m_to << endl;
00184 os << ")" << endl;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 bool
00196 sc_fxnum_fast_subref::get() const
00197 {
00198 return m_num.get_slice( m_from, m_to, m_bv );
00199 }
00200
00201 bool
00202 sc_fxnum_fast_subref::set()
00203 {
00204 return m_num.set_slice( m_from, m_to, m_bv );
00205 }
00206
00207
00208
00209
00210 void
00211 sc_fxnum_fast_subref::print( ostream& os ) const
00212 {
00213 get();
00214 m_bv.print( os );
00215 }
00216
00217 void
00218 sc_fxnum_fast_subref::scan( istream& is )
00219 {
00220 m_bv.scan( is );
00221 set();
00222 }
00223
00224 void
00225 sc_fxnum_fast_subref::dump( ostream& os ) const
00226 {
00227 os << "sc_fxnum_fast_subref" << endl;
00228 os << "(" << endl;
00229 os << "num = ";
00230 m_num.dump( os );
00231 os << "from = " << m_from << endl;
00232 os << "to = " << m_to << endl;
00233 os << ")" << endl;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 const sc_string
00246 sc_fxnum::to_string() const
00247 {
00248 return sc_string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
00249 }
00250
00251 const sc_string
00252 sc_fxnum::to_string( sc_numrep numrep ) const
00253 {
00254 return sc_string( m_rep->to_string( numrep, -1, SC_F, &m_params ) );
00255 }
00256
00257 const sc_string
00258 sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const
00259 {
00260 return sc_string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
00261 SC_F, &m_params ) );
00262 }
00263
00264 const sc_string
00265 sc_fxnum::to_string( sc_fmt fmt ) const
00266 {
00267 return sc_string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) );
00268 }
00269
00270 const sc_string
00271 sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const
00272 {
00273 return sc_string( m_rep->to_string( numrep, -1, fmt, &m_params ) );
00274 }
00275
00276 const sc_string
00277 sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
00278 {
00279 return sc_string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
00280 fmt, &m_params ) );
00281 }
00282
00283
00284 const sc_string
00285 sc_fxnum::to_dec() const
00286 {
00287 return sc_string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
00288 }
00289
00290 const sc_string
00291 sc_fxnum::to_bin() const
00292 {
00293 return sc_string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) );
00294 }
00295
00296 const sc_string
00297 sc_fxnum::to_oct() const
00298 {
00299 return sc_string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) );
00300 }
00301
00302 const sc_string
00303 sc_fxnum::to_hex() const
00304 {
00305 return sc_string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) );
00306 }
00307
00308
00309
00310
00311 void
00312 sc_fxnum::print( ostream& os ) const
00313 {
00314 os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params );
00315 }
00316
00317 void
00318 sc_fxnum::scan( istream& is )
00319 {
00320 sc_string s;
00321 is >> s;
00322 *this = s.c_str();
00323 }
00324
00325 void
00326 sc_fxnum::dump( ostream& os ) const
00327 {
00328 os << "sc_fxnum" << endl;
00329 os << "(" << endl;
00330 os << "rep = ";
00331 m_rep->dump( os );
00332 os << "params = ";
00333 m_params.dump( os );
00334 os << "q_flag = " << m_q_flag << endl;
00335 os << "o_flag = " << m_o_flag << endl;
00336
00337
00338
00339
00340
00341
00342 os << ")" << endl;
00343 }
00344
00345
00346 sc_fxnum_observer*
00347 sc_fxnum::lock_observer() const
00348 {
00349 SC_ASSERT_( m_observer != 0, "lock observer failed" );
00350 sc_fxnum_observer* tmp = m_observer;
00351 m_observer = 0;
00352 return tmp;
00353 }
00354
00355 void
00356 sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const
00357 {
00358 SC_ASSERT_( observer_ != 0, "unlock observer failed" );
00359 m_observer = observer_;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369 static
00370 void
00371 quantization( double& c, const scfx_params& params, bool& q_flag )
00372 {
00373 int fwl = params.wl() - params.iwl();
00374 double scale = scfx_pow2( fwl );
00375 double val = scale * c;
00376 double int_part;
00377 double frac_part = modf( val, &int_part );
00378
00379 q_flag = ( frac_part != 0.0 );
00380
00381 if( q_flag )
00382 {
00383 val = int_part;
00384
00385 switch( params.q_mode() )
00386 {
00387 case SC_TRN:
00388 {
00389 if( c < 0.0 )
00390 val -= 1.0;
00391 break;
00392 }
00393 case SC_RND:
00394 {
00395 if( frac_part >= 0.5 )
00396 val += 1.0;
00397 else if( frac_part < -0.5 )
00398 val -= 1.0;
00399 break;
00400 }
00401 case SC_TRN_ZERO:
00402 {
00403 break;
00404 }
00405 case SC_RND_INF:
00406 {
00407 if( frac_part >= 0.5 )
00408 val += 1.0;
00409 else if( frac_part <= -0.5 )
00410 val -= 1.0;
00411 break;
00412 }
00413 case SC_RND_CONV:
00414 {
00415 if( frac_part > 0.5 ||
00416 frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 )
00417 val += 1.0;
00418 else if( frac_part < -0.5 ||
00419 frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 )
00420 val -= 1.0;
00421 break;
00422 }
00423 case SC_RND_ZERO:
00424 {
00425 if( frac_part > 0.5 )
00426 val += 1.0;
00427 else if( frac_part < -0.5 )
00428 val -= 1.0;
00429 break;
00430 }
00431 case SC_RND_MIN_INF:
00432 {
00433 if( frac_part > 0.5 )
00434 val += 1.0;
00435 else if( frac_part <= -0.5 )
00436 val -= 1.0;
00437 break;
00438 }
00439 default:
00440 ;
00441 }
00442 }
00443
00444 val /= scale;
00445 c = val;
00446 }
00447
00448 static
00449 void
00450 overflow( double& c, const scfx_params& params, bool& o_flag )
00451 {
00452 int iwl = params.iwl();
00453 int fwl = params.wl() - iwl;
00454 double full_circle = scfx_pow2( iwl );
00455 double resolution = scfx_pow2( -fwl );
00456 double low, high;
00457 if( params.enc() == SC_TC_ )
00458 {
00459 high = full_circle / 2.0 - resolution;
00460 if( params.o_mode() == SC_SAT_SYM )
00461 low = - high;
00462 else
00463 low = - full_circle / 2.0;
00464 }
00465 else
00466 {
00467 low = 0.0;
00468 high = full_circle - resolution;
00469 }
00470 double val = c;
00471 sc_fxval_fast c2 = c;
00472
00473 bool under = ( val < low );
00474 bool over = ( val > high );
00475
00476 o_flag = ( under || over );
00477
00478 if( o_flag )
00479 {
00480 switch( params.o_mode() )
00481 {
00482 case SC_WRAP:
00483 {
00484 int n_bits = params.n_bits();
00485
00486 if( n_bits == 0 )
00487 {
00488
00489 val -= floor( val / full_circle ) * full_circle;
00490 if( val > high )
00491 val -= full_circle;
00492 }
00493 else if( n_bits < params.wl() )
00494 {
00495 double X = scfx_pow2( iwl - n_bits );
00496
00497
00498 val -= floor( val / X ) * X;
00499 if( val > ( X - resolution ) )
00500 val -= X;
00501
00502
00503 if( under )
00504 val += low;
00505 else
00506 {
00507 if( params.enc() == SC_TC_ )
00508 val += full_circle / 2.0 - X;
00509 else
00510 val += full_circle - X;
00511 }
00512 }
00513 else
00514 {
00515
00516 if( under )
00517 val = low;
00518 else
00519 val = high;
00520 }
00521 break;
00522 }
00523 case SC_SAT:
00524 case SC_SAT_SYM:
00525 {
00526 if( under )
00527 val = low;
00528 else
00529 val = high;
00530 break;
00531 }
00532 case SC_SAT_ZERO:
00533 {
00534 val = 0.0;
00535 break;
00536 }
00537 case SC_WRAP_SM:
00538 {
00539 SC_ERROR_IF_( params.enc() == SC_US_,
00540 SC_ID_WRAP_SM_NOT_DEFINED_ );
00541
00542 int n_bits = params.n_bits();
00543
00544 if( n_bits == 0 )
00545 {
00546
00547 if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) )
00548 val = -val - resolution;
00549
00550
00551 val -= floor( val / full_circle ) * full_circle;
00552 if( val > high )
00553 val -= full_circle;
00554 }
00555 else if( n_bits == 1 )
00556 {
00557
00558 if( c2.is_neg() != c2.get_bit( iwl - 1 ) )
00559 val = -val - resolution;
00560
00561
00562 val -= floor( val / full_circle ) * full_circle;
00563 if( val > high )
00564 val -= full_circle;
00565 }
00566 else if( n_bits < params.wl() )
00567 {
00568
00569 if( c2.is_neg() == c2.get_bit( iwl - n_bits ) )
00570 val = -val - resolution;
00571
00572 double X = scfx_pow2( iwl - n_bits );
00573
00574
00575 val -= floor( val / X ) * X;
00576 if( val > ( X - resolution ) )
00577 val -= X;
00578
00579
00580 if( under )
00581 val += low;
00582 else
00583 val += full_circle / 2.0 - X;
00584 } else {
00585
00586 if( under )
00587 val = low;
00588 else
00589 val = high;
00590 }
00591 break;
00592 }
00593 default:
00594 ;
00595 }
00596
00597 c = val;
00598 }
00599 }
00600
00601
00602 void
00603 sc_fxnum_fast::cast()
00604 {
00605 scfx_ieee_double id( m_val );
00606 SC_ERROR_IF_( id.is_nan() || id.is_inf(), SC_ID_INVALID_FX_VALUE_ );
00607
00608 if( m_params.cast_switch() == SC_ON )
00609 {
00610 m_q_flag = false;
00611 m_o_flag = false;
00612
00613
00614
00615 if( id.is_zero() )
00616 {
00617 if( id.negative() != 0 )
00618 m_val = -m_val;
00619 return;
00620 }
00621
00622
00623
00624 sc_dt::quantization( m_val, m_params, m_q_flag );
00625 sc_dt::overflow( m_val, m_params, m_o_flag );
00626
00627
00628
00629 id = m_val;
00630 if( id.is_zero() && id.negative() != 0 ) {
00631 m_val = -m_val;
00632 }
00633
00634
00635
00636 if( id.is_nan() || id.is_inf() ) {
00637 m_val = 0.0;
00638 }
00639 }
00640 }
00641
00642
00643
00644 extern
00645 const char*
00646 to_string( const scfx_ieee_double&,
00647 sc_numrep,
00648 int,
00649 sc_fmt,
00650 const scfx_params* = 0 );
00651
00652
00653
00654
00655 const sc_string
00656 sc_fxnum_fast::to_string() const
00657 {
00658 return sc_string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
00659 }
00660
00661 const sc_string
00662 sc_fxnum_fast::to_string( sc_numrep numrep ) const
00663 {
00664 return sc_string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) );
00665 }
00666
00667 const sc_string
00668 sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const
00669 {
00670 return sc_string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
00671 SC_F, &m_params ) );
00672 }
00673
00674 const sc_string
00675 sc_fxnum_fast::to_string( sc_fmt fmt ) const
00676 {
00677 return sc_string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) );
00678 }
00679
00680 const sc_string
00681 sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const
00682 {
00683 return sc_string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) );
00684 }
00685
00686 const sc_string
00687 sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
00688 {
00689 return sc_string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
00690 fmt, &m_params ) );
00691 }
00692
00693
00694 const sc_string
00695 sc_fxnum_fast::to_dec() const
00696 {
00697 return sc_string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
00698 }
00699
00700 const sc_string
00701 sc_fxnum_fast::to_bin() const
00702 {
00703 return sc_string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) );
00704 }
00705
00706 const sc_string
00707 sc_fxnum_fast::to_oct() const
00708 {
00709 return sc_string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) );
00710 }
00711
00712 const sc_string
00713 sc_fxnum_fast::to_hex() const
00714 {
00715 return sc_string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) );
00716 }
00717
00718
00719
00720
00721 void
00722 sc_fxnum_fast::print( ostream& os ) const
00723 {
00724 os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params );
00725 }
00726
00727 void
00728 sc_fxnum_fast::scan( istream& is )
00729 {
00730 sc_string s;
00731 is >> s;
00732 *this = s.c_str();
00733 }
00734
00735 void
00736 sc_fxnum_fast::dump( ostream& os ) const
00737 {
00738 os << "sc_fxnum_fast" << endl;
00739 os << "(" << endl;
00740 os << "val = " << m_val << endl;
00741 os << "params = ";
00742 m_params.dump( os );
00743 os << "q_flag = " << m_q_flag << endl;
00744 os << "o_flag = " << m_o_flag << endl;
00745
00746
00747
00748
00749
00750
00751 os << ")" << endl;
00752 }
00753
00754
00755
00756 bool
00757 sc_fxnum_fast::get_bit( int i ) const
00758 {
00759 scfx_ieee_double id( m_val );
00760 if( id.is_zero() || id.is_nan() || id.is_inf() )
00761 return false;
00762
00763
00764
00765 unsigned int m0 = id.mantissa0();
00766 unsigned int m1 = id.mantissa1();
00767
00768 if( id.is_normal() )
00769 m0 += 1U << 20;
00770
00771 if( id.negative() != 0 )
00772 {
00773 m0 = ~ m0;
00774 m1 = ~ m1;
00775 unsigned int tmp = m1;
00776 m1 += 1U;
00777 if( m1 <= tmp )
00778 m0 += 1U;
00779 }
00780
00781
00782
00783 int j = i - id.exponent();
00784 if( ( j += 20 ) >= 32 )
00785 return ( ( m0 & 1U << 31 ) != 0 );
00786 else if( j >= 0 )
00787 return ( ( m0 & 1U << j ) != 0 );
00788 else if( ( j += 32 ) >= 0 )
00789 return ( ( m1 & 1U << j ) != 0 );
00790 else
00791 return false;
00792 }
00793
00794
00795 bool
00796 sc_fxnum_fast::set_bit( int i, bool high )
00797 {
00798 scfx_ieee_double id( m_val );
00799 if( id.is_nan() || id.is_inf() )
00800 return false;
00801
00802 if( high )
00803 {
00804 if( get_bit( i ) )
00805 return true;
00806
00807 if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
00808 m_val -= scfx_pow2( i );
00809 else
00810 m_val += scfx_pow2( i );
00811 }
00812 else
00813 {
00814 if( ! get_bit( i ) )
00815 return true;
00816
00817 if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
00818 m_val += scfx_pow2( i );
00819 else
00820 m_val -= scfx_pow2( i );
00821 }
00822
00823 return true;
00824 }
00825
00826
00827 bool
00828 sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const
00829 {
00830 scfx_ieee_double id( m_val );
00831 if( id.is_nan() || id.is_inf() )
00832 return false;
00833
00834
00835
00836 unsigned int m0 = id.mantissa0();
00837 unsigned int m1 = id.mantissa1();
00838
00839 if( id.is_normal() )
00840 m0 += 1U << 20;
00841
00842 if( id.negative() != 0 )
00843 {
00844 m0 = ~ m0;
00845 m1 = ~ m1;
00846 unsigned int tmp = m1;
00847 m1 += 1U;
00848 if( m1 <= tmp )
00849 m0 += 1U;
00850 }
00851
00852
00853
00854 int l = j;
00855 for( int k = 0; k < bv.length(); ++ k )
00856 {
00857 bool b = false;
00858
00859 int n = l - id.exponent();
00860 if( ( n += 20 ) >= 32 )
00861 b = ( ( m0 & 1U << 31 ) != 0 );
00862 else if( n >= 0 )
00863 b = ( ( m0 & 1U << n ) != 0 );
00864 else if( ( n += 32 ) >= 0 )
00865 b = ( ( m1 & 1U << n ) != 0 );
00866
00867 bv[k] = b;
00868
00869 if( i >= j )
00870 ++ l;
00871 else
00872 -- l;
00873 }
00874
00875 return true;
00876 }
00877
00878 bool
00879 sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv )
00880 {
00881 scfx_ieee_double id( m_val );
00882 if( id.is_nan() || id.is_inf() )
00883 return false;
00884
00885
00886
00887 int l = j;
00888 for( int k = 0; k < bv.length(); ++ k )
00889 {
00890 if( bv[k].to_bool() )
00891 {
00892 if( ! get_bit( l ) )
00893 {
00894 if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
00895 m_val -= scfx_pow2( l );
00896 else
00897 m_val += scfx_pow2( l );
00898 }
00899 }
00900 else
00901 {
00902 if( get_bit( l ) )
00903 {
00904 if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
00905 m_val += scfx_pow2( l );
00906 else
00907 m_val -= scfx_pow2( l );
00908 }
00909 }
00910
00911
00912 if( i >= j )
00913 ++ l;
00914 else
00915 -- l;
00916 }
00917
00918 return true;
00919 }
00920
00921
00922 sc_fxnum_fast_observer*
00923 sc_fxnum_fast::lock_observer() const
00924 {
00925 SC_ASSERT_( m_observer != 0, "lock observer failed" );
00926 sc_fxnum_fast_observer* tmp = m_observer;
00927 m_observer = 0;
00928 return tmp;
00929 }
00930
00931 void
00932 sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const
00933 {
00934 SC_ASSERT_( observer_ != 0, "unlock observer failed" );
00935 m_observer = observer_;
00936 }
00937
00938 }
00939
00940
00941