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

sc_lv_base.h

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