Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

sc_fxnum.cpp

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-2004 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.3 (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   sc_fxnum.cpp - 
00021 
00022   Original Author: Martin Janssen, Synopsys, Inc.
00023 
00024  *****************************************************************************/
00025 
00026 /*****************************************************************************
00027 
00028   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
00029   changes you are making here.
00030 
00031       Name, Affiliation, Date:
00032   Description of Modification:
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 //  CLASS : sc_fxnum_bitref
00047 //
00048 //  Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
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 // print or dump content
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 //  CLASS : sc_fxnum_fast_bitref
00094 //
00095 //  Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
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 // print or dump content
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 //  CLASS : sc_fxnum_subref
00141 //
00142 //  Proxy class for part-selection in class sc_fxnum,
00143 //  behaves like sc_bv_base.
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 // print or dump content
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 //  CLASS : sc_fxnum_fast_subref
00190 //
00191 //  Proxy class for part-selection in class sc_fxnum_fast,
00192 //  behaves like sc_bv_base.
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 // print or dump content
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 //  CLASS : sc_fxnum
00239 //
00240 //  Base class for the fixed-point types; arbitrary precision.
00241 // ----------------------------------------------------------------------------
00242 
00243 // explicit conversion to character string
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 // print or dump content
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     // TO BE COMPLETED
00337     // os << "observer = ";
00338     // if( m_observer != 0 )
00339     //     m_observer->dump( os );
00340     // else
00341     //     os << "0" << endl;
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 //  CLASS : sc_fxnum_fast
00365 //
00366 //  Base class for the fixed-point types; limited precision.
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:      // truncation
00388       {
00389           if( c < 0.0 )
00390         val -= 1.0;
00391     break;
00392       }
00393             case SC_RND:      // rounding to plus infinity
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:     // truncation to zero
00402       {
00403           break;
00404       }
00405             case SC_RND_INF:      // rounding to infinity
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:     // convergent rounding
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:     // rounding to 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:    // rounding to minus infinity
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:     // wrap-around
00483       {
00484     int n_bits = params.n_bits();
00485 
00486           if( n_bits == 0 )
00487     {
00488         // wrap-around all 'wl' bits
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         // wrap-around least significant 'wl - n_bits' bits
00498         val -= floor( val / X ) * X;
00499         if( val > ( X - resolution ) )
00500       val -= X;
00501         
00502         // saturate most significant 'n_bits' bits
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         // saturate all 'wl' bits
00516         if( under )
00517       val = low;
00518         else
00519       val = high;
00520     }
00521     break;
00522       }
00523             case SC_SAT:      // saturation
00524             case SC_SAT_SYM:      // symmetrical saturation
00525       {
00526           if( under )
00527         val = low;
00528     else
00529         val = high;
00530     break;
00531       }
00532             case SC_SAT_ZERO:     // saturation to zero
00533       {
00534           val = 0.0;
00535     break;
00536       }
00537             case SC_WRAP_SM:      // sign magnitude wrap-around
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         // invert conditionally
00547         if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) )
00548       val = -val - resolution;
00549 
00550         // wrap-around all 'wl' bits
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         // invert conditionally
00558         if( c2.is_neg() != c2.get_bit( iwl - 1 ) )
00559       val = -val - resolution;
00560 
00561         // wrap-around all 'wl' bits
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         // invert conditionally
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         // wrap-around least significant 'wl - n_bits' bits
00575         val -= floor( val / X ) * X;
00576         if( val > ( X - resolution ) )
00577       val -= X;
00578 
00579         // saturate most significant 'n_bits' bits
00580         if( under )
00581             val += low;
00582         else
00583       val += full_circle / 2.0 - X;
00584     } else {
00585         // saturate all 'wl' bits
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   // check for special cases
00614 
00615   if( id.is_zero() )
00616   {
00617       if( id.negative() != 0 )
00618           m_val = -m_val;
00619       return;
00620   }
00621 
00622   // perform casting
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   // check for special case: -0
00628 
00629   id = m_val;
00630   if( id.is_zero() && id.negative() != 0 ) {
00631       m_val = -m_val;
00632   }
00633 
00634   // check for special case: NaN of Inf
00635 
00636   if( id.is_nan() || id.is_inf() ) {
00637       m_val = 0.0;
00638   }
00639     }
00640 }
00641 
00642 
00643 // defined in sc_fxval.cpp;
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 // explicit conversion to character string
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 // print or dump content
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     // TO BE COMPLETED
00746     // os << "observer = ";
00747     // if( m_observer != 0 )
00748     //     m_observer->dump( os );
00749     // else
00750     //     os << "0" << endl;
00751     os << ")" << endl;
00752 }
00753 
00754 
00755 // internal use only;
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     // convert to two's complement
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     // get the right bit
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     // convert to two's complement
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     // get the bits
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     // set the bits
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 } // namespace sc_dt
00939 
00940 
00941 // Taf!

Generated on Fri Jan 14 08:29:01 2005 for SystemC2.1beta11(excludingMSLib)(IncludingSCV)\nProvidedby:www.openverificationfoundation.org by doxygen1.2.18