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

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