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
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef SCFX_REP_H
00067 #define SCFX_REP_H
00068
00069
00070 #include <climits>
00071
00072 #include "sysc/datatypes/fx/scfx_mant.h"
00073 #include "sysc/datatypes/fx/scfx_params.h"
00074 #include "sysc/datatypes/fx/scfx_string.h"
00075
00076
00077 namespace sc_dt
00078 {
00079
00080
00081 class scfx_index;
00082 class scfx_rep;
00083
00084
00085 class sc_bv_base;
00086 class sc_signed;
00087 class sc_unsigned;
00088
00089
00090 void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&,
00091 int max_wl = SC_DEFAULT_MAX_WL_ );
00092 scfx_rep* neg_scfx_rep( const scfx_rep& );
00093 scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&,
00094 int max_wl = SC_DEFAULT_MAX_WL_ );
00095 scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&,
00096 int max_wl = SC_DEFAULT_DIV_WL_ );
00097 scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&,
00098 int max_wl = SC_DEFAULT_MAX_WL_ );
00099 scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&,
00100 int max_wl = SC_DEFAULT_MAX_WL_ );
00101 scfx_rep* lsh_scfx_rep( const scfx_rep&, int );
00102 scfx_rep* rsh_scfx_rep( const scfx_rep&, int );
00103 int cmp_scfx_rep( const scfx_rep&, const scfx_rep& );
00104
00105
00106 const int min_mant = 4;
00107
00108 const int bits_in_int = sizeof(int) * CHAR_BIT;
00109 const int bits_in_word = sizeof(word) * CHAR_BIT;
00110
00114
00115 struct scfx_rep_list_lock {
00116 static pthread_mutex_t m_mutex;
00117 explicit scfx_rep_list_lock();
00118 ~scfx_rep_list_lock();
00119 };
00120
00124
00125 struct scfx_rep_pow10_fx_lock {
00126 static pthread_mutex_t m_mutex;
00127 explicit scfx_rep_pow10_fx_lock();
00128 ~scfx_rep_pow10_fx_lock();
00129 };
00130
00134
00135 struct scfx_rep_scfx_string_lock {
00136 static pthread_mutex_t m_mutex;
00137 explicit scfx_rep_scfx_string_lock();
00138 ~scfx_rep_scfx_string_lock();
00139 };
00140
00141
00142
00143
00144
00145
00146 class scfx_index
00147 {
00148
00149 public:
00150
00151 scfx_index( int wi_, int bi_ ) : m_wi( wi_ ), m_bi( bi_ ) {}
00152
00153 int wi() const { return m_wi; }
00154 int bi() const { return m_bi; }
00155
00156 void wi( int wi_ ) { m_wi = wi_; }
00157
00158 private:
00159
00160 int m_wi;
00161 int m_bi;
00162
00163 };
00164
00165
00166
00167
00168
00169
00170
00171
00172 class scfx_rep
00173 {
00174 enum state
00175 {
00176 normal,
00177 infinity,
00178 not_a_number
00179 };
00180
00181 public:
00182
00183
00184
00185 scfx_rep();
00186 explicit scfx_rep( int );
00187 explicit scfx_rep( unsigned int );
00188 explicit scfx_rep( long );
00189 explicit scfx_rep( unsigned long );
00190 explicit scfx_rep( double );
00191 explicit scfx_rep( const char* );
00192 explicit scfx_rep( int64 );
00193 explicit scfx_rep( uint64 );
00194 explicit scfx_rep( const sc_signed& );
00195 explicit scfx_rep( const sc_unsigned& );
00196
00197
00198
00199
00200 scfx_rep( const scfx_rep& );
00201
00202
00203
00204
00205 ~scfx_rep();
00206
00207
00208 void* operator new( std::size_t );
00209 void operator delete( void*, std::size_t );
00210
00211
00212 void from_string( const char*, int );
00213
00214 double to_double() const;
00215
00216 const char* to_string( sc_numrep,
00217 int,
00218 sc_fmt,
00219 const scfx_params* = 0 ) const;
00220
00221
00222
00223
00224 void operator = ( const scfx_rep& );
00225
00226 friend void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int );
00227
00228 friend scfx_rep* neg_scfx_rep( const scfx_rep& );
00229 friend scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int );
00230 friend scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int );
00231 friend scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int );
00232 friend scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int );
00233 friend scfx_rep* lsh_scfx_rep( const scfx_rep&, int );
00234 friend scfx_rep* rsh_scfx_rep( const scfx_rep&, int );
00235
00236 void lshift( int );
00237 void rshift( int );
00238
00239 friend int cmp_scfx_rep( const scfx_rep&, const scfx_rep& );
00240
00241 void cast( const scfx_params&, bool&, bool& );
00242
00243 bool is_neg() const;
00244 bool is_zero() const;
00245 bool is_nan() const;
00246 bool is_inf() const;
00247 bool is_normal() const;
00248
00249 void set_zero( int = 1 );
00250 void set_nan();
00251 void set_inf( int );
00252
00253 bool get_bit( int ) const;
00254 bool set( int, const scfx_params& );
00255 bool clear( int, const scfx_params& );
00256
00257 bool get_slice( int, int, const scfx_params&, sc_bv_base& ) const;
00258 bool set_slice( int, int, const scfx_params&, const sc_bv_base& );
00259
00260 void print( ::std::ostream& ) const;
00261 void dump( ::std::ostream& ) const;
00262
00263 void get_type( int&, int&, sc_enc& ) const;
00264
00265 friend scfx_rep* quantization_scfx_rep( const scfx_rep&,
00266 const scfx_params&,
00267 bool& );
00268 friend scfx_rep* overflow_scfx_rep( const scfx_rep&,
00269 const scfx_params&,
00270 bool& );
00271
00272 bool rounding_flag() const;
00273
00274 private:
00275
00276 friend void align( const scfx_rep&, const scfx_rep&, int&, int&,
00277 scfx_mant_ref&, scfx_mant_ref& );
00278 friend int compare_msw( const scfx_rep&, const scfx_rep& );
00279 friend int compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs );
00280 unsigned int divide_by_ten();
00281 int find_lsw() const;
00282 int find_msw() const;
00283 void find_sw();
00284 void multiply_by_ten();
00285 void normalize( int );
00286 scfx_mant* resize( int, int ) const;
00287 void set_bin( int );
00288 void set_oct( int, int );
00289 void set_hex( int, int );
00290 void shift_left( int );
00291 void shift_right( int );
00292
00293 const scfx_index calc_indices( int ) const;
00294
00295 void o_extend( const scfx_index&, sc_enc );
00296 bool o_bit_at( const scfx_index& ) const;
00297 bool o_zero_left( const scfx_index& ) const;
00298 bool o_zero_right( const scfx_index& ) const;
00299 void o_set_low( const scfx_index&, sc_enc );
00300 void o_set_high( const scfx_index&, const scfx_index&, sc_enc, int = 1 );
00301 void o_set( const scfx_index&, const scfx_index&, sc_enc, bool );
00302 void o_invert( const scfx_index& );
00303 bool q_bit( const scfx_index& ) const;
00304 void q_clear( const scfx_index& );
00305 void q_incr( const scfx_index& );
00306 bool q_odd( const scfx_index& ) const;
00307 bool q_zero( const scfx_index& ) const;
00308
00309 void resize_to( int, int = 0 );
00310 int size() const;
00311 void toggle_tc();
00312
00313 friend void print_dec( scfx_string&, const scfx_rep&, int, sc_fmt );
00314 friend void print_other( scfx_string&, const scfx_rep&, sc_numrep, int,
00315 sc_fmt, const scfx_params* );
00316
00317 void quantization( const scfx_params&, bool& );
00318 void overflow( const scfx_params&, bool& );
00319
00320 friend int compare_abs( const scfx_rep&, const scfx_rep& );
00321
00322 void round( int );
00323
00324 private:
00325
00326 scfx_mant m_mant;
00327 int m_wp;
00328 int m_sign;
00329 state m_state;
00330 int m_msw;
00331 int m_lsw;
00332 bool m_r_flag;
00333
00334 };
00335
00336
00337
00338
00339 inline
00340 void
00341 scfx_rep::set_zero( int sign )
00342 {
00343 m_mant.clear();
00344 m_wp = m_msw = m_lsw = 0;
00345 m_sign = sign;
00346 m_state = normal;
00347 }
00348
00349 inline
00350 void
00351 scfx_rep::set_nan()
00352 {
00353 m_mant.resize_to( min_mant );
00354 m_state = not_a_number;
00355 }
00356
00357 inline
00358 void
00359 scfx_rep::set_inf( int sign )
00360 {
00361 m_mant.resize_to( min_mant );
00362 m_state = infinity;
00363 m_sign = sign;
00364 }
00365
00366
00367
00368
00369 inline
00370 scfx_rep::scfx_rep( const char* s )
00371 : m_mant( min_mant ), m_wp( 2 ), m_sign( 1 ), m_state( normal ),
00372 m_msw(0), m_lsw(0), m_r_flag( false )
00373 {
00374 from_string( s, SC_DEFAULT_CTE_WL_ );
00375 }
00376
00377
00378
00379
00380 inline
00381 scfx_rep::~scfx_rep()
00382 {}
00383
00384
00385
00386
00387 inline
00388 void
00389 scfx_rep::operator = ( const scfx_rep& f )
00390 {
00391 if( &f != this )
00392 {
00393 m_mant = f.m_mant;
00394 m_wp = f.m_wp;
00395 m_sign = f.m_sign;
00396 m_state = f.m_state;
00397 m_msw = f.m_msw;
00398 m_lsw = f.m_lsw;
00399 round( SC_DEFAULT_MAX_WL_ );
00400 }
00401 }
00402
00403 inline
00404 scfx_rep*
00405 neg_scfx_rep( const scfx_rep& a )
00406 {
00407 scfx_rep& c = *new scfx_rep( a );
00408 c.m_sign = - c.m_sign;
00409 return &c;
00410 }
00411
00412 inline
00413 scfx_rep*
00414 mult_scfx_rep( const scfx_rep& a, const scfx_rep& b, int max_wl )
00415 {
00416 scfx_rep& c = *new scfx_rep;
00417 sc_dt::multiply( c, a, b, max_wl );
00418 return &c;
00419 }
00420
00421 inline
00422 scfx_rep*
00423 lsh_scfx_rep( const scfx_rep& a, int b )
00424 {
00425 scfx_rep& c = *new scfx_rep( a );
00426 c.lshift( b );
00427 return &c;
00428 }
00429
00430 inline
00431 scfx_rep*
00432 rsh_scfx_rep( const scfx_rep& a, int b )
00433 {
00434 scfx_rep& c = *new scfx_rep( a );
00435 c.rshift( b );
00436 return &c;
00437 }
00438
00439 inline
00440 int
00441 scfx_rep::size() const
00442 {
00443 return m_mant.size();
00444 }
00445
00446 inline
00447 bool
00448 scfx_rep::is_neg() const
00449 {
00450 return ( m_sign == -1 );
00451 }
00452
00453 inline
00454 bool
00455 scfx_rep::is_zero() const
00456 {
00457 if( m_state != normal )
00458 return false;
00459
00460 for( int i = 0; i < size(); i ++ )
00461 {
00462 if( m_mant[i] )
00463 return false;
00464 }
00465
00466 return true;
00467 }
00468
00469 inline
00470 bool
00471 scfx_rep::is_nan() const
00472 {
00473 return ( m_state == not_a_number );
00474 }
00475
00476 inline
00477 bool
00478 scfx_rep::is_inf() const
00479 {
00480 return ( m_state == infinity );
00481 }
00482
00483 inline
00484 bool
00485 scfx_rep::is_normal() const
00486 {
00487 return ( m_state == normal );
00488 }
00489
00490 inline
00491 scfx_rep*
00492 quantization_scfx_rep( const scfx_rep& a,
00493 const scfx_params& params,
00494 bool& q_flag )
00495 {
00496 scfx_rep& c = *new scfx_rep( a );
00497 c.quantization( params, q_flag );
00498 return &c;
00499 }
00500
00501 inline
00502 scfx_rep*
00503 overflow_scfx_rep( const scfx_rep& a,
00504 const scfx_params& params,
00505 bool& o_flag )
00506 {
00507 scfx_rep& c = *new scfx_rep( a );
00508 c.overflow( params, o_flag );
00509 return &c;
00510 }
00511
00512 inline
00513 bool
00514 scfx_rep::rounding_flag() const
00515 {
00516 return m_r_flag;
00517 }
00518
00519 inline
00520 void
00521 scfx_rep::resize_to( int new_size, int restore )
00522 {
00523 if( restore == -1 )
00524 {
00525 int size_incr = new_size - size();
00526 m_wp += size_incr;
00527 m_msw += size_incr;
00528 m_lsw += size_incr;
00529 }
00530 m_mant.resize_to( new_size, restore );
00531 }
00532
00533 inline
00534 const scfx_index
00535 scfx_rep::calc_indices( int n ) const
00536 {
00537 int wi = n / bits_in_word + m_wp;
00538 int bi = n % bits_in_word;
00539
00540 if( bi < 0 )
00541 {
00542 bi += bits_in_word;
00543 -- wi;
00544 }
00545
00546 return scfx_index( wi, bi );
00547 }
00548
00549 inline
00550 void
00551 scfx_rep::o_extend( const scfx_index& x, sc_enc enc )
00552 {
00553 int wi = x.wi();
00554 int bi = x.bi();
00555
00556 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00557
00558 if( enc == SC_US_ || ( m_mant[wi] & ( ((word)1) << bi ) ) == 0 )
00559 {
00560 if( bi != bits_in_word - 1 )
00561 m_mant[wi] &= ~( ((word)-1) << ( bi + 1 ) );
00562 for( int i = wi + 1; i < size(); ++ i )
00563 m_mant[i] = 0;
00564 m_sign = 1;
00565 }
00566 else
00567 {
00568 if( bi != bits_in_word - 1 )
00569 m_mant[wi] |= ( ((word)-1) << ( bi + 1 ) );
00570 for( int i = wi + 1; i < size(); ++ i )
00571 m_mant[i] = static_cast<word>( -1 );
00572 m_sign = -1;
00573 }
00574 }
00575
00576 inline
00577 bool
00578 scfx_rep::o_bit_at( const scfx_index& x ) const
00579 {
00580 int wi = x.wi();
00581 int bi = x.bi();
00582
00583 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00584
00585 return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0;
00586 }
00587
00588 inline
00589 bool
00590 scfx_rep::o_zero_left( const scfx_index& x ) const
00591 {
00592 int wi = x.wi();
00593 int bi = x.bi();
00594
00595 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00596
00597 bool zero = true;
00598 if( bi != bits_in_word - 1 )
00599 zero = ( m_mant[wi] & ( ((word)-1) << ( bi + 1 ) ) ) == 0;
00600 for( int i = wi + 1; i < size(); ++ i )
00601 zero = zero && m_mant[i] == 0;
00602
00603 return zero;
00604 }
00605
00606 inline
00607 bool
00608 scfx_rep::o_zero_right( const scfx_index& x ) const
00609 {
00610 int wi = x.wi();
00611 int bi = x.bi();
00612
00613 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00614
00615 bool zero = ( m_mant[wi] & ~( ((word)-1) << bi ) ) == 0;
00616 for( int i = wi - 1; i >= 0; -- i )
00617 zero = zero && m_mant[i] == 0;
00618
00619 return zero;
00620 }
00621
00622 inline
00623 void
00624 scfx_rep::o_set_low( const scfx_index& x, sc_enc enc )
00625 {
00626 int wi = x.wi();
00627 int bi = x.bi();
00628
00629 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00630
00631 m_mant.clear();
00632
00633 if( enc == SC_TC_ )
00634 {
00635 m_mant[wi] |= ( ((word)1) << bi );
00636 m_sign = -1;
00637 }
00638 else
00639 m_sign = 1;
00640 }
00641
00642 inline
00643 void
00644 scfx_rep::o_set_high( const scfx_index& x, const scfx_index& x2,
00645 sc_enc enc, int sign )
00646 {
00647 int wi = x.wi();
00648 int bi = x.bi();
00649 int wi2 = x2.wi();
00650 int bi2 = x2.bi();
00651
00652 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00653 SC_ASSERT_( wi2 >= 0 && wi2 < size(), "word index out of range" );
00654
00655 int i;
00656
00657 for( i = 0; i < size(); ++ i )
00658 m_mant[i] = static_cast<word>( -1 );
00659
00660 m_mant[wi] &= ~( ((word)-1) << bi );
00661 for( i = wi + 1; i < size(); ++ i )
00662 m_mant[i] = 0;
00663
00664 m_mant[wi2] &= ( ((word)-1) << bi2 );
00665 for( i = wi2 - 1; i >= 0; -- i )
00666 m_mant[i] = 0;
00667
00668 if( enc == SC_TC_ )
00669 m_sign = sign;
00670 else
00671 {
00672 m_mant[wi] |= ( ((word)1) << bi );
00673 m_sign = 1;
00674 }
00675 }
00676
00677 inline
00678 void
00679 scfx_rep::o_set( const scfx_index& x, const scfx_index& x3,
00680 sc_enc enc, bool under )
00681 {
00682 int wi = x.wi();
00683 int bi = x.bi();
00684 int wi3 = x3.wi();
00685 int bi3 = x3.bi();
00686
00687 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00688 SC_ASSERT_( wi3 >= 0 && wi3 < size(), "word index out of range" );
00689
00690 if( bi3 != bits_in_word - 1 )
00691 {
00692 if( under )
00693 m_mant[wi3] &= ~( ((word)-1) << ( bi3 + 1 ) );
00694 else
00695 m_mant[wi3] |= ( ((word)-1) << ( bi3 + 1 ) );
00696 }
00697 for( int i = wi3 + 1; i < size(); ++ i )
00698 {
00699 if( under )
00700 m_mant[i] = 0;
00701 else
00702 m_mant[i] = static_cast<word>( -1 );
00703 }
00704
00705 if( enc == SC_TC_ )
00706 {
00707 if( under )
00708 m_mant[wi] |= ( ((word)1) << bi );
00709 else
00710 m_mant[wi] &= ~( ((word)1) << bi );
00711 }
00712 }
00713
00714 inline
00715 void
00716 scfx_rep::o_invert( const scfx_index& x2 )
00717 {
00718 int wi2 = x2.wi();
00719 int bi2 = x2.bi();
00720
00721 m_mant[wi2] ^= ( ((word)-1) << bi2 );
00722 for( int i = wi2 + 1; i < size(); ++ i )
00723 m_mant[i] = ~ m_mant[i];
00724 }
00725
00726 inline
00727 bool
00728 scfx_rep::q_bit( const scfx_index& x ) const
00729 {
00730 int wi = x.wi();
00731 int bi = x.bi();
00732
00733 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00734
00735 if( bi != 0 )
00736 return ( m_mant[wi] & ( ((word)1) << ( bi - 1 ) ) ) != 0;
00737 else if( wi != 0 )
00738 return ( m_mant[wi - 1] & ( ((word)1) << ( bits_in_word - 1 ) ) ) != 0;
00739 else
00740 return false;
00741 }
00742
00743 inline
00744 void
00745 scfx_rep::q_clear( const scfx_index& x )
00746 {
00747 int wi = x.wi();
00748 int bi = x.bi();
00749
00750 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00751
00752 m_mant[wi] &= ( ((word)-1) << bi );
00753 for( int i = wi - 1; i >= 0; -- i )
00754 m_mant[i] = 0;
00755 }
00756
00757 inline
00758 void
00759 scfx_rep::q_incr( const scfx_index& x )
00760 {
00761 int wi = x.wi();
00762 int bi = x.bi();
00763
00764 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00765
00766 word old_val = m_mant[wi];
00767 m_mant[wi] += ( ((word)1) << bi );
00768 if( m_mant[wi] <= old_val )
00769 {
00770 if( wi + 1 == size() )
00771 resize_to( size() + 1, 1 );
00772
00773 for( int i = wi + 1; i < size(); ++ i )
00774 {
00775 if( ++ m_mant[i] != 0 )
00776 break;
00777 }
00778 }
00779 }
00780
00781 inline
00782 bool
00783 scfx_rep::q_odd( const scfx_index& x ) const
00784 {
00785 int wi = x.wi();
00786 int bi = x.bi();
00787
00788 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00789
00790 return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0;
00791 }
00792
00793 inline
00794 bool
00795 scfx_rep::q_zero( const scfx_index& x ) const
00796 {
00797 int wi = x.wi();
00798 int bi = x.bi();
00799
00800 SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" );
00801
00802 bool zero;
00803
00804 if( bi != 0 )
00805 {
00806 zero = ( m_mant[wi] & ~( ((word)-1) << (bi - 1) ) ) == 0;
00807 for( int i = wi - 1; i >= 0; -- i )
00808 zero = zero && m_mant[i] == 0;
00809 }
00810 else if( wi != 0 )
00811 {
00812 zero = ( m_mant[wi - 1] & ~( ((word)-1) << (bits_in_word - 1) ) ) == 0;
00813 for( int i = wi - 2; i >= 0; -- i )
00814 zero = zero && m_mant[i] == 0;
00815 }
00816 else
00817 zero = true;
00818
00819 return zero;
00820 }
00821
00822 inline
00823 int
00824 scfx_rep::find_lsw() const
00825 {
00826 for( int i = 0; i < size(); i ++ )
00827 {
00828 if( m_mant[i] )
00829 return i;
00830 }
00831 return 0;
00832 }
00833
00834 inline
00835 int
00836 scfx_rep::find_msw() const
00837 {
00838 for( int i = size() - 1; i >= 0; i -- )
00839 {
00840 if( m_mant[i] )
00841 return i;
00842 }
00843 return 0;
00844 }
00845
00846 inline
00847 void
00848 scfx_rep::find_sw()
00849 {
00850 m_lsw = find_lsw();
00851 m_msw = find_msw();
00852 }
00853
00854 inline
00855 void
00856 scfx_rep::toggle_tc()
00857 {
00858 if( is_neg() )
00859 {
00860 complement( m_mant, m_mant, m_mant.size() );
00861 inc( m_mant );
00862 }
00863 }
00864
00865 }
00866
00867
00868 #endif
00869
00870