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 #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
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
00079
00080
00081
00082
00083 sc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
00084
00085
00086
00087
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
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
00132
00133
00134
00135
00136 bool sc_uint_subref_r::concat_get_ctrl( sc_digit* dst_p, int low_i ) const
00137 {
00138 int dst_i;
00139 int end_i;
00140 int left_shift;
00141 sc_digit mask;
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;
00159 int end_i;
00160 int high_i;
00161 int left_shift;
00162 sc_digit mask;
00163 bool result;
00164 uint_type val;
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
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
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
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
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
00218
00219
00220
00221
00222 sc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
00223
00224
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
00267
00268
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
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
00312
00313
00314
00315
00316
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
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
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
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
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
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
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
00514 return *this;
00515 }
00516 }
00517
00518
00519
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
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;
00570 int end_i;
00571 int left_shift;
00572 sc_digit mask;
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
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;
00591 int end_i;
00592 int high_i;
00593 int left_shift;
00594 sc_digit mask;
00595 bool result;
00596 sc_digit val;
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
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
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
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
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
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 }
00674
00675
00676