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