src/sysc/datatypes/fx/scfx_rep.h

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   The following code is derived, directly or indirectly, from the SystemC
00004   source code Copyright (c) 1996-2005 by all Contributors.
00005   All Rights reserved.
00006 
00007   The contents of this file are subject to the restrictions and limitations
00008   set forth in the SystemC Open Source License Version 2.4 (the "License");
00009   You may not use this file except in compliance with such restrictions and
00010   limitations. You may obtain instructions on how to receive a copy of the
00011   License at http://www.systemc.org/. Software distributed by Contributors
00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
00013   ANY KIND, either express or implied. See the License for the specific
00014   language governing rights and limitations under the License.
00015 
00016  *****************************************************************************/
00017 
00018 /*****************************************************************************
00019 
00020   scfx_rep.h - 
00021 
00022   Original Author: Robert Graulich, Synopsys, Inc.
00023                    Martin Janssen,  Synopsys, Inc.
00024 
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028 
00029   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00030   changes you are making here.
00031 
00032       Name, Affiliation, Date:
00033   Description of Modification:
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 // classes defined in this module
00052 class scfx_index;
00053 class scfx_rep;
00054 
00055 // forward class declarations
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 //  CLASS : scfx_index
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 //  CLASS : scfx_rep
00093 //
00094 //  Arbitrary-precision fixed-point implementation class.
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     // constructors
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     // copy constructor
00124 
00125              scfx_rep( const scfx_rep& );
00126 
00127 
00128     // destructor
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     // assignment operator
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 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
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 // constructors
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 // destructor
00309 
00310 inline
00311 scfx_rep::~scfx_rep()
00312 {}
00313 
00314 
00315 // assignment operator
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 } // namespace sc_dt
00796 
00797 
00798 #endif
00799 
00800 // Taf!

Generated on Wed Apr 25 13:53:26 2007 for SystemC by  doxygen 1.5.1