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