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-2006 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   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 // $Log: sc_fxnum.cpp,v $
00038 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
00039 // SystemC 2.2
00040 //
00041 // Revision 1.3  2006/01/13 18:53:57  acg
00042 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
00043 // the source.
00044 //
00045 
00046 #include <math.h>
00047 
00048 #include "sysc/datatypes/fx/sc_fxnum.h"
00049 
00050 
00051 namespace sc_dt
00052 {
00053 
00054 // ----------------------------------------------------------------------------
00055 //  CLASS : sc_fxnum_bitref
00056 //
00057 //  Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
00058 // ----------------------------------------------------------------------------
00059 
00060 bool
00061 sc_fxnum_bitref::get() const
00062 {
00063     return m_num.get_bit( m_idx );
00064 }
00065 
00066 void
00067 sc_fxnum_bitref::set( bool high )
00068 {
00069     m_num.set_bit( m_idx, high );
00070 }
00071 
00072 
00073 // print or dump content
00074 
00075 void
00076 sc_fxnum_bitref::print( ::std::ostream& os ) const
00077 {
00078     os << get();
00079 }
00080 
00081 void
00082 sc_fxnum_bitref::scan( ::std::istream& is )
00083 {
00084     bool b;
00085     is >> b;
00086     *this = b;
00087 }
00088 
00089 void
00090 sc_fxnum_bitref::dump( ::std::ostream& os ) const
00091 {
00092     os << "sc_fxnum_bitref" << ::std::endl;
00093     os << "(" << ::std::endl;
00094     os << "num = ";
00095     m_num.dump( os );
00096     os << "idx = " << m_idx << ::std::endl;
00097     os << ")" << ::std::endl;
00098 }
00099 
00100 
00101 // ----------------------------------------------------------------------------
00102 //  CLASS : sc_fxnum_fast_bitref
00103 //
00104 //  Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
00105 // ----------------------------------------------------------------------------
00106 
00107 bool
00108 sc_fxnum_fast_bitref::get() const
00109 {
00110     return m_num.get_bit( m_idx );
00111 }
00112 
00113 void
00114 sc_fxnum_fast_bitref::set( bool high )
00115 {
00116     m_num.set_bit( m_idx, high );
00117 }
00118 
00119 
00120 // print or dump content
00121 
00122 void
00123 sc_fxnum_fast_bitref::print( ::std::ostream& os ) const
00124 {
00125     os << get();
00126 }
00127 
00128 void
00129 sc_fxnum_fast_bitref::scan( ::std::istream& is )
00130 {
00131     bool b;
00132     is >> b;
00133     *this = b;
00134 }
00135 
00136 void
00137 sc_fxnum_fast_bitref::dump( ::std::ostream& os ) const
00138 {
00139     os << "sc_fxnum_fast_bitref" << ::std::endl;
00140     os << "(" << ::std::endl;
00141     os << "num = ";
00142     m_num.dump( os );
00143     os << "idx = " << m_idx << ::std::endl;
00144     os << ")" << ::std::endl;
00145 }
00146 
00147 
00148 // ----------------------------------------------------------------------------
00149 //  CLASS : sc_fxnum_subref
00150 //
00151 //  Proxy class for part-selection in class sc_fxnum,
00152 //  behaves like sc_bv_base.
00153 // ----------------------------------------------------------------------------
00154 
00155 bool
00156 sc_fxnum_subref::get() const
00157 {
00158     return m_num.get_slice( m_from, m_to, m_bv );
00159 }
00160 
00161 bool
00162 sc_fxnum_subref::set()
00163 {
00164     return m_num.set_slice( m_from, m_to, m_bv );
00165 }
00166 
00167 
00168 // print or dump content
00169 
00170 void
00171 sc_fxnum_subref::print( ::std::ostream& os ) const
00172 {
00173     get();
00174     m_bv.print( os );
00175 }
00176 
00177 void
00178 sc_fxnum_subref::scan( ::std::istream& is )
00179 {
00180     m_bv.scan( is );
00181     set();
00182 }
00183 
00184 void
00185 sc_fxnum_subref::dump( ::std::ostream& os ) const
00186 {
00187     os << "sc_fxnum_subref" << ::std::endl;
00188     os << "(" << ::std::endl;
00189     os << "num  = ";
00190     m_num.dump( os );
00191     os << "from = " << m_from << ::std::endl;
00192     os << "to   = " << m_to << ::std::endl;
00193     os << ")" << ::std::endl;
00194 }
00195 
00196 
00197 // ----------------------------------------------------------------------------
00198 //  CLASS : sc_fxnum_fast_subref
00199 //
00200 //  Proxy class for part-selection in class sc_fxnum_fast,
00201 //  behaves like sc_bv_base.
00202 // ----------------------------------------------------------------------------
00203 
00204 bool
00205 sc_fxnum_fast_subref::get() const
00206 {
00207     return m_num.get_slice( m_from, m_to, m_bv );
00208 }
00209 
00210 bool
00211 sc_fxnum_fast_subref::set()
00212 {
00213     return m_num.set_slice( m_from, m_to, m_bv );
00214 }
00215 
00216 
00217 // print or dump content
00218 
00219 void
00220 sc_fxnum_fast_subref::print( ::std::ostream& os ) const
00221 {
00222     get();
00223     m_bv.print( os );
00224 }
00225 
00226 void
00227 sc_fxnum_fast_subref::scan( ::std::istream& is )
00228 {
00229     m_bv.scan( is );
00230     set();
00231 }
00232 
00233 void
00234 sc_fxnum_fast_subref::dump( ::std::ostream& os ) const
00235 {
00236     os << "sc_fxnum_fast_subref" << ::std::endl;
00237     os << "(" << ::std::endl;
00238     os << "num  = ";
00239     m_num.dump( os );
00240     os << "from = " << m_from << ::std::endl;
00241     os << "to   = " << m_to << ::std::endl;
00242     os << ")" << ::std::endl;
00243 }
00244 
00245 
00246 // ----------------------------------------------------------------------------
00247 //  CLASS : sc_fxnum
00248 //
00249 //  Base class for the fixed-point types; arbitrary precision.
00250 // ----------------------------------------------------------------------------
00251 
00252 // explicit conversion to character string
00253 
00254 const std::string
00255 sc_fxnum::to_string() const
00256 {
00257     return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
00258 }
00259 
00260 const std::string
00261 sc_fxnum::to_string( sc_numrep numrep ) const
00262 {
00263     return std::string( m_rep->to_string( numrep, -1, SC_F, &m_params ) );
00264 }
00265 
00266 const std::string
00267 sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const
00268 {
00269     return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
00270                     SC_F, &m_params ) );
00271 }
00272 
00273 const std::string
00274 sc_fxnum::to_string( sc_fmt fmt ) const
00275 {
00276     return std::string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) );
00277 }
00278 
00279 const std::string
00280 sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const
00281 {
00282     return std::string( m_rep->to_string( numrep, -1, fmt, &m_params ) );
00283 }
00284 
00285 const std::string
00286 sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
00287 {
00288     return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0),
00289                     fmt, &m_params ) );
00290 }
00291 
00292 
00293 const std::string
00294 sc_fxnum::to_dec() const
00295 {
00296     return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) );
00297 }
00298 
00299 const std::string
00300 sc_fxnum::to_bin() const
00301 {
00302     return std::string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) );
00303 }
00304 
00305 const std::string
00306 sc_fxnum::to_oct() const
00307 {
00308     return std::string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) );
00309 }
00310 
00311 const std::string
00312 sc_fxnum::to_hex() const
00313 {
00314     return std::string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) );
00315 }
00316 
00317 
00318 // print or dump content
00319 
00320 void
00321 sc_fxnum::print( ::std::ostream& os ) const
00322 {
00323     os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params );
00324 }
00325 
00326 void
00327 sc_fxnum::scan( ::std::istream& is )
00328 {
00329     std::string s;
00330     is >> s;
00331     *this = s.c_str();
00332 }
00333 
00334 void
00335 sc_fxnum::dump( ::std::ostream& os ) const
00336 {
00337     os << "sc_fxnum" << ::std::endl;
00338     os << "(" << ::std::endl;
00339     os << "rep      = ";
00340     m_rep->dump( os );
00341     os << "params   = ";
00342     m_params.dump( os );
00343     os << "q_flag   = " << m_q_flag << ::std::endl;
00344     os << "o_flag   = " << m_o_flag << ::std::endl;
00345     // TO BE COMPLETED
00346     // os << "observer = ";
00347     // if( m_observer != 0 )
00348     //     m_observer->dump( os );
00349     // else
00350     //     os << "0" << ::std::endl;
00351     os << ")" << ::std::endl;
00352 }
00353 
00354 
00355 sc_fxnum_observer*
00356 sc_fxnum::lock_observer() const
00357 {
00358     SC_ASSERT_( m_observer != 0, "lock observer failed" );
00359     sc_fxnum_observer* tmp = m_observer;
00360     m_observer = 0;
00361     return tmp;
00362 }
00363 
00364 void
00365 sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const
00366 {
00367     SC_ASSERT_( observer_ != 0, "unlock observer failed" );
00368     m_observer = observer_;
00369 }
00370 
00371 
00372 // ----------------------------------------------------------------------------
00373 //  CLASS : sc_fxnum_fast
00374 //
00375 //  Base class for the fixed-point types; limited precision.
00376 // ----------------------------------------------------------------------------
00377 
00378 static
00379 void
00380 quantization( double& c, const scfx_params& params, bool& q_flag )
00381 {
00382     int fwl = params.wl() - params.iwl();
00383     double scale = scfx_pow2( fwl );
00384     double val = scale * c;
00385     double int_part;
00386     double frac_part = modf( val, &int_part );
00387 
00388     q_flag = ( frac_part != 0.0 );
00389 
00390     if( q_flag )
00391     {
00392         val = int_part;
00393 
00394     switch( params.q_mode() )
00395     {
00396             case SC_TRN:            // truncation
00397         {
00398             if( c < 0.0 )
00399             val -= 1.0;
00400         break;
00401         }
00402             case SC_RND:            // rounding to plus infinity
00403         {
00404         if( frac_part >= 0.5 )
00405             val += 1.0;
00406         else if( frac_part < -0.5 )
00407             val -= 1.0;
00408         break;
00409         }
00410             case SC_TRN_ZERO:           // truncation to zero
00411         {
00412             break;
00413         }
00414             case SC_RND_INF:            // rounding to infinity
00415         {
00416         if( frac_part >= 0.5 )
00417             val += 1.0;
00418         else if( frac_part <= -0.5 )
00419             val -= 1.0;
00420         break;
00421         }
00422             case SC_RND_CONV:           // convergent rounding
00423         {
00424         if( frac_part > 0.5 ||
00425             frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 )
00426             val += 1.0;
00427         else if( frac_part < -0.5 ||
00428              frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 )
00429             val -= 1.0;
00430         break;
00431         }
00432             case SC_RND_ZERO:           // rounding to zero
00433         {
00434         if( frac_part > 0.5 )
00435             val += 1.0;
00436         else if( frac_part < -0.5 )
00437             val -= 1.0;
00438         break;
00439         }
00440             case SC_RND_MIN_INF:        // rounding to minus infinity
00441         {
00442         if( frac_part > 0.5 )
00443             val += 1.0;
00444         else if( frac_part <= -0.5 )
00445             val -= 1.0;
00446         break;
00447         }
00448             default:
00449             ;
00450     }
00451     }
00452 
00453     val /= scale;
00454     c = val;
00455 }
00456 
00457 static
00458 void
00459 overflow( double& c, const scfx_params& params, bool& o_flag )
00460 {
00461     int iwl = params.iwl();
00462     int fwl = params.wl() - iwl;
00463     double full_circle = scfx_pow2( iwl );
00464     double resolution = scfx_pow2( -fwl );
00465     double low, high;
00466     if( params.enc() == SC_TC_ )
00467     {
00468     high = full_circle / 2.0 - resolution;
00469     if( params.o_mode() == SC_SAT_SYM )
00470         low = - high;
00471     else
00472         low = - full_circle / 2.0;
00473     }
00474     else
00475     {
00476     low = 0.0;
00477     high = full_circle - resolution;
00478     }
00479     double val = c;
00480     sc_fxval_fast c2 = c;
00481 
00482     bool under = ( val < low );
00483     bool over = ( val > high );
00484 
00485     o_flag = ( under || over );
00486 
00487     if( o_flag )
00488     {
00489         switch( params.o_mode() )
00490     {
00491             case SC_WRAP:           // wrap-around
00492         {
00493         int n_bits = params.n_bits();
00494 
00495             if( n_bits == 0 )
00496         {
00497             // wrap-around all 'wl' bits
00498             val -= floor( val / full_circle ) * full_circle;
00499             if( val > high )
00500             val -= full_circle;
00501         }
00502         else if( n_bits < params.wl() )
00503         {
00504             double X = scfx_pow2( iwl - n_bits );
00505 
00506             // wrap-around least significant 'wl - n_bits' bits
00507             val -= floor( val / X ) * X;
00508             if( val > ( X - resolution ) )
00509             val -= X;
00510             
00511             // saturate most significant 'n_bits' bits
00512             if( under )
00513                 val += low;
00514             else
00515             {
00516                 if( params.enc() == SC_TC_ )
00517                 val += full_circle / 2.0 - X;
00518             else
00519                 val += full_circle - X;
00520             }
00521         }
00522         else
00523         {
00524             // saturate all 'wl' bits
00525             if( under )
00526             val = low;
00527             else
00528             val = high;
00529         }
00530         break;
00531         }
00532             case SC_SAT:            // saturation
00533             case SC_SAT_SYM:            // symmetrical saturation
00534         {
00535             if( under )
00536             val = low;
00537         else
00538             val = high;
00539         break;
00540         }
00541             case SC_SAT_ZERO:           // saturation to zero
00542         {
00543             val = 0.0;
00544         break;
00545         }
00546             case SC_WRAP_SM:            // sign magnitude wrap-around
00547         {
00548         SC_ERROR_IF_( params.enc() == SC_US_,
00549                   sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ );
00550     
00551         int n_bits = params.n_bits();
00552 
00553         if( n_bits == 0 )
00554         {
00555             // invert conditionally
00556             if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) )
00557             val = -val - resolution;
00558 
00559             // wrap-around all 'wl' bits
00560             val -= floor( val / full_circle ) * full_circle;
00561             if( val > high )
00562             val -= full_circle;
00563         }
00564         else if( n_bits == 1 )
00565         {
00566             // invert conditionally
00567             if( c2.is_neg() != c2.get_bit( iwl - 1 ) )
00568             val = -val - resolution;
00569 
00570             // wrap-around all 'wl' bits
00571             val -= floor( val / full_circle ) * full_circle;
00572             if( val > high )
00573             val -= full_circle;
00574         }
00575         else if( n_bits < params.wl() )
00576         {
00577             // invert conditionally
00578             if( c2.is_neg() == c2.get_bit( iwl - n_bits ) )
00579             val = -val - resolution;
00580             
00581             double X = scfx_pow2( iwl - n_bits );
00582 
00583             // wrap-around least significant 'wl - n_bits' bits
00584             val -= floor( val / X ) * X;
00585             if( val > ( X - resolution ) )
00586             val -= X;
00587 
00588             // saturate most significant 'n_bits' bits
00589             if( under )
00590                 val += low;
00591             else
00592             val += full_circle / 2.0 - X;
00593         } else {
00594             // saturate all 'wl' bits
00595             if( under )
00596             val = low;
00597             else
00598             val = high;
00599         }
00600             break;
00601         }
00602             default:
00603             ;
00604     }
00605 
00606     c = val;
00607     }
00608 }
00609 
00610 
00611 void
00612 sc_fxnum_fast::cast()
00613 {
00614     scfx_ieee_double id( m_val );
00615     SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_);
00616 
00617     if( m_params.cast_switch() == SC_ON )
00618     {
00619         m_q_flag = false;
00620     m_o_flag = false;
00621 
00622     // check for special cases
00623 
00624     if( id.is_zero() )
00625     {
00626         if( id.negative() != 0 )
00627             m_val = -m_val;
00628         return;
00629     }
00630 
00631     // perform casting
00632 
00633     sc_dt::quantization( m_val, m_params, m_q_flag );
00634     sc_dt::overflow( m_val, m_params, m_o_flag );
00635 
00636     // check for special case: -0
00637 
00638     id = m_val;
00639     if( id.is_zero() && id.negative() != 0 ) {
00640         m_val = -m_val;
00641     }
00642 
00643     // check for special case: NaN of Inf
00644 
00645     if( id.is_nan() || id.is_inf() ) {
00646         m_val = 0.0;
00647     }
00648     }
00649 }
00650 
00651 
00652 // defined in sc_fxval.cpp;
00653 extern
00654 const char*
00655 to_string( const scfx_ieee_double&,
00656        sc_numrep,
00657        int,
00658        sc_fmt,
00659        const scfx_params* = 0 );
00660 
00661 
00662 // explicit conversion to character string
00663 
00664 const std::string
00665 sc_fxnum_fast::to_string() const
00666 {
00667     return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
00668 }
00669 
00670 const std::string
00671 sc_fxnum_fast::to_string( sc_numrep numrep ) const
00672 {
00673     return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) );
00674 }
00675 
00676 const std::string
00677 sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const
00678 {
00679     return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
00680                     SC_F, &m_params ) );
00681 }
00682 
00683 const std::string
00684 sc_fxnum_fast::to_string( sc_fmt fmt ) const
00685 {
00686     return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) );
00687 }
00688 
00689 const std::string
00690 sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const
00691 {
00692     return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) );
00693 }
00694 
00695 const std::string
00696 sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const
00697 {
00698     return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0),
00699                     fmt, &m_params ) );
00700 }
00701 
00702 
00703 const std::string
00704 sc_fxnum_fast::to_dec() const
00705 {
00706     return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) );
00707 }
00708 
00709 const std::string
00710 sc_fxnum_fast::to_bin() const
00711 {
00712     return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) );
00713 }
00714 
00715 const std::string
00716 sc_fxnum_fast::to_oct() const
00717 {
00718     return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) );
00719 }
00720 
00721 const std::string
00722 sc_fxnum_fast::to_hex() const
00723 {
00724     return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) );
00725 }
00726 
00727 
00728 // print or dump content
00729 
00730 void
00731 sc_fxnum_fast::print( ::std::ostream& os ) const
00732 {
00733     os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params );
00734 }
00735 
00736 void
00737 sc_fxnum_fast::scan( ::std::istream& is )
00738 {
00739     std::string s;
00740     is >> s;
00741     *this = s.c_str();
00742 }
00743 
00744 void
00745 sc_fxnum_fast::dump( ::std::ostream& os ) const
00746 {
00747     os << "sc_fxnum_fast" << ::std::endl;
00748     os << "(" << ::std::endl;
00749     os << "val      = " << m_val << ::std::endl;
00750     os << "params   = ";
00751     m_params.dump( os );
00752     os << "q_flag   = " << m_q_flag << ::std::endl;
00753     os << "o_flag   = " << m_o_flag << ::std::endl;
00754     // TO BE COMPLETED
00755     // os << "observer = ";
00756     // if( m_observer != 0 )
00757     //     m_observer->dump( os );
00758     // else
00759     //     os << "0" << ::std::endl;
00760     os << ")" << ::std::endl;
00761 }
00762 
00763 
00764 // internal use only;
00765 bool
00766 sc_fxnum_fast::get_bit( int i ) const
00767 {
00768     scfx_ieee_double id( m_val );
00769     if( id.is_zero() || id.is_nan() || id.is_inf() )
00770         return false;
00771 
00772     // convert to two's complement
00773 
00774     unsigned int m0 = id.mantissa0();
00775     unsigned int m1 = id.mantissa1();
00776 
00777     if( id.is_normal() )
00778         m0 += 1U << 20;
00779 
00780     if( id.negative() != 0 )
00781     {
00782     m0 = ~ m0;
00783     m1 = ~ m1;
00784     unsigned int tmp = m1;
00785     m1 += 1U;
00786     if( m1 <= tmp )
00787         m0 += 1U;
00788     }
00789 
00790     // get the right bit
00791 
00792     int j = i - id.exponent();
00793     if( ( j += 20 ) >= 32 )
00794         return ( ( m0 & 1U << 31 ) != 0 );
00795     else if( j >= 0 )
00796         return ( ( m0 & 1U << j ) != 0 );
00797     else if( ( j += 32 ) >= 0 )
00798         return ( ( m1 & 1U << j ) != 0 );
00799     else
00800         return false;
00801 }
00802 
00803 
00804 bool
00805 sc_fxnum_fast::set_bit( int i, bool high )
00806 {
00807     scfx_ieee_double id( m_val );
00808     if( id.is_nan() || id.is_inf() )
00809         return false;
00810 
00811     if( high )
00812     {
00813     if( get_bit( i ) )
00814         return true;
00815 
00816     if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
00817         m_val -= scfx_pow2( i );
00818     else
00819         m_val += scfx_pow2( i );
00820     }
00821     else
00822     {
00823     if( ! get_bit( i ) )
00824         return true;
00825 
00826     if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 )
00827         m_val += scfx_pow2( i );
00828     else
00829         m_val -= scfx_pow2( i );
00830     }
00831 
00832     return true;
00833 }
00834 
00835 
00836 bool
00837 sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const
00838 {
00839     scfx_ieee_double id( m_val );
00840     if( id.is_nan() || id.is_inf() )
00841     return false;
00842 
00843     // convert to two's complement
00844 
00845     unsigned int m0 = id.mantissa0();
00846     unsigned int m1 = id.mantissa1();
00847 
00848     if( id.is_normal() )
00849         m0 += 1U << 20;
00850 
00851     if( id.negative() != 0 )
00852     {
00853     m0 = ~ m0;
00854     m1 = ~ m1;
00855     unsigned int tmp = m1;
00856     m1 += 1U;
00857     if( m1 <= tmp )
00858         m0 += 1U;
00859     }
00860 
00861     // get the bits
00862 
00863     int l = j;
00864     for( int k = 0; k < bv.length(); ++ k )
00865     {
00866     bool b = false;
00867 
00868         int n = l - id.exponent();
00869         if( ( n += 20 ) >= 32 )
00870         b = ( ( m0 & 1U << 31 ) != 0 );
00871     else if( n >= 0 )
00872         b = ( ( m0 & 1U << n ) != 0 );
00873     else if( ( n += 32 ) >= 0 )
00874         b = ( ( m1 & 1U << n ) != 0 );
00875 
00876     bv[k] = b;
00877 
00878     if( i >= j )
00879         ++ l;
00880     else
00881         -- l;
00882     }
00883 
00884     return true;
00885 }
00886 
00887 bool
00888 sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv )
00889 {
00890     scfx_ieee_double id( m_val );
00891     if( id.is_nan() || id.is_inf() )
00892         return false;
00893 
00894     // set the bits
00895 
00896     int l = j;
00897     for( int k = 0; k < bv.length(); ++ k )
00898     {
00899     if( bv[k].to_bool() )
00900     {
00901         if( ! get_bit( l ) )
00902         {
00903         if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
00904             m_val -= scfx_pow2( l );
00905         else
00906             m_val += scfx_pow2( l );
00907         }
00908     }
00909     else
00910     {
00911         if( get_bit( l ) )
00912         {
00913         if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 )
00914             m_val += scfx_pow2( l );
00915         else
00916             m_val -= scfx_pow2( l );
00917         }
00918     }
00919 
00920 
00921     if( i >= j )
00922         ++ l;
00923     else
00924         -- l;
00925     }
00926 
00927     return true;
00928 }
00929 
00930 
00931 sc_fxnum_fast_observer*
00932 sc_fxnum_fast::lock_observer() const
00933 {
00934     SC_ASSERT_( m_observer != 0, "lock observer failed" );
00935     sc_fxnum_fast_observer* tmp = m_observer;
00936     m_observer = 0;
00937     return tmp;
00938 }
00939 
00940 void
00941 sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const
00942 {
00943     SC_ASSERT_( observer_ != 0, "unlock observer failed" );
00944     m_observer = observer_;
00945 }
00946 
00947 } // namespace sc_dt
00948 
00949 
00950 // Taf!

Generated on Wed Jan 21 15:32:07 2009 for SystemC by  doxygen 1.5.5