00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "sysc/datatypes/bit/sc_bit_ids.h"
00051 #include "sysc/datatypes/bit/sc_bv_base.h"
00052 #include "sysc/datatypes/fx/sc_fix.h"
00053 #include "sysc/datatypes/fx/sc_ufix.h"
00054
00055
00056 namespace sc_dt
00057 {
00058
00059
00060
00061
00062
00063
00064
00065 void
00066 sc_bv_base::init( int length_, bool init_value )
00067 {
00068
00069 if( length_ <= 0 ) {
00070 SC_REPORT_ERROR( sc_core::SC_ID_ZERO_LENGTH_, 0 );
00071 }
00072
00073 m_len = length_;
00074 m_size = (m_len - 1) / SC_DIGIT_SIZE + 1;
00075 m_data = new sc_digit[m_size];
00076
00077 sc_digit dw = init_value ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO;
00078 int sz = m_size;
00079 for( int i = 0; i < sz; ++ i ) {
00080 m_data[i] = dw;
00081 }
00082 clean_tail();
00083 }
00084
00085
00086 void
00087 sc_bv_base::assign_from_string( const std::string& s )
00088 {
00089
00090 int len = m_len;
00091 int s_len = s.length() - 1;
00092 int min_len = sc_min( len, s_len );
00093 int i = 0;
00094 for( ; i < min_len; ++ i ) {
00095 char c = s[s_len - i - 1];
00096 if( c != '0' && c != '1' ) {
00097 SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_,
00098 "string can contain only '0' and '1' characters" );
00099 }
00100 set_bit( i, sc_logic_value_t( c - '0' ) );
00101 }
00102
00103 sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
00104 : sc_logic_value_t( 0 ));
00105 for( ; i < len; ++ i ) {
00106 set_bit( i, fill );
00107 }
00108 }
00109
00110
00111
00112
00113 sc_bv_base::sc_bv_base( const char* a )
00114 : m_len( 0 ), m_size( 0 ), m_data( 0 )
00115 {
00116 std::string s = convert_to_bin( a );
00117 init( s.length() - 1 );
00118 assign_from_string( s );
00119 }
00120
00121 sc_bv_base::sc_bv_base( const char* a, int length_ )
00122 : m_len( 0 ), m_size( 0 ), m_data( 0 )
00123 {
00124 init( length_ );
00125 assign_from_string( convert_to_bin( a ) );
00126 }
00127
00128 sc_bv_base::sc_bv_base( const sc_bv_base& a )
00129 : m_len( a.m_len ),
00130 m_size( a.m_size ),
00131 m_data( new sc_digit[m_size] )
00132 {
00133
00134 int sz = m_size;
00135 for( int i = 0; i < sz; ++ i ) {
00136 m_data[i] = a.m_data[i];
00137 }
00138 }
00139
00140
00141
00142
00143 sc_bv_base&
00144 sc_bv_base::operator = ( const char* a )
00145 {
00146 assign_from_string( convert_to_bin( a ) );
00147 return *this;
00148 }
00149
00150
00151 #if 0
00152
00153
00154
00155 sc_bv_base&
00156 sc_bv_base::b_not()
00157 {
00158 int sz = m_size;
00159 for( int i = 0; i < sz; ++ i ) {
00160 m_data[i] = ~m_data[i];
00161 }
00162 clean_tail();
00163 return *this;
00164 }
00165
00166
00167
00168
00169 sc_bv_base&
00170 sc_bv_base::operator <<= ( int n )
00171 {
00172 if( n < 0 ) {
00173 char msg[BUFSIZ];
00174 std::sprintf( msg,
00175 "left shift operation is only allowed with positive "
00176 "shift values, shift value = %d", n );
00177 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
00178 }
00179 int sz = m_size;
00180 if( n >= m_len ) {
00181 for( int i = 0; i < sz; ++ i ) {
00182 m_data[i] = SC_DIGIT_ZERO;
00183 }
00184
00185 return *this;
00186 }
00187 int wn = n / SC_DIGIT_SIZE;
00188 int bn = n % SC_DIGIT_SIZE;
00189 if( wn != 0 ) {
00190
00191 int i = sz - 1;
00192 for( ; i >= wn; -- i ) {
00193 m_data[i] = m_data[i - wn];
00194 }
00195 for( ; i >= 0; -- i ) {
00196 m_data[i] = SC_DIGIT_ZERO;
00197 }
00198 }
00199 if( bn != 0 ) {
00200
00201 for( int i = sz - 1; i >= 1; -- i ) {
00202 m_data[i] <<= bn;
00203 m_data[i] |= m_data[i - 1] >> (SC_DIGIT_SIZE - bn);
00204 }
00205 m_data[0] <<= bn;
00206 }
00207 clean_tail();
00208 return *this;
00209 }
00210
00211
00212
00213
00214 sc_bv_base&
00215 sc_bv_base::operator >>= ( int n )
00216 {
00217 if( n < 0 ) {
00218 char msg[BUFSIZ];
00219 std::sprintf( msg,
00220 "right shift operation is only allowed with positive "
00221 "shift values, shift value = %d", n );
00222 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
00223 }
00224 int sz = m_size;
00225 if( n >= m_len ) {
00226 for( int i = 0; i < sz; ++ i ) {
00227 m_data[i] = SC_DIGIT_ZERO;
00228 }
00229
00230 return *this;
00231 }
00232 int wn = n / SC_DIGIT_SIZE;
00233 int bn = n % SC_DIGIT_SIZE;
00234 if( wn != 0 ) {
00235
00236 int i = 0;
00237 for( ; i < (sz - wn); ++ i ) {
00238 m_data[i] = m_data[i + wn];
00239 }
00240 for( ; i < sz; ++ i ) {
00241 m_data[i] = SC_DIGIT_ZERO;
00242 }
00243 }
00244 if( bn != 0 ) {
00245
00246 for( int i = 0; i < (sz - 1); ++ i ) {
00247 m_data[i] >>= bn;
00248 m_data[i] |= m_data[i + 1] << (SC_DIGIT_SIZE - bn);
00249 }
00250 m_data[sz - 1] >>= bn;
00251 }
00252 clean_tail();
00253 return *this;
00254 }
00255
00256
00257
00258
00259 sc_bv_base&
00260 sc_bv_base::lrotate( int n )
00261 {
00262 if( n < 0 ) {
00263 char msg[BUFSIZ];
00264 std::sprintf( msg,
00265 "left rotate operation is only allowed with positive "
00266 "rotate values, rotate value = %d", n );
00267 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
00268 }
00269 int len = m_len;
00270 n %= len;
00271 *this = (*this << n) | (*this >> (len - n));
00272 return *this;
00273 }
00274
00275
00276
00277
00278 sc_bv_base&
00279 sc_bv_base::rrotate( int n )
00280 {
00281 if( n < 0 ) {
00282 char msg[BUFSIZ];
00283 std::sprintf( msg,
00284 "right rotate operation is only allowed with positive "
00285 "rotate values, rotate value = %d", n );
00286 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
00287 }
00288 int len = m_len;
00289 n %= len;
00290 *this = (*this >> n) | (*this << (len - n));
00291 return *this;
00292 }
00293
00294 #endif
00295
00296
00297
00298
00299
00300
00301 const std::string
00302 convert_to_bin( const char* s )
00303 {
00304
00305
00306
00307 if( s == 0 ) {
00308 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_,
00309 "character string is zero" );
00310 }
00311 if( *s == 0 ) {
00312 SC_REPORT_ERROR(sc_core::SC_ID_CANNOT_CONVERT_,
00313 "character string is empty");
00314 }
00315
00316 int n = strlen( s );
00317 int i = 0;
00318 if( s[0] == '-' || s[0] == '+' ) {
00319 ++ i;
00320 }
00321 if( n > (i + 2) && s[i] == '0' )
00322 {
00323 if (s[i+1] == 'b' || s[i+1] == 'B' )
00324 {
00325 if ( s[i+2] == '0' || s[i+2] == '1' )
00326 {
00327 std::string str( &s[2] );
00328 str += "F";
00329 return str;
00330 }
00331 }
00332 if ( s[i+1] == 'b' || s[i+1] == 'B' ||
00333 s[i+1] == 'c' || s[i+1] == 'C' ||
00334 s[i+1] == 'd' || s[i+1] == 'D' ||
00335 s[i+1] == 'o' || s[i+1] == 'O' ||
00336 s[i+1] == 'x' || s[i+1] == 'X')
00337 {
00338 try {
00339
00340 sc_fix a( s, n * 4, n * 4, SC_TRN, SC_WRAP, 0, SC_ON );
00341 std::string str = a.to_bin();
00342 str += "F";
00343
00344 const char* p = str.c_str() + 2;
00345 while( p[1] && p[0] == p[1] ) {
00346 ++ p;
00347 }
00348 return std::string( p );
00349 } catch( sc_core::sc_report ) {
00350 char msg[BUFSIZ];
00351 std::sprintf( msg, "character string '%s' is not valid", s );
00352 SC_REPORT_ERROR( sc_core::SC_ID_CANNOT_CONVERT_, msg );
00353
00354 return std::string();
00355 }
00356 }
00357
00358 }
00359
00360
00361
00362 std::string str( s );
00363 str += "U";
00364 return str;
00365 }
00366
00367
00368
00369 const std::string
00370 convert_to_fmt( const std::string& s, sc_numrep numrep, bool w_prefix )
00371 {
00372 int n = s.length();
00373 std::string str("0bus");
00374
00375 str += s;
00376 sc_ufix a( str.c_str(), n, n, SC_TRN, SC_WRAP, 0, SC_ON );
00377 return a.to_string( numrep, w_prefix );
00378 }
00379
00380 }