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
00051
00052
00053 #ifndef SC_PROXY_H
00054 #define SC_PROXY_H
00055
00056
00057 #include "sysc/kernel/sc_cmnhdr.h"
00058 #include "sysc/utils/sc_iostream.h"
00059 #include "sysc/datatypes/int/sc_signed.h"
00060 #include "sysc/datatypes/int/sc_unsigned.h"
00061 #include "sysc/datatypes/int/sc_int_base.h"
00062 #include "sysc/datatypes/int/sc_uint_base.h"
00063 #include "sysc/utils/sc_string.h"
00064 #include "sysc/datatypes/bit/sc_bit.h"
00065 #include "sysc/datatypes/bit/sc_bit_ids.h"
00066 #include "sysc/datatypes/bit/sc_logic.h"
00067 #include "sysc/kernel/sc_macros.h"
00068
00069
00070 namespace sc_dt
00071 {
00072
00073
00074 template <class X> class sc_proxy;
00075
00076
00077 class sc_bv_base;
00078 class sc_lv_base;
00079 template <class X> class sc_bitref_r;
00080 template <class X> class sc_bitref;
00081 template <class X> class sc_subref_r;
00082 template <class X> class sc_subref;
00083 template <class X, class Y> class sc_concref_r;
00084 template <class X, class Y> class sc_concref;
00085
00086
00087 const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit );
00088
00089 const sc_digit SC_DIGIT_ZERO = (sc_digit)0;
00090 const sc_digit SC_DIGIT_ONE = (sc_digit)1;
00091 const sc_digit SC_DIGIT_TWO = (sc_digit)2;
00092
00093
00094
00095
00096 template <class X, class Y>
00097 inline
00098 void
00099 assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py );
00100
00101
00102
00103
00104 template <class X, class T>
00105 inline
00106 void
00107 assign_v_( sc_proxy<X>& px, const T& a );
00108
00109
00110
00111
00112 const std::string convert_to_bin( const char* s );
00113 const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool );
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 template <class X>
00124 class sc_proxy
00125 {
00126 public:
00127
00128
00129
00130 virtual ~sc_proxy() {}
00131
00132
00133
00134
00135 X& back_cast()
00136 { return SCAST<X&>( *this ); }
00137
00138 const X& back_cast() const
00139 { return SCAST<const X&>( *this ); }
00140
00141
00142
00143
00144 template <class Y>
00145 X& assign_( const sc_proxy<Y>& a )
00146 { assign_p_( *this, a ); return back_cast(); }
00147
00148 X& assign_( const char* a );
00149 X& assign_( const bool* a );
00150 X& assign_( const sc_logic* a );
00151
00152 X& assign_( const sc_unsigned& a )
00153 { assign_v_( *this, a ); return back_cast(); }
00154
00155 X& assign_( const sc_signed& a )
00156 { assign_v_( *this, a ); return back_cast(); }
00157
00158 X& assign_( const sc_uint_base& a )
00159 { return assign_( (uint64) a ); }
00160
00161 X& assign_( const sc_int_base& a )
00162 { return assign_( (int64) a ); }
00163
00164 X& assign_( unsigned int a );
00165 X& assign_( int a );
00166
00167 X& assign_( unsigned long a );
00168
00169 X& assign_( long a );
00170
00171 X& assign_( uint64 a );
00172 X& assign_( int64 a );
00173
00174
00175
00176
00177
00178
00179 X& b_not();
00180
00181 const sc_lv_base operator ~ () const;
00182
00183
00184
00185
00186 X& operator &= ( const char* b );
00187 X& operator &= ( const bool* b );
00188 X& operator &= ( const sc_logic* b );
00189 X& operator &= ( const sc_unsigned& b );
00190 X& operator &= ( const sc_signed& b );
00191
00192 X& operator &= ( const sc_uint_base& b )
00193 { return operator &= ( (uint64) b ); }
00194
00195 X& operator &= ( const sc_int_base& b )
00196 { return operator &= ( (int64) b ); }
00197
00198 X& operator &= ( unsigned long b );
00199 X& operator &= ( long b );
00200
00201 X& operator &= ( unsigned int b )
00202 { return operator &= ( (unsigned long) b ); }
00203
00204 X& operator &= ( int b )
00205 { return operator &= ( (long) b ); }
00206
00207 X& operator &= ( uint64 b );
00208 X& operator &= ( int64 b );
00209
00210
00211 const sc_lv_base operator & ( const char* b ) const;
00212 const sc_lv_base operator & ( const bool* b ) const;
00213 const sc_lv_base operator & ( const sc_logic* b ) const;
00214 const sc_lv_base operator & ( const sc_unsigned& b ) const;
00215 const sc_lv_base operator & ( const sc_signed& b ) const;
00216 const sc_lv_base operator & ( const sc_uint_base& b ) const;
00217 const sc_lv_base operator & ( const sc_int_base& b ) const;
00218 const sc_lv_base operator & ( unsigned long b ) const;
00219 const sc_lv_base operator & ( long b ) const;
00220 const sc_lv_base operator & ( unsigned int b ) const;
00221 const sc_lv_base operator & ( int b ) const;
00222 const sc_lv_base operator & ( uint64 b ) const;
00223 const sc_lv_base operator & ( int64 b ) const;
00224
00225
00226
00227
00228 X& operator |= ( const char* b );
00229 X& operator |= ( const bool* b );
00230 X& operator |= ( const sc_logic* b );
00231 X& operator |= ( const sc_unsigned& b );
00232 X& operator |= ( const sc_signed& b );
00233
00234 X& operator |= ( const sc_uint_base& b )
00235 { return operator |= ( (uint64) b ); }
00236
00237 X& operator |= ( const sc_int_base& b )
00238 { return operator |= ( (int64) b ); }
00239
00240 X& operator |= ( unsigned long b );
00241 X& operator |= ( long b );
00242
00243 X& operator |= ( unsigned int b )
00244 { return operator |= ( (unsigned long) b ); }
00245
00246 X& operator |= ( int b )
00247 { return operator |= ( (long) b ); }
00248
00249 X& operator |= ( uint64 b );
00250 X& operator |= ( int64 b );
00251
00252
00253 const sc_lv_base operator | ( const char* b ) const;
00254 const sc_lv_base operator | ( const bool* b ) const;
00255 const sc_lv_base operator | ( const sc_logic* b ) const;
00256 const sc_lv_base operator | ( const sc_unsigned& b ) const;
00257 const sc_lv_base operator | ( const sc_signed& b ) const;
00258 const sc_lv_base operator | ( const sc_uint_base& b ) const;
00259 const sc_lv_base operator | ( const sc_int_base& b ) const;
00260 const sc_lv_base operator | ( unsigned long b ) const;
00261 const sc_lv_base operator | ( long b ) const;
00262 const sc_lv_base operator | ( unsigned int b ) const;
00263 const sc_lv_base operator | ( int b ) const;
00264 const sc_lv_base operator | ( uint64 b ) const;
00265 const sc_lv_base operator | ( int64 b ) const;
00266
00267
00268
00269
00270 X& operator ^= ( const char* b );
00271 X& operator ^= ( const bool* b );
00272 X& operator ^= ( const sc_logic* b );
00273 X& operator ^= ( const sc_unsigned& b );
00274 X& operator ^= ( const sc_signed& b );
00275
00276 X& operator ^= ( const sc_uint_base& b )
00277 { return operator ^= ( (uint64) b ); }
00278
00279 X& operator ^= ( const sc_int_base& b )
00280 { return operator ^= ( (int64) b ); }
00281
00282 X& operator ^= ( unsigned long b );
00283 X& operator ^= ( long b );
00284
00285 X& operator ^= ( unsigned int b )
00286 { return operator ^= ( (unsigned long) b ); }
00287
00288 X& operator ^= ( int b )
00289 { return operator ^= ( (long) b ); }
00290
00291 X& operator ^= ( uint64 b );
00292 X& operator ^= ( int64 b );
00293
00294
00295 const sc_lv_base operator ^ ( const char* b ) const;
00296 const sc_lv_base operator ^ ( const bool* b ) const;
00297 const sc_lv_base operator ^ ( const sc_logic* b ) const;
00298 const sc_lv_base operator ^ ( const sc_unsigned& b ) const;
00299 const sc_lv_base operator ^ ( const sc_signed& b ) const;
00300 const sc_lv_base operator ^ ( const sc_uint_base& b ) const;
00301 const sc_lv_base operator ^ ( const sc_int_base& b ) const;
00302 const sc_lv_base operator ^ ( unsigned long b ) const;
00303 const sc_lv_base operator ^ ( long b ) const;
00304 const sc_lv_base operator ^ ( unsigned int b ) const;
00305 const sc_lv_base operator ^ ( int b ) const;
00306 const sc_lv_base operator ^ ( uint64 b ) const;
00307 const sc_lv_base operator ^ ( int64 b ) const;
00308
00309
00310
00311
00312 X& operator <<= ( int n );
00313
00314 const sc_lv_base operator << ( int n ) const;
00315
00316
00317
00318
00319 X& operator >>= ( int n );
00320
00321 const sc_lv_base operator >> ( int n ) const;
00322
00323
00324
00325
00326 X& lrotate( int n );
00327
00328
00329
00330
00331 X& rrotate( int n );
00332
00333
00334
00335
00336 X& reverse();
00337
00338
00339
00340
00341 sc_bitref<X> operator [] ( int i )
00342 { return sc_bitref<X>( back_cast(), i ); }
00343
00344 sc_bitref_r<X> operator [] ( int i ) const
00345 { return sc_bitref_r<X>( back_cast(), i ); }
00346
00347 sc_bitref<X> bit( int i )
00348 { return sc_bitref<X>( back_cast(), i ); }
00349
00350 sc_bitref_r<X> bit( int i ) const
00351 { return sc_bitref_r<X>( back_cast(), i ); }
00352
00353
00354
00355
00356 sc_subref<X> operator () ( int hi, int lo )
00357 { return sc_subref<X>( back_cast(), hi, lo ); }
00358
00359 sc_subref_r<X> operator () ( int hi, int lo ) const
00360 { return sc_subref_r<X>( back_cast(), hi, lo ); }
00361
00362 sc_subref<X> range( int hi, int lo )
00363 { return sc_subref<X>( back_cast(), hi, lo ); }
00364
00365 sc_subref_r<X> range( int hi, int lo ) const
00366 { return sc_subref_r<X>( back_cast(), hi, lo ); }
00367
00368
00369
00370
00371 sc_logic_value_t and_reduce() const;
00372
00373 sc_logic_value_t nand_reduce() const
00374 { return sc_logic::not_table[and_reduce()]; }
00375
00376 sc_logic_value_t or_reduce() const;
00377
00378 sc_logic_value_t nor_reduce() const
00379 { return sc_logic::not_table[or_reduce()]; }
00380
00381 sc_logic_value_t xor_reduce() const;
00382
00383 sc_logic_value_t xnor_reduce() const
00384 { return sc_logic::not_table[xor_reduce()]; }
00385
00386
00387
00388
00389 bool operator == ( const char* b ) const;
00390 bool operator == ( const bool* b ) const;
00391 bool operator == ( const sc_logic* b ) const;
00392 bool operator == ( const sc_unsigned& b ) const;
00393 bool operator == ( const sc_signed& b ) const;
00394 bool operator == ( const sc_uint_base& b ) const;
00395 bool operator == ( const sc_int_base& b ) const;
00396 bool operator == ( unsigned long b ) const;
00397 bool operator == ( long b ) const;
00398 bool operator == ( unsigned int b ) const;
00399 bool operator == ( int b ) const;
00400 bool operator == ( uint64 b ) const;
00401 bool operator == ( int64 b ) const;
00402
00403
00404
00405
00406 const std::string to_string() const;
00407 const std::string to_string( sc_numrep ) const;
00408 const std::string to_string( sc_numrep, bool ) const;
00409
00410
00411
00412
00413 inline int64 to_int64() const
00414 { return to_anything_signed(); }
00415 inline uint64 to_uint64() const;
00416 int to_int() const
00417 { return (int)to_anything_signed(); }
00418
00419 unsigned int to_uint() const
00420 { return (unsigned int)to_anything_unsigned(); }
00421
00422 long to_long() const
00423 { return (long)to_anything_signed(); }
00424
00425 unsigned long to_ulong() const
00426 { return (unsigned long)to_anything_unsigned(); }
00427
00428 #ifdef SC_DT_DEPRECATED
00429
00430 int to_signed() const
00431 { return to_int(); }
00432
00433 sc_digit to_unsigned() const
00434 { return to_uint(); }
00435
00436 #endif
00437
00438
00439
00440
00441 void print( ::std::ostream& os = ::std::cout ) const
00442 {
00443
00444
00445 if ( sc_io_base(os, SC_DEC) == SC_DEC )
00446 os << to_string();
00447 else
00448 os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os));
00449 }
00450
00451 void scan( ::std::istream& is = ::std::cin );
00452
00453 protected:
00454
00455 void check_bounds( int n ) const;
00456 void check_wbounds( int n ) const;
00457
00458 sc_digit to_anything_unsigned() const;
00459 int64 to_anything_signed() const;
00460 };
00461
00462
00463
00464
00465
00466
00467
00468
00469 template <class X, class Y>
00470 inline
00471 X&
00472 operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
00473
00474
00475 template <class X, class Y>
00476 inline
00477 const sc_lv_base
00478 operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
00479
00480
00481 #define DECL_BITWISE_AND_OP_T(tp) \
00482 template <class X> \
00483 inline \
00484 const sc_lv_base \
00485 operator & ( tp b, const sc_proxy<X>& px );
00486
00487 DECL_BITWISE_AND_OP_T(const char*)
00488 DECL_BITWISE_AND_OP_T(const bool*)
00489 DECL_BITWISE_AND_OP_T(const sc_logic*)
00490 DECL_BITWISE_AND_OP_T(const sc_unsigned&)
00491 DECL_BITWISE_AND_OP_T(const sc_signed&)
00492 DECL_BITWISE_AND_OP_T(const sc_uint_base&)
00493 DECL_BITWISE_AND_OP_T(const sc_int_base&)
00494 DECL_BITWISE_AND_OP_T(unsigned long)
00495 DECL_BITWISE_AND_OP_T(long)
00496 DECL_BITWISE_AND_OP_T(unsigned int)
00497 DECL_BITWISE_AND_OP_T(int)
00498 DECL_BITWISE_AND_OP_T(uint64)
00499 DECL_BITWISE_AND_OP_T(int64)
00500
00501 #undef DECL_BITWISE_AND_OP_T
00502
00503
00504
00505
00506 template <class X, class Y>
00507 inline
00508 X&
00509 operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
00510
00511
00512 template <class X, class Y>
00513 inline
00514 const sc_lv_base
00515 operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
00516
00517
00518 #define DECL_BITWISE_OR_OP_T(tp) \
00519 template <class X> \
00520 inline \
00521 const sc_lv_base \
00522 operator | ( tp a, const sc_proxy<X>& px );
00523
00524 DECL_BITWISE_OR_OP_T(const char*)
00525 DECL_BITWISE_OR_OP_T(const bool*)
00526 DECL_BITWISE_OR_OP_T(const sc_logic*)
00527 DECL_BITWISE_OR_OP_T(const sc_unsigned&)
00528 DECL_BITWISE_OR_OP_T(const sc_signed&)
00529 DECL_BITWISE_OR_OP_T(const sc_uint_base&)
00530 DECL_BITWISE_OR_OP_T(const sc_int_base&)
00531 DECL_BITWISE_OR_OP_T(unsigned long)
00532 DECL_BITWISE_OR_OP_T(long)
00533 DECL_BITWISE_OR_OP_T(unsigned int)
00534 DECL_BITWISE_OR_OP_T(int)
00535 DECL_BITWISE_OR_OP_T(uint64)
00536 DECL_BITWISE_OR_OP_T(int64)
00537
00538 #undef DECL_BITWISE_OR_OP_T
00539
00540
00541
00542
00543 template <class X, class Y>
00544 inline
00545 X&
00546 operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
00547
00548
00549 template <class X, class Y>
00550 inline
00551 const sc_lv_base
00552 operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
00553
00554
00555 #define DECL_BITWISE_XOR_OP_T(tp) \
00556 template <class X> \
00557 inline \
00558 const sc_lv_base \
00559 operator ^ ( tp a, const sc_proxy<X>& px );
00560
00561 DECL_BITWISE_XOR_OP_T(const char*)
00562 DECL_BITWISE_XOR_OP_T(const bool*)
00563 DECL_BITWISE_XOR_OP_T(const sc_logic*)
00564 DECL_BITWISE_XOR_OP_T(const sc_unsigned&)
00565 DECL_BITWISE_XOR_OP_T(const sc_signed&)
00566 DECL_BITWISE_XOR_OP_T(const sc_uint_base&)
00567 DECL_BITWISE_XOR_OP_T(const sc_int_base&)
00568 DECL_BITWISE_XOR_OP_T(unsigned long)
00569 DECL_BITWISE_XOR_OP_T(long)
00570 DECL_BITWISE_XOR_OP_T(unsigned int)
00571 DECL_BITWISE_XOR_OP_T(int)
00572 DECL_BITWISE_XOR_OP_T(uint64)
00573 DECL_BITWISE_XOR_OP_T(int64)
00574
00575 #undef DECL_BITWISE_XOR_OP_T
00576
00577
00578
00579
00580 template <class X, class Y>
00581 inline
00582 bool
00583 operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
00584
00585 template <class X, class Y>
00586 inline
00587 bool
00588 operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
00589
00590
00591 #define DECL_REL_OP_T(tp) \
00592 template <class X> \
00593 inline \
00594 bool \
00595 operator == ( tp b, const sc_proxy<X>& px ); \
00596 \
00597 template <class X> \
00598 inline \
00599 bool \
00600 operator != ( const sc_proxy<X>& px, tp b ); \
00601 \
00602 template <class X> \
00603 inline \
00604 bool \
00605 operator != ( tp b, const sc_proxy<X>& px );
00606
00607 DECL_REL_OP_T(const char*)
00608 DECL_REL_OP_T(const bool*)
00609 DECL_REL_OP_T(const sc_logic*)
00610 DECL_REL_OP_T(const sc_unsigned&)
00611 DECL_REL_OP_T(const sc_signed&)
00612 DECL_REL_OP_T(const sc_uint_base&)
00613 DECL_REL_OP_T(const sc_int_base&)
00614 DECL_REL_OP_T(unsigned long)
00615 DECL_REL_OP_T(long)
00616 DECL_REL_OP_T(unsigned int)
00617 DECL_REL_OP_T(int)
00618 DECL_REL_OP_T(uint64)
00619 DECL_REL_OP_T(int64)
00620
00621 #undef DECL_REL_OP_T
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 template <class X>
00634 inline
00635 void
00636 get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw )
00637 {
00638 x_dw = x.get_word( wi );
00639 x_cw = x.get_cword( wi );
00640 }
00641
00642 template <class X>
00643 inline
00644 void
00645 set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw )
00646 {
00647 x.set_word( wi, x_dw );
00648 x.set_cword( wi, x_cw );
00649 }
00650
00651 template <class X>
00652 inline
00653 void
00654 extend_sign_w_( X& x, int wi, bool sign )
00655 {
00656 int sz = x.size();
00657 unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO);
00658 for( int i = wi; i < sz; ++ i ) {
00659 set_words_( x, i, sgn, SC_DIGIT_ZERO );
00660 }
00661 }
00662
00663
00664
00665
00666 template <class X, class Y>
00667 inline
00668 void
00669 assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py )
00670 {
00671 if( (void*) &px != (void*) &py ) {
00672 X& x = px.back_cast();
00673 const Y& y = py.back_cast();
00674 int sz = x.size();
00675 int min_sz = sc_min( sz, y.size() );
00676 int i = 0;
00677 for( ; i < min_sz; ++ i ) {
00678 set_words_( x, i, y.get_word( i ), y.get_cword( i ) );
00679 }
00680
00681 extend_sign_w_( x, i, false );
00682 x.clean_tail();
00683 }
00684 }
00685
00686
00687
00688
00689
00690
00691
00692 template <class X, class T>
00693 inline
00694 void
00695 assign_v_( sc_proxy<X>& px, const T& a )
00696 {
00697 X& x = px.back_cast();
00698 int i;
00699 int len_x = x.length();
00700 int len_a = a.length();
00701 if ( len_a > len_x ) len_a = len_x;
00702 for( i = 0 ; i < len_a; ++ i ) {
00703 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
00704 }
00705 for( ; i < len_x; ++ i ) {
00706 x.set_bit( i, sc_logic_value_t( false ) );
00707 }
00708 }
00709
00710 template <class X>
00711 inline
00712 void
00713 assign_v_( sc_proxy<X>& px, const sc_int_base& a )
00714 {
00715 X& x = px.back_cast();
00716 int i;
00717 bool sign = a < 0;
00718 int len_x = x.length();
00719 int len_a = a.length();
00720 if ( len_a > len_x ) len_a = len_x;
00721 for( i = 0 ; i < len_a; ++ i ) {
00722 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
00723 }
00724 for( ; i < len_x; ++ i ) {
00725 x.set_bit( i, sc_logic_value_t( sign ) );
00726 }
00727 }
00728
00729 template <class X>
00730 inline
00731 void
00732 assign_v_( sc_proxy<X>& px, const sc_signed& a )
00733 {
00734 X& x = px.back_cast();
00735 int i;
00736 bool sign = a < 0;
00737 int len_x = x.length();
00738 int len_a = a.length();
00739 if ( len_a > len_x ) len_a = len_x;
00740 for( i = 0 ; i < len_a; ++ i ) {
00741 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
00742 }
00743 for( ; i < len_x; ++ i ) {
00744 x.set_bit( i, sc_logic_value_t( sign ) );
00745 }
00746 }
00747
00748 template <class X>
00749 inline
00750 void
00751 assign_v_( sc_proxy<X>& px, const sc_uint_base& a )
00752 {
00753 X& x = px.back_cast();
00754 int i;
00755 int len_x = x.length();
00756 int len_a = a.length();
00757 if ( len_a > len_x ) len_a = len_x;
00758 for( i = 0 ; i < len_a; ++ i ) {
00759 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
00760 }
00761 for( ; i < len_x; ++ i ) {
00762 x.set_bit( i, sc_logic_value_t( false ) );
00763 }
00764 }
00765
00766 template <class X>
00767 inline
00768 void
00769 assign_v_( sc_proxy<X>& px, const sc_unsigned& a )
00770 {
00771 X& x = px.back_cast();
00772 int i;
00773 int len_x = x.length();
00774 int len_a = a.length();
00775 if ( len_a > len_x ) len_a = len_x;
00776 for( i = 0 ; i < len_a; ++ i ) {
00777 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
00778 }
00779 for( ; i < len_x; ++ i ) {
00780 x.set_bit( i, sc_logic_value_t( false ) );
00781 }
00782 }
00783
00784
00785
00786
00787 template <class X>
00788 inline
00789 X&
00790 sc_proxy<X>::assign_( const char* a )
00791 {
00792 X& x = back_cast();
00793 std::string s = convert_to_bin( a );
00794 int len = x.length();
00795 int s_len = s.length() - 1;
00796 int min_len = sc_min( len, s_len );
00797 int i = 0;
00798 for( ; i < min_len; ++ i ) {
00799 char c = s[s_len - i - 1];
00800 x.set_bit( i, sc_logic::char_to_logic[(int)c] );
00801 }
00802
00803 sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
00804 : sc_logic_value_t( 0 ));
00805 for( ; i < len; ++ i ) {
00806 x.set_bit( i, fill );
00807 }
00808 return x;
00809 }
00810
00811 template <class X>
00812 inline
00813 X&
00814 sc_proxy<X>::assign_( const bool* a )
00815 {
00816
00817 X& x = back_cast();
00818 int len = x.length();
00819 for( int i = 0; i < len; ++ i ) {
00820 x.set_bit( i, sc_logic_value_t( a[i] ) );
00821 }
00822 return x;
00823 }
00824
00825 template <class X>
00826 inline
00827 X&
00828 sc_proxy<X>::assign_( const sc_logic* a )
00829 {
00830
00831 X& x = back_cast();
00832 int len = x.length();
00833 for( int i = 0; i < len; ++ i ) {
00834 x.set_bit( i, a[i].value() );
00835 }
00836 return x;
00837 }
00838
00839 template <class X>
00840 inline
00841 X&
00842 sc_proxy<X>::assign_( unsigned int a )
00843 {
00844 X& x = back_cast();
00845 set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
00846
00847 extend_sign_w_( x, 1, false );
00848 x.clean_tail();
00849 return x;
00850 }
00851
00852 template <class X>
00853 inline
00854 X&
00855 sc_proxy<X>::assign_( int a )
00856 {
00857 X& x = back_cast();
00858 set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
00859
00860 extend_sign_w_( x, 1, (a < 0) );
00861 x.clean_tail();
00862 return x;
00863 }
00864
00865 #if defined(SC_LONG_64)
00866 template <class X>
00867 inline
00868 X&
00869 sc_proxy<X>::assign_( unsigned long a )
00870 {
00871 X& x = back_cast();
00872 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
00873 if( x.size() > 1 ) {
00874 set_words_( x, 1,
00875 ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
00876 SC_DIGIT_ZERO );
00877
00878 extend_sign_w_( x, 2, false );
00879 }
00880 x.clean_tail();
00881 return x;
00882 }
00883
00884 template <class X>
00885 inline
00886 X&
00887 sc_proxy<X>::assign_( long a )
00888 {
00889 X& x = back_cast();
00890 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
00891 if( x.size() > 1 ) {
00892 set_words_( x, 1,
00893 ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
00894 SC_DIGIT_ZERO );
00895
00896 extend_sign_w_( x, 2, (a < 0) );
00897 }
00898 x.clean_tail();
00899 return x;
00900 }
00901
00902 #else
00903 template <class X>
00904 inline
00905 X&
00906 sc_proxy<X>::assign_( unsigned long a )
00907 {
00908 X& x = back_cast();
00909 set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
00910
00911 extend_sign_w_( x, 1, false );
00912 x.clean_tail();
00913 return x;
00914 }
00915
00916 template <class X>
00917 inline
00918 X&
00919 sc_proxy<X>::assign_( long a )
00920 {
00921 X& x = back_cast();
00922 set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
00923
00924 extend_sign_w_( x, 1, (a < 0) );
00925 x.clean_tail();
00926 return x;
00927 }
00928 #endif
00929 template <class X>
00930 inline
00931 X&
00932 sc_proxy<X>::assign_( uint64 a )
00933 {
00934 X& x = back_cast();
00935 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
00936 if( x.size() > 1 ) {
00937 set_words_( x, 1,
00938 ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
00939 SC_DIGIT_ZERO );
00940
00941 extend_sign_w_( x, 2, false );
00942 }
00943 x.clean_tail();
00944 return x;
00945 }
00946
00947 template <class X>
00948 inline
00949 X&
00950 sc_proxy<X>::assign_( int64 a )
00951 {
00952 X& x = back_cast();
00953 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
00954 if( x.size() > 1 ) {
00955 set_words_( x, 1,
00956 ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
00957 SC_DIGIT_ZERO );
00958
00959 extend_sign_w_( x, 2, (a < 0) );
00960 }
00961 x.clean_tail();
00962 return x;
00963 }
00964
00965
00966
00967
00968
00969
00970 template <class X>
00971 inline
00972 X&
00973 sc_proxy<X>::b_not()
00974 {
00975 X& x = back_cast();
00976 int sz = x.size();
00977 for( int i = 0; i < sz; ++ i ) {
00978 sc_digit x_dw, x_cw;
00979 get_words_( x, i, x_dw, x_cw );
00980 x.set_word( i, x_cw | ~x_dw );
00981 }
00982 x.clean_tail();
00983 return x;
00984 }
00985
00986
00987
00988
00989 template <class X, class Y>
00990 inline
00991 X&
00992 b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
00993 {
00994 X& x = px.back_cast();
00995 const Y& y = py.back_cast();
00996 assert( x.length() == y.length() );
00997 int sz = x.size();
00998 for( int i = 0; i < sz; ++ i ) {
00999 sc_digit x_dw, x_cw, y_dw, y_cw;
01000 get_words_( x, i, x_dw, x_cw );
01001 get_words_( y, i, y_dw, y_cw );
01002 sc_digit cw = x_dw & y_cw | x_cw & y_dw | x_cw & y_cw;
01003 sc_digit dw = cw | x_dw & y_dw;
01004 set_words_( x, i, dw, cw );
01005 }
01006
01007 return x;
01008 }
01009
01010
01011
01012
01013 template <class X, class Y>
01014 inline
01015 X&
01016 b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
01017 {
01018 X& x = px.back_cast();
01019 const Y& y = py.back_cast();
01020 assert( x.length() == y.length() );
01021 int sz = x.size();
01022 for( int i = 0; i < sz; ++ i ) {
01023 sc_digit x_dw, x_cw, y_dw, y_cw;
01024 get_words_( x, i, x_dw, x_cw );
01025 get_words_( y, i, y_dw, y_cw );
01026 sc_digit cw = x_cw & y_cw | x_cw & ~y_dw | ~x_dw & y_cw;
01027 sc_digit dw = cw | x_dw | y_dw;
01028 set_words_( x, i, dw, cw );
01029 }
01030
01031 return x;
01032 }
01033
01034
01035
01036
01037 template <class X, class Y>
01038 inline
01039 X&
01040 b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b )
01041 {
01042 X& x = a.back_cast();
01043 const Y& y = b.back_cast();
01044 assert( x.length() == y.length() );
01045 int sz = x.size();
01046 for( int i = 0; i < sz; ++ i ) {
01047 sc_digit x_dw, x_cw, y_dw, y_cw;
01048 get_words_( x, i, x_dw, x_cw );
01049 get_words_( y, i, y_dw, y_cw );
01050 sc_digit cw = x_cw | y_cw;
01051 sc_digit dw = cw | x_dw ^ y_dw;
01052 set_words_( x, i, dw, cw );
01053 }
01054
01055 return x;
01056 }
01057
01058
01059
01060
01061 template <class X>
01062 inline
01063 X&
01064 sc_proxy<X>::operator <<= ( int n )
01065 {
01066 X& x = back_cast();
01067 if( n < 0 ) {
01068 char msg[BUFSIZ];
01069 std::sprintf( msg,
01070 "left shift operation is only allowed with positive "
01071 "shift values, shift value = %d", n );
01072 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
01073 }
01074 if( n >= x.length() ) {
01075 extend_sign_w_( x, 0, false );
01076
01077 return x;
01078 }
01079 int sz = x.size();
01080 int wn = n / SC_DIGIT_SIZE;
01081 int bn = n % SC_DIGIT_SIZE;
01082 if( wn != 0 ) {
01083
01084 int i = sz - 1;
01085 for( ; i >= wn; -- i ) {
01086 set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) );
01087 }
01088 for( ; i >= 0; -- i ) {
01089 set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
01090 }
01091 }
01092 if( bn != 0 ) {
01093
01094 for( int i = sz - 1; i >= 1; -- i ) {
01095 sc_digit x_dw, x_cw;
01096 get_words_( x, i, x_dw, x_cw );
01097 x_dw <<= bn;
01098 x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn);
01099 x_cw <<= bn;
01100 x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn);
01101 set_words_( x, i, x_dw, x_cw );
01102 }
01103 sc_digit x_dw, x_cw;
01104 get_words_( x, 0, x_dw, x_cw );
01105 x_dw <<= bn;
01106 x_cw <<= bn;
01107 set_words_( x, 0, x_dw, x_cw );
01108 }
01109 x.clean_tail();
01110 return x;
01111 }
01112
01113
01114
01115
01116
01117 template <class X>
01118 inline
01119 X&
01120 sc_proxy<X>::operator >>= ( int n )
01121 {
01122 X& x = back_cast();
01123 if( n < 0 ) {
01124 char msg[BUFSIZ];
01125 std::sprintf( msg,
01126 "right shift operation is only allowed with positive "
01127 "shift values, shift value = %d", n );
01128 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
01129 }
01130 if( n >= x.length() ) {
01131 extend_sign_w_( x, 0, false );
01132
01133 return x;
01134 }
01135 int sz = x.size();
01136 int wn = n / SC_DIGIT_SIZE;
01137 int bn = n % SC_DIGIT_SIZE;
01138 if( wn != 0 ) {
01139
01140 int i = 0;
01141 for( ; i < (sz - wn); ++ i ) {
01142 set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) );
01143 }
01144 for( ; i < sz; ++ i ) {
01145 set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
01146 }
01147 }
01148 if( bn != 0 ) {
01149
01150 for( int i = 0; i < (sz - 1); ++ i ) {
01151 sc_digit x_dw, x_cw;
01152 get_words_( x, i, x_dw, x_cw );
01153 x_dw >>= bn;
01154 x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn);
01155 x_cw >>= bn;
01156 x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn);
01157 set_words_( x, i, x_dw, x_cw );
01158 }
01159 sc_digit x_dw, x_cw;
01160 get_words_( x, sz - 1, x_dw, x_cw );
01161 x_dw >>= bn;
01162 x_cw >>= bn;
01163 set_words_( x, sz - 1, x_dw, x_cw );
01164 }
01165 x.clean_tail();
01166 return x;
01167 }
01168
01169
01170
01171
01172 template <class X>
01173 inline
01174 const sc_lv_base
01175 lrotate( const sc_proxy<X>& x, int n );
01176
01177
01178
01179
01180 template <class X>
01181 inline
01182 const sc_lv_base
01183 rrotate( const sc_proxy<X>& x, int n );
01184
01185
01186
01187
01188 template <class X>
01189 inline
01190 X&
01191 sc_proxy<X>::reverse()
01192 {
01193 X& x = back_cast();
01194 int len = x.length();
01195 int half_len = len / 2;
01196 for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) {
01197 sc_logic_value_t t = x.get_bit( i );
01198 x.set_bit( i, x.get_bit( j ) );
01199 x.set_bit( j, t );
01200 }
01201 return x;
01202 }
01203
01204 template <class X>
01205 inline
01206 const sc_lv_base
01207 reverse( const sc_proxy<X>& a );
01208
01209
01210
01211
01212 template <class X>
01213 inline
01214 sc_logic_value_t
01215 sc_proxy<X>::and_reduce() const
01216 {
01217 const X& x = back_cast();
01218 sc_logic_value_t result = sc_logic_value_t( 1 );
01219 int len = x.length();
01220 for( int i = 0; i < len; ++ i ) {
01221 result = sc_logic::and_table[result][x.get_bit( i )];
01222 }
01223 return result;
01224 }
01225
01226 template <class X>
01227 inline
01228 sc_logic_value_t
01229 sc_proxy<X>::or_reduce() const
01230 {
01231 const X& x = back_cast();
01232 sc_logic_value_t result = sc_logic_value_t( 0 );
01233 int len = x.length();
01234 for( int i = 0; i < len; ++ i ) {
01235 result = sc_logic::or_table[result][x.get_bit( i )];
01236 }
01237 return result;
01238 }
01239
01240 template <class X>
01241 inline
01242 sc_logic_value_t
01243 sc_proxy<X>::xor_reduce() const
01244 {
01245 const X& x = back_cast();
01246 sc_logic_value_t result = sc_logic_value_t( 0 );
01247 int len = x.length();
01248 for( int i = 0; i < len; ++ i ) {
01249 result = sc_logic::xor_table[result][x.get_bit( i )];
01250 }
01251 return result;
01252 }
01253
01254
01255
01256
01257 template <class X, class Y>
01258 inline
01259 bool
01260 operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
01261 {
01262 return !( px == py );
01263 }
01264
01265
01266 #define DEFN_REL_OP_T(tp) \
01267 template <class X> \
01268 inline \
01269 bool \
01270 operator == ( tp b, const sc_proxy<X>& px ) \
01271 { \
01272 return ( px == b ); \
01273 } \
01274 \
01275 template <class X> \
01276 inline \
01277 bool \
01278 operator != ( const sc_proxy<X>& px, tp b ) \
01279 { \
01280 return !( px == b ); \
01281 } \
01282 \
01283 template <class X> \
01284 inline \
01285 bool \
01286 operator != ( tp b, const sc_proxy<X>& px ) \
01287 { \
01288 return !( px == b ); \
01289 }
01290
01291 DEFN_REL_OP_T(const char*)
01292 DEFN_REL_OP_T(const bool*)
01293 DEFN_REL_OP_T(const sc_logic*)
01294 DEFN_REL_OP_T(const sc_unsigned&)
01295 DEFN_REL_OP_T(const sc_signed&)
01296 DEFN_REL_OP_T(const sc_uint_base&)
01297 DEFN_REL_OP_T(const sc_int_base&)
01298 DEFN_REL_OP_T(unsigned long)
01299 DEFN_REL_OP_T(long)
01300 DEFN_REL_OP_T(unsigned int)
01301 DEFN_REL_OP_T(int)
01302 DEFN_REL_OP_T(uint64)
01303 DEFN_REL_OP_T(int64)
01304
01305 #undef DEFN_REL_OP_T
01306
01307
01308
01309
01310 template <class X>
01311 inline
01312 const std::string
01313 sc_proxy<X>::to_string() const
01314 {
01315 const X& x = back_cast();
01316 int len = x.length();
01317 std::string s;
01318 for( int i = 0; i < len; ++ i ) {
01319 s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )];
01320 }
01321 return s;
01322 }
01323
01324 template <class X>
01325 inline
01326 const std::string
01327 sc_proxy<X>::to_string( sc_numrep numrep ) const
01328 {
01329 return convert_to_fmt( to_string(), numrep, true );
01330 }
01331
01332 template <class X>
01333 inline
01334 const std::string
01335 sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const
01336 {
01337 return convert_to_fmt( to_string(), numrep, w_prefix );
01338 }
01339
01340
01341
01342
01343 template <class X>
01344 inline
01345 void
01346 sc_proxy<X>::scan( ::std::istream& is )
01347 {
01348 std::string s;
01349 is >> s;
01350 back_cast() = s.c_str();
01351 }
01352
01353
01354 template <class X>
01355 inline
01356 void
01357 sc_proxy<X>::check_bounds( int n ) const
01358 {
01359 if( n < 0 || n >= back_cast().length() ) {
01360 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
01361 }
01362 }
01363
01364 template <class X>
01365 inline
01366 void
01367 sc_proxy<X>::check_wbounds( int n ) const
01368 {
01369 if( n < 0 || n >= back_cast().size() ) {
01370 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
01371 }
01372 }
01373
01374
01375 template <class X>
01376 inline
01377 sc_digit
01378 sc_proxy<X>::to_anything_unsigned() const
01379 {
01380
01381
01382 const X& x = back_cast();
01383 int len = x.length();
01384 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
01385 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
01386 }
01387 sc_digit w = x.get_word( 0 );
01388 if( len >= SC_DIGIT_SIZE ) {
01389 return w;
01390 }
01391 return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
01392 }
01393
01394 template <class X>
01395 inline
01396 uint64
01397 sc_proxy<X>::to_uint64() const
01398 {
01399
01400
01401 const X& x = back_cast();
01402 int len = x.length();
01403 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
01404 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
01405 }
01406 uint64 w = x.get_word( 0 );
01407 if( len > SC_DIGIT_SIZE )
01408 {
01409 if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) {
01410 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
01411 }
01412 uint64 w1 = x.get_word( 1 );
01413 w = w | (w1 << SC_DIGIT_SIZE);
01414 return w;
01415 }
01416 else if( len == SC_DIGIT_SIZE )
01417 {
01418 return w;
01419 }
01420 else
01421 {
01422 return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
01423 }
01424 }
01425
01426 template <class X>
01427 inline
01428 int64
01429 sc_proxy<X>::to_anything_signed() const
01430 {
01431
01432
01433 const X& x = back_cast();
01434 int len = x.length();
01435 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
01436 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
01437 }
01438 int64 w = x.get_word( 0 );
01439 uint64 zero = 0;
01440 if( len >= 64 ) {
01441 return (uint64) w;
01442 }
01443 sc_logic_value_t sgn = x.get_bit( len - 1 );
01444 if( sgn == 0 ) {
01445 return ( w & (~zero >> (64 - len)) );
01446 } else {
01447 return ( w | (~zero << len) );
01448 }
01449 }
01450
01451
01452
01453
01454
01455
01456 template <class X>
01457 inline
01458 sc_logic_value_t
01459 and_reduce( const sc_proxy<X>& a )
01460 {
01461 return a.and_reduce();
01462 }
01463
01464 template <class X>
01465 inline
01466 sc_logic_value_t
01467 nand_reduce( const sc_proxy<X>& a )
01468 {
01469 return a.nand_reduce();
01470 }
01471
01472 template <class X>
01473 inline
01474 sc_logic_value_t
01475 or_reduce( const sc_proxy<X>& a )
01476 {
01477 return a.or_reduce();
01478 }
01479
01480 template <class X>
01481 inline
01482 sc_logic_value_t
01483 nor_reduce( const sc_proxy<X>& a )
01484 {
01485 return a.nor_reduce();
01486 }
01487
01488 template <class X>
01489 inline
01490 sc_logic_value_t
01491 xor_reduce( const sc_proxy<X>& a )
01492 {
01493 return a.xor_reduce();
01494 }
01495
01496 template <class X>
01497 inline
01498 sc_logic_value_t
01499 xnor_reduce( const sc_proxy<X>& a )
01500 {
01501 return a.xnor_reduce();
01502 }
01503
01504
01505
01506
01507 template <class X>
01508 inline
01509 ::std::ostream&
01510 operator << ( ::std::ostream& os, const sc_proxy<X>& a )
01511 {
01512 a.print( os );
01513 return os;
01514 }
01515
01516 template <class X>
01517 inline
01518 ::std::istream&
01519 operator >> ( ::std::istream& is, sc_proxy<X>& a )
01520 {
01521 a.scan( is );
01522 return is;
01523 }
01524
01525 }
01526
01527
01528 #endif