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

Generated on Wed Apr 25 13:53:26 2007 for SystemC by  doxygen 1.5.1