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

sc_bv_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_bv_base.cpp -- Arbitrary size bit vector class.
00021 
00022   Original Author: Gene Bushuyev, 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 "systemc/datatypes/bit/sc_bit_ids.h"
00038 #include "systemc/datatypes/bit/sc_bv_base.h"
00039 #include "systemc/datatypes/fx/sc_fix.h"
00040 #include "systemc/datatypes/fx/sc_ufix.h"
00041 #include "systemc/utils/sc_exception.h"
00042 
00043 
00044 namespace sc_dt
00045 {
00046 
00047 // ----------------------------------------------------------------------------
00048 //  CLASS : sc_bv_base
00049 //
00050 //  Arbitrary size bit vector base class.
00051 // ----------------------------------------------------------------------------
00052 
00053 void
00054 sc_bv_base::init( int length_, bool init_value )
00055 {
00056     // check the length
00057     if( length_ <= 0 ) {
00058   SC_REPORT_ERROR( SC_ID_ZERO_LENGTH_, 0 );
00059     }
00060     // allocate memory for the data and control words
00061     m_len = length_;
00062     m_size = (m_len - 1) / UL_SIZE + 1;
00063     m_data = new unsigned long[m_size];
00064     // initialize the bits to 'init_value'
00065     unsigned long dw = init_value ? ~UL_ZERO : UL_ZERO;
00066     int sz = m_size;
00067     for( int i = 0; i < sz; ++ i ) {
00068   m_data[i] = dw;
00069     }
00070     clean_tail();
00071 }
00072 
00073 
00074 void
00075 sc_bv_base::assign_from_string( const sc_string& s )
00076 {
00077     // s must have been converted to bin
00078     int len = m_len;
00079     int s_len = s.length() - 1;
00080     int min_len = sc_min( len, s_len );
00081     int i = 0;
00082     for( ; i < min_len; ++ i ) {
00083   char c = s[s_len - i - 1];
00084   if( c != '0' && c != '1' ) {
00085       SC_REPORT_ERROR( SC_ID_CANNOT_CONVERT_,
00086           "string can contain only '0' and '1' characters" );
00087   }
00088   set_bit( i, sc_logic_value_t( c - '0' ) );
00089     }
00090     // if formatted, fill the rest with sign(s), otherwise fill with zeros
00091     sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
00092                                  : sc_logic_value_t( 0 ));
00093     for( ; i < len; ++ i ) {
00094   set_bit( i, fill );
00095     }
00096 }
00097 
00098 
00099 // constructors
00100 
00101 sc_bv_base::sc_bv_base( const char* a )
00102     : m_len( 0 ), m_size( 0 ), m_data( 0 )
00103 {
00104     sc_string s = convert_to_bin( a );
00105     init( s.length() -  1 );
00106     assign_from_string( s );
00107 }
00108 
00109 sc_bv_base::sc_bv_base( const char* a, int length_ )
00110     : m_len( 0 ), m_size( 0 ), m_data( 0 )
00111 {
00112     init( length_ );
00113     assign_from_string( convert_to_bin( a ) );
00114 }
00115 
00116 sc_bv_base::sc_bv_base( const sc_bv_base& a )
00117     : m_len( a.m_len ),
00118       m_size( a.m_size ),
00119       m_data( new unsigned long[m_size] )
00120 {
00121     // copy the bits
00122     int sz = m_size;
00123     for( int i = 0; i < sz; ++ i ) {
00124   m_data[i] = a.m_data[i];
00125     }
00126 }
00127 
00128 
00129 // assignment operators
00130 
00131 sc_bv_base&
00132 sc_bv_base::operator = ( const char* a )
00133 {
00134     assign_from_string( convert_to_bin( a ) );
00135     return *this;
00136 }
00137 
00138 
00139 #if 0
00140 
00141 // bitwise complement
00142 
00143 sc_bv_base&
00144 sc_bv_base::b_not()
00145 {
00146     int sz = m_size;
00147     for( int i = 0; i < sz; ++ i ) {
00148   m_data[i] = ~m_data[i];
00149     }
00150     clean_tail();
00151     return *this;
00152 }
00153 
00154 
00155 // bitwise left shift
00156 
00157 sc_bv_base&
00158 sc_bv_base::operator <<= ( int n )
00159 {
00160     if( n < 0 ) {
00161   char msg[BUFSIZ];
00162   sprintf( msg,
00163      "left shift operation is only allowed with positive "
00164      "shift values, shift value = %d", n );
00165   SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00166     }
00167     int sz = m_size;
00168     if( n >= m_len ) {
00169   for( int i = 0; i < sz; ++ i ) {
00170       m_data[i] = UL_ZERO;
00171   }
00172   // clean_tail();
00173   return *this;
00174     }
00175     int wn = n / UL_SIZE;
00176     int bn = n % UL_SIZE;
00177     if( wn != 0 ) {
00178   // shift words
00179   int i = sz - 1;
00180   for( ; i >= wn; -- i ) {
00181       m_data[i] = m_data[i - wn];
00182   }
00183   for( ; i >= 0; -- i ) {
00184       m_data[i] = UL_ZERO;
00185   }
00186     }
00187     if( bn != 0 ) {
00188   // shift bits
00189   for( int i = sz - 1; i >= 1; -- i ) {
00190       m_data[i] <<= bn;
00191       m_data[i] |= m_data[i - 1] >> (UL_SIZE - bn);
00192   }
00193   m_data[0] <<= bn;
00194     }
00195     clean_tail();
00196     return *this;
00197 }
00198 
00199 
00200 // bitwise right shift
00201 
00202 sc_bv_base&
00203 sc_bv_base::operator >>= ( int n )
00204 {
00205     if( n < 0 ) {
00206   char msg[BUFSIZ];
00207   sprintf( msg,
00208      "right shift operation is only allowed with positive "
00209      "shift values, shift value = %d", n );
00210   SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00211     }
00212     int sz = m_size;
00213     if( n >= m_len ) {
00214   for( int i = 0; i < sz; ++ i ) {
00215       m_data[i] = UL_ZERO;
00216   }
00217   // clean_tail();
00218   return *this;
00219     }
00220     int wn = n / UL_SIZE;
00221     int bn = n % UL_SIZE;
00222     if( wn != 0 ) {
00223   // shift words
00224   int i = 0;
00225   for( ; i < (sz - wn); ++ i ) {
00226       m_data[i] = m_data[i + wn];
00227   }
00228   for( ; i < sz; ++ i ) {
00229       m_data[i] = UL_ZERO;
00230   }
00231     }
00232     if( bn != 0 ) {
00233   // shift bits
00234   for( int i = 0; i < (sz - 1); ++ i ) {
00235       m_data[i] >>= bn;
00236       m_data[i] |= m_data[i + 1] << (UL_SIZE - bn);
00237   }
00238   m_data[sz - 1] >>= bn;
00239     }
00240     clean_tail();
00241     return *this;
00242 }
00243 
00244 
00245 // bitwise left rotate
00246 
00247 sc_bv_base&
00248 sc_bv_base::lrotate( int n )
00249 {
00250     if( n < 0 ) {
00251   char msg[BUFSIZ];
00252   sprintf( msg,
00253      "left rotate operation is only allowed with positive "
00254      "rotate values, rotate value = %d", n );
00255   SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00256     }
00257     int len = m_len;
00258     n %= len;
00259     *this = (*this << n) | (*this >> (len - n));
00260     return *this;
00261 }
00262 
00263 
00264 // bitwise right rotate
00265 
00266 sc_bv_base&
00267 sc_bv_base::rrotate( int n )
00268 {
00269     if( n < 0 ) {
00270   char msg[BUFSIZ];
00271   sprintf( msg,
00272      "right rotate operation is only allowed with positive "
00273      "rotate values, rotate value = %d", n );
00274   SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, msg );
00275     }
00276     int len = m_len;
00277     n %= len;
00278     *this = (*this >> n) | (*this << (len - n));
00279     return *this;
00280 }
00281 
00282 #endif
00283 
00284 
00285 // ----------------------------------------------------------------------------
00286 
00287 // convert formatted string to binary string
00288 
00289 const sc_string
00290 convert_to_bin( const char* s )
00291 {
00292     // Beware: logic character strings cannot start with '0x' or '0X',
00293     //         because this is seen as a hexadecimal encoding prefix!
00294 
00295     if( s == 0 ) {
00296   SC_REPORT_ERROR( SC_ID_CANNOT_CONVERT_, "character string is zero" );
00297     }
00298     if( *s == 0 ) {
00299   SC_REPORT_ERROR( SC_ID_CANNOT_CONVERT_, "character string is empty" );
00300     }
00301 
00302     int n = strlen( s );
00303     int i = 0;
00304     if( s[0] == '-' || s[0] == '+' ) {
00305   ++ i;
00306     }
00307     if( n > (i + 2) && s[i] == '0' &&
00308   (s[i+1] == 'b' || s[i+1] == 'B' ||
00309    s[i+1] == 'c' || s[i+1] == 'C' ||
00310    s[i+1] == 'd' || s[i+1] == 'D' ||
00311    s[i+1] == 'o' || s[i+1] == 'O' ||
00312    s[i+1] == 'x' || s[i+1] == 'X') )
00313     {
00314   try {
00315       // worst case length = n * 4
00316       sc_fix a( s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON );
00317       sc_string str = a.to_bin();
00318       str += "F"; // mark the string as formatted
00319       // get rid of prefix (0b) and redundant leading bits
00320       const char* p = str.c_str() + 2;
00321       while( p[1] && p[0] == p[1] ) {
00322     ++ p;
00323       }
00324       return sc_string( p );
00325   } catch( sc_exception ) {
00326       char msg[BUFSIZ];
00327       sprintf( msg, "character string '%s' is not valid", s );
00328       SC_REPORT_ERROR( SC_ID_CANNOT_CONVERT_, msg );
00329       // never reached
00330       return sc_string();
00331   }
00332     }
00333     else {
00334   // bin by default
00335   sc_string str( s );
00336   str += "U"; // mark the string as unformatted
00337   return str;
00338     }
00339 }
00340 
00341 // convert binary string to formatted string
00342 
00343 const sc_string
00344 convert_to_fmt( const sc_string& s, sc_numrep numrep, bool w_prefix )
00345 {
00346     int n = s.length();
00347     sc_string str = "0bus" + s;
00348     sc_ufix a( str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON );
00349     return a.to_string( numrep, w_prefix );
00350 }
00351 
00352 } // namespace sc_dt

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