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

sc_int_base.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_int_base.cpp -- contains interface definitions between sc_int and
00021                 sc_signed, sc_unsigned, and definitions for sc_int_subref.
00022 
00023   Original Author: Ali Dasdan, 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 
00038 #include "systemc/kernel/sc_macros.h"
00039 #include "systemc/datatypes/int/sc_signed.h"
00040 #include "systemc/datatypes/int/sc_unsigned.h"
00041 #include "systemc/datatypes/int/sc_int_base.h"
00042 #include "systemc/datatypes/int/sc_int_ids.h"
00043 #include "systemc/datatypes/bit/sc_bv_base.h"
00044 #include "systemc/datatypes/bit/sc_lv_base.h"
00045 #include "systemc/datatypes/misc/sc_concatref.h"
00046 #include "systemc/datatypes/fx/sc_fix.h"
00047 #include "systemc/datatypes/fx/scfx_other_defs.h"
00048 #include "systemc/utils/sc_exception.h"
00049 
00050 
00051 namespace sc_dt
00052 {
00053 
00054 // to avoid code bloat in sc_int_concref<T1,T2>
00055 
00056 void
00057 sc_int_concref_invalid_length( int length )
00058 {
00059     char msg[BUFSIZ];
00060     sprintf( msg,
00061        "sc_int_concref<T1,T2> initialization: length = %d "
00062        "violates 1 <= length <= %d",
00063        length, SC_INTWIDTH );
00064     SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00065 }
00066 
00067 
00068 // ----------------------------------------------------------------------------
00069 //  CLASS : sc_int_bitref
00070 //
00071 //  Proxy class for sc_int bit selection (r-value and l-value).
00072 // ----------------------------------------------------------------------------
00073 
00074 // concatenation methods:
00075 
00076 // #### OPTIMIZE
00077 void sc_int_bitref::concat_set(int64 src, int low_i)
00078 {
00079     sc_int_base aa( 1 );
00080     *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
00081 }
00082 
00083 void sc_int_bitref::concat_set(const sc_signed& src, int low_i)
00084 {
00085     sc_int_base aa( 1 );
00086     if ( low_i < src.length() )
00087   *this = aa = 1 & (src >> low_i);
00088     else
00089   *this = aa = (src < 0) ? (int_type)-1 : 0;
00090 }
00091 
00092 void sc_int_bitref::concat_set(const sc_unsigned& src, int low_i)
00093 {
00094     sc_int_base aa( 1 );
00095     if ( low_i < src.length() )
00096   *this = aa = 1 & (src >> low_i);
00097     else
00098   *this = aa = 0;
00099 }
00100 
00101 void sc_int_bitref::concat_set(uint64 src, int low_i)
00102 {
00103     sc_int_base aa( 1 );
00104     *this = aa = (low_i < 64) ? src >> low_i : 0;
00105 }
00106 
00107 
00108 // other methods
00109 
00110 void
00111 sc_int_bitref::scan( istream& is )
00112 {
00113     bool b;
00114     is >> b;
00115     *this = b;
00116 }
00117 
00118 
00119 // ----------------------------------------------------------------------------
00120 //  CLASS : sc_int_subref_r
00121 //
00122 //  Proxy class for sc_int part selection (l-value).
00123 // ----------------------------------------------------------------------------
00124 
00125 bool sc_int_subref_r::concat_get_ctrl( unsigned long* dst_p, int low_i ) const
00126 {    
00127     int       dst_i;       // Word in dst_p now processing.
00128     int       end_i;       // Highest order word in dst_p to process.
00129     int       high_i;      // Index of high order bit in dst_p to set.
00130     uint_type mask;        // Mask for bits to extract or keep.
00131 
00132     dst_i = low_i / BITS_PER_DIGIT;
00133     high_i = low_i + (m_left-m_right);
00134     end_i = high_i / BITS_PER_DIGIT;
00135     mask = ~mask_int[m_left][m_right];
00136 
00137 
00138     // PROCESS THE FIRST WORD:
00139 
00140     dst_p[dst_i] = (unsigned long)(dst_p[dst_i] & mask);
00141     switch ( end_i - dst_i )
00142     {
00143      // BITS ARE ACROSS TWO WORDS:
00144 
00145      case 1:
00146         dst_i++;
00147         dst_p[dst_i] = 0;
00148         break;
00149 
00150      // BITS ARE ACROSS THREE WORDS:
00151 
00152      case 2:
00153         dst_i++;
00154         dst_p[dst_i++] = 0;
00155         dst_p[dst_i] = 0;
00156         break;
00157 
00158      // BITS ARE ACROSS FOUR WORDS:
00159 
00160      case 3:
00161         dst_i++;
00162         dst_p[dst_i++] = 0;
00163         dst_p[dst_i++] = 0;
00164         dst_p[dst_i] = 0;
00165         break;
00166     }
00167     return false;
00168 }
00169 
00170 
00171 bool sc_int_subref_r::concat_get_data( unsigned long* dst_p, int low_i ) const
00172 {    
00173     int       dst_i;       // Word in dst_p now processing.
00174     int       end_i;       // Highest order word in dst_p to process.
00175     int       high_i;      // Index of high order bit in dst_p to set.
00176     int       left_shift;  // Left shift for val.
00177     uint_type mask;        // Mask for bits to extract or keep.
00178     bool      non_zero;    // True if value inserted is non-zero.
00179     uint_type val;         // Selection value extracted from m_obj_p.
00180 
00181     dst_i = low_i / BITS_PER_DIGIT;
00182     left_shift = low_i % BITS_PER_DIGIT;
00183     high_i = low_i + (m_left-m_right);
00184     end_i = high_i / BITS_PER_DIGIT;
00185     mask = ~mask_int[m_left][m_right];
00186     val = (m_obj_p->m_val & mask) >> m_right;
00187     non_zero = val != 0;
00188 
00189 
00190     // PROCESS THE FIRST WORD:
00191 
00192     mask = ~(-1 << left_shift);
00193     dst_p[dst_i] = (unsigned long)((dst_p[dst_i] & mask) | 
00194     ((val << left_shift) & DIGIT_MASK));
00195     switch ( end_i - dst_i )
00196     {
00197      // BITS ARE ACROSS TWO WORDS:
00198 
00199      case 1:
00200         dst_i++;
00201         val >>= (BITS_PER_DIGIT-left_shift);
00202         dst_p[dst_i] = (unsigned long)(val & DIGIT_MASK);
00203         break;
00204 
00205      // BITS ARE ACROSS THREE WORDS:
00206 
00207      case 2:
00208         dst_i++;
00209         val >>= (BITS_PER_DIGIT-left_shift);
00210         dst_p[dst_i++] = (unsigned long)(val & DIGIT_MASK);
00211         val >>= BITS_PER_DIGIT;
00212         dst_p[dst_i] = (unsigned long)val;
00213         break;
00214 
00215      // BITS ARE ACROSS FOUR WORDS:
00216 
00217      case 3:
00218         dst_i++;
00219         val >>= (BITS_PER_DIGIT-left_shift);
00220         dst_p[dst_i++] = (unsigned long)(val & DIGIT_MASK);
00221         val >>= BITS_PER_DIGIT;
00222         dst_p[dst_i++] = (unsigned long)val;
00223         val >>= BITS_PER_DIGIT;
00224         dst_p[dst_i] = (unsigned long)val;
00225         break;
00226     }
00227     return non_zero;
00228 }
00229 
00230 // ----------------------------------------------------------------------------
00231 //  CLASS : sc_int_subref
00232 //
00233 //  Proxy class for sc_int part selection (r-value and l-value).
00234 // ----------------------------------------------------------------------------
00235 
00236 // assignment operators
00237   
00238 sc_int_subref& 
00239 sc_int_subref::operator = ( int_type v )
00240 {
00241     int_type val = m_obj_p->m_val;
00242     uint_type mask = mask_int[m_left][m_right];
00243     val &= mask;
00244     val |= (v << m_right) & ~mask;
00245     m_obj_p->m_val = val;
00246     m_obj_p->extend_sign();
00247     return *this;
00248 }
00249 
00250 sc_int_subref&
00251 sc_int_subref::operator = ( const sc_signed& a )
00252 {
00253     sc_int_base aa( length() );
00254     return ( *this = aa = a );
00255 }
00256 
00257 sc_int_subref&
00258 sc_int_subref::operator = ( const sc_unsigned& a )
00259 {
00260     sc_int_base aa( length() );
00261     return ( *this = aa = a );
00262 }
00263 
00264 sc_int_subref&
00265 sc_int_subref::operator = ( const sc_concatref& a )
00266 {
00267     int_type v = a.to_uint64();
00268     int_type val = m_obj_p->m_val;
00269     uint_type mask = mask_int[m_left][m_right];
00270     val &= mask;
00271     val |= (v << m_right) & ~mask;
00272     m_obj_p->m_val = val;
00273     m_obj_p->extend_sign();
00274     return *this;
00275 }
00276 
00277 sc_int_subref&
00278 sc_int_subref::operator = ( const sc_bv_base& a )
00279 {
00280     sc_int_base aa( length() );
00281     return ( *this = aa = a );
00282 }
00283 
00284 sc_int_subref&
00285 sc_int_subref::operator = ( const sc_lv_base& a )
00286 {
00287     sc_int_base aa( length() );
00288     return ( *this = aa = a );
00289 }
00290 
00291 
00292 // concatenation methods:
00293 
00294 // #### OPTIMIZE
00295 void sc_int_subref::concat_set(int64 src, int low_i)
00296 {
00297     sc_int_base aa ( length() );
00298     *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
00299 }
00300 
00301 void sc_int_subref::concat_set(const sc_signed& src, int low_i)
00302 {
00303     sc_int_base aa( length() );
00304     if ( low_i < src.length() )
00305   *this = aa = src >> low_i;
00306     else
00307   *this = (src < 0) ? (int_type)-1 : 0;
00308 }
00309 
00310 void sc_int_subref::concat_set(const sc_unsigned& src, int low_i)
00311 {
00312     sc_int_base aa( length() );
00313     if ( low_i < src.length() )
00314   *this = aa = src >> low_i;
00315     else
00316   *this = 0;
00317 }
00318 
00319 void sc_int_subref::concat_set(uint64 src, int low_i)
00320 {
00321     sc_int_base aa ( length() );
00322     *this = aa = (low_i < 64) ? src >> low_i : 0;
00323 }
00324 
00325 
00326 // other methods
00327 
00328 void
00329 sc_int_subref::scan( istream& is )
00330 {
00331     sc_string s;
00332     is >> s;
00333     *this = s.c_str();
00334 }
00335 
00336 
00337 // ----------------------------------------------------------------------------
00338 //  CLASS : sc_int_base
00339 //
00340 //  Base class for sc_int.
00341 // ----------------------------------------------------------------------------
00342 
00343 // support methods
00344 
00345 void
00346 sc_int_base::invalid_length() const
00347 {
00348     char msg[BUFSIZ];
00349     sprintf( msg,
00350        "sc_int[_base] initialization: length = %d violates "
00351        "1 <= length <= %d",
00352        m_len, SC_INTWIDTH );
00353     SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00354 }
00355 
00356 void
00357 sc_int_base::invalid_index( int i ) const
00358 {
00359     char msg[BUFSIZ];
00360     sprintf( msg,
00361        "sc_int[_base] bit selection: index = %d violates "
00362        "0 <= index <= %d",
00363        i, m_len - 1 );
00364     SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00365 }
00366 
00367 void
00368 sc_int_base::invalid_range( int l, int r ) const
00369 {
00370     char msg[BUFSIZ];
00371     sprintf( msg,
00372        "sc_int[_base] part selection: left = %d, right = %d violates "
00373        "0 <= right <= left <= %d",
00374        l, r, m_len - 1 );
00375     SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00376 }
00377 
00378 
00379 void
00380 sc_int_base::check_value() const
00381 {
00382     int_type limit = (int_type) 1 << ( m_len - 1 );
00383     if( m_val < -limit || m_val >= limit ) {
00384   char msg[BUFSIZ];
00385   sprintf( msg, "sc_int[_base]: value does not fit into a length of %d",
00386      m_len );
00387   SC_REPORT_WARNING( SC_ID_OUT_OF_BOUNDS_, msg );
00388     }
00389 }
00390 
00391 
00392 // constructors
00393 
00394 sc_int_base::sc_int_base( const sc_signed& a )
00395     : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
00396 {
00397     check_length();
00398     for( int i = m_len - 1; i >= 0; -- i ) {
00399   set( i, a.test( i ) );
00400     }
00401     extend_sign();
00402 }
00403 
00404 sc_int_base::sc_int_base( const sc_unsigned& a )
00405     : m_val( 0 ), m_len( a.length() ), m_ulen( SC_INTWIDTH - m_len )
00406 {
00407     check_length();
00408     for( int i = m_len - 1; i >= 0; -- i ) {
00409   set( i, a.test( i ) );
00410     }
00411     extend_sign();
00412 }
00413 
00414 
00415 // assignment operators
00416 
00417 sc_int_base& 
00418 sc_int_base::operator = ( const sc_signed& a )
00419 {
00420     int minlen = sc_min( m_len, a.length() );
00421     int i = 0;
00422     for( ; i < minlen; ++ i ) {
00423   set( i, a.test( i ) );
00424     }
00425     bool sgn = a.sign();
00426     for( ; i < m_len; ++ i ) {
00427   // sign extension
00428   set( i, sgn );
00429     }
00430     extend_sign();
00431     return *this;
00432 }
00433 
00434 sc_int_base& 
00435 sc_int_base::operator = ( const sc_unsigned& a )
00436 {
00437     int minlen = sc_min( m_len, a.length() );
00438     int i = 0;
00439     for( ; i < minlen; ++ i ) {
00440   set( i, a.test( i ) );
00441     }
00442     for( ; i < m_len; ++ i ) {
00443   // zero extension
00444   set( i, 0 );
00445     }
00446     extend_sign();
00447     return *this;
00448 }
00449 
00450 
00451 sc_int_base&
00452 sc_int_base::operator = ( const sc_bv_base& a )
00453 {
00454     int minlen = sc_min( m_len, a.length() );
00455     int i = 0;
00456     for( ; i < minlen; ++ i ) {
00457   set( i, a.get_bit( i ) );
00458     }
00459     for( ; i < m_len; ++ i ) {
00460   // zero extension
00461   set( i, 0 );
00462     }
00463     extend_sign();
00464     return *this;
00465 }
00466 
00467 sc_int_base&
00468 sc_int_base::operator = ( const sc_lv_base& a )
00469 {
00470     int minlen = sc_min( m_len, a.length() );
00471     int i = 0;
00472     for( ; i < minlen; ++ i ) {
00473   set( i, sc_logic( a.get_bit( i ) ).to_bool() );
00474     }
00475     for( ; i < m_len; ++ i ) {
00476   // zero extension
00477   set( i, 0 );
00478     }
00479     extend_sign();
00480     return *this;
00481 }
00482 
00483 sc_int_base&
00484 sc_int_base::operator = ( const char* a )
00485 {
00486     if( a == 0 ) {
00487   SC_REPORT_ERROR( SC_ID_CONVERSION_FAILED_,
00488        "character string is zero" );
00489     }
00490     if( *a == 0 ) {
00491   SC_REPORT_ERROR( SC_ID_CONVERSION_FAILED_,
00492        "character string is empty" );
00493     }
00494     try {
00495   int len = m_len;
00496   sc_fix aa( a, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
00497   return this->operator = ( aa );
00498     } catch( sc_exception ) {
00499   char msg[BUFSIZ];
00500   sprintf( msg, "character string '%s' is not valid", a );
00501   SC_REPORT_ERROR( SC_ID_CONVERSION_FAILED_, msg );
00502   // never reached
00503   return *this;
00504     }
00505 }
00506 
00507 sc_int_base&  
00508 sc_int_base::operator = ( const sc_concatref& a )  
00509 {
00510     m_val = a.to_int64();
00511     extend_sign();
00512     return *this;
00513 }
00514 
00515 
00516 
00517 // explicit conversion to character string
00518 
00519 const sc_string
00520 sc_int_base::to_string( sc_numrep numrep ) const
00521 {
00522     int len = m_len;
00523     sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
00524     return aa.to_string( numrep );
00525 }
00526 
00527 const sc_string
00528 sc_int_base::to_string( sc_numrep numrep, bool w_prefix ) const
00529 {
00530     int len = m_len;
00531     sc_fix aa( *this, len, len, SC_TRN, SC_WRAP, 0, SC_ON );
00532     return aa.to_string( numrep, w_prefix );
00533 }
00534 
00535 
00536 // reduce methods
00537 
00538 bool
00539 sc_int_base::and_reduce() const
00540 {
00541     return ( m_val == int_type( -1 ) );
00542 }
00543 
00544 bool
00545 sc_int_base::or_reduce() const
00546 {
00547     return ( m_val != int_type( 0 ) );
00548 }
00549 
00550 bool
00551 sc_int_base::xor_reduce() const
00552 {
00553     uint_type mask = ~UINT_ZERO;
00554     uint_type val = m_val & (mask >> m_ulen);
00555     int n = SC_INTWIDTH;
00556     do {
00557   n >>= 1;
00558   mask >>= n;
00559   val = ((val & (mask << n)) >> n) ^ (val & mask);
00560     } while( n != 1 );
00561     return ( val != uint_type( 0 ) );
00562 }
00563 
00564 
00565 bool sc_int_base::concat_get_ctrl( unsigned long* dst_p, int low_i ) const
00566 {    
00567     int       dst_i;       // Word in dst_p now processing.
00568     int       end_i;       // Highest order word in dst_p to process.
00569     int       left_shift;  // Left shift for val.
00570     uint_type mask;        // Mask for bits to extract or keep.
00571 
00572     dst_i = low_i / BITS_PER_DIGIT;
00573     left_shift = low_i % BITS_PER_DIGIT;
00574     end_i = (low_i + (m_len-1)) / BITS_PER_DIGIT;
00575 
00576     mask = ~(-1 << left_shift);
00577     dst_p[dst_i] = (unsigned long)(dst_p[dst_i] & mask);
00578   dst_i++;
00579   for ( ; dst_i <= end_i; dst_i++ ) dst_p[dst_i] = 0;
00580   return false;
00581 }
00582 
00583 bool sc_int_base::concat_get_data( unsigned long* dst_p, int low_i ) const
00584 {    
00585     int       dst_i;       // Word in dst_p now processing.
00586     int       end_i;       // Highest order word in dst_p to process.
00587     int       high_i;      // Index of high order bit in dst_p to set.
00588     int       left_shift;  // Left shift for val.
00589     uint_type mask;        // Mask for bits to extract or keep.
00590     bool      non_zero;    // True if value inserted is non-zero.
00591     uint_type val;         // Value for this object.
00592 
00593     dst_i = low_i / BITS_PER_DIGIT;
00594     left_shift = low_i % BITS_PER_DIGIT;
00595     high_i = low_i + (m_len-1);
00596     end_i = high_i / BITS_PER_DIGIT;
00597     val = m_val;
00598     non_zero = val != 0;
00599     if ( m_len < 64 )
00600     {
00601   mask = ~((uint_type)-1 << m_len);
00602         val &=  mask;
00603     }
00604     // PROCESS THE FIRST WORD:
00605 
00606     mask = ~(-1 << left_shift);
00607     dst_p[dst_i] = (unsigned long)((dst_p[dst_i] & mask) | 
00608     ((val <<left_shift) & DIGIT_MASK));
00609     switch ( end_i - dst_i )
00610     {
00611      // BITS ARE ACROSS TWO WORDS:
00612 
00613      case 1:
00614         dst_i++;
00615         val >>= (BITS_PER_DIGIT-left_shift);
00616         dst_p[dst_i] = (unsigned long)val;
00617         break;
00618 
00619      // BITS ARE ACROSS THREE WORDS:
00620 
00621      case 2:
00622         dst_i++;
00623         val >>= (BITS_PER_DIGIT-left_shift);
00624         dst_p[dst_i++] = ((unsigned long)val) & DIGIT_MASK;
00625         val >>= BITS_PER_DIGIT;
00626         dst_p[dst_i] = (unsigned long)val;
00627         break;
00628 
00629      // BITS ARE ACROSS THREE WORDS:
00630 
00631      case 3:
00632         dst_i++;
00633         val >>= (BITS_PER_DIGIT-left_shift);
00634         dst_p[dst_i++] = (unsigned long)(val & DIGIT_MASK);
00635         val >>= BITS_PER_DIGIT;
00636         dst_p[dst_i++] = (unsigned long)(val & DIGIT_MASK);
00637         val >>= BITS_PER_DIGIT;
00638         dst_p[dst_i] = (unsigned long)val;
00639         break;
00640     }
00641     return non_zero;
00642 }
00643 
00644 // #### OPTIMIZE
00645 void sc_int_base::concat_set(int64 src, int low_i)
00646 {
00647     *this = (low_i < 64) ? src >> low_i : src >> 63;
00648 }
00649 
00650 void sc_int_base::concat_set(const sc_signed& src, int low_i)
00651 {
00652     if ( low_i < src.length() )
00653   *this = src >> low_i;
00654     else
00655         *this = (src < 0) ? (int_type)-1 : 0;
00656 }
00657 
00658 void sc_int_base::concat_set(const sc_unsigned& src, int low_i)
00659 {
00660     if ( low_i < src.length() )
00661   *this = src >> low_i;
00662     else
00663         *this = 0;
00664 }
00665 
00666 void sc_int_base::concat_set(uint64 src, int low_i)
00667 {
00668     *this = (low_i < 64) ? src >> low_i : 0;
00669 }
00670 
00671 // other methods
00672 
00673 void
00674 sc_int_base::scan( istream& is )
00675 {
00676     sc_string s;
00677     is >> s;
00678     *this = s.c_str();
00679 }
00680 
00681 } // namespace sc_dt;
00682 
00683 
00684 // Taf!

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