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 #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
00049
00050
00051
00052
00053 void
00054 sc_bv_base::init( int length_, bool init_value )
00055 {
00056
00057 if( length_ <= 0 ) {
00058 SC_REPORT_ERROR( SC_ID_ZERO_LENGTH_, 0 );
00059 }
00060
00061 m_len = length_;
00062 m_size = (m_len - 1) / UL_SIZE + 1;
00063 m_data = new unsigned long[m_size];
00064
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
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
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
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
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
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
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
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
00173 return *this;
00174 }
00175 int wn = n / UL_SIZE;
00176 int bn = n % UL_SIZE;
00177 if( wn != 0 ) {
00178
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
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
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
00218 return *this;
00219 }
00220 int wn = n / UL_SIZE;
00221 int bn = n % UL_SIZE;
00222 if( wn != 0 ) {
00223
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
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
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
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
00288
00289 const sc_string
00290 convert_to_bin( const char* s )
00291 {
00292
00293
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
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";
00319
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
00330 return sc_string();
00331 }
00332 }
00333 else {
00334
00335 sc_string str( s );
00336 str += "U";
00337 return str;
00338 }
00339 }
00340
00341
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 }