| /***************************************************************************** |
| |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or |
| more contributor license agreements. See the NOTICE file distributed |
| with this work for additional information regarding copyright ownership. |
| Accellera licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| implied. See the License for the specific language governing |
| permissions and limitations under the License. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| sc_proxy.h -- Proxy base class for vector data types. |
| |
| This class is created for several purposes: |
| 1) hiding operators from the global namespace that would be |
| otherwise found by Koenig lookup |
| 2) avoiding repeating the same operations in every class |
| including proxies that could also be achieved by common |
| base class, but this method allows |
| 3) improve performance by using non-virtual functions |
| |
| Original Author: Gene Bushuyev, Synopsys, Inc. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and |
| changes you are making here. |
| |
| Name, Affiliation, Date: |
| Description of Modification: |
| |
| *****************************************************************************/ |
| |
| // $Log: sc_proxy.h,v $ |
| // Revision 1.3 2010/12/07 20:09:07 acg |
| // Andy Goodrich: Fix for returning enough data |
| // |
| // Revision 1.2 2009/02/28 00:26:14 acg |
| // Andy Goodrich: bug fixes. |
| // |
| // Revision 1.1.1.1 2006/12/15 20:31:36 acg |
| // SystemC 2.2 |
| // |
| // Revision 1.3 2006/01/13 18:53:53 acg |
| // Andy Goodrich: added $Log command so that CVS comments are reproduced in |
| // the source. |
| // |
| |
| #ifndef SC_PROXY_H |
| #define SC_PROXY_H |
| |
| |
| #include "sysc/kernel/sc_cmnhdr.h" |
| #include "sysc/utils/sc_iostream.h" |
| #include "sysc/datatypes/int/sc_signed.h" |
| #include "sysc/datatypes/int/sc_unsigned.h" |
| #include "sysc/datatypes/int/sc_int_base.h" |
| #include "sysc/datatypes/int/sc_uint_base.h" |
| #include "sysc/datatypes/bit/sc_bit.h" |
| #include "sysc/datatypes/bit/sc_bit_ids.h" |
| #include "sysc/datatypes/bit/sc_logic.h" |
| #include "sysc/kernel/sc_macros.h" |
| |
| |
| namespace sc_dt |
| { |
| |
| // classes defined in this module |
| template <class X> class sc_proxy; |
| |
| // forward class declarations |
| class sc_bv_base; |
| class sc_lv_base; |
| template <class X> class sc_bitref_r; |
| template <class X> class sc_bitref; |
| template <class X> class sc_subref_r; |
| template <class X> class sc_subref; |
| template <class X, class Y> class sc_concref_r; |
| template <class X, class Y> class sc_concref; |
| |
| |
| const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit ); |
| |
| const sc_digit SC_DIGIT_ZERO = (sc_digit)0; |
| const sc_digit SC_DIGIT_ONE = (sc_digit)1; |
| const sc_digit SC_DIGIT_TWO = (sc_digit)2; |
| |
| |
| // assignment functions; forward declarations |
| |
| template <class X, class Y> |
| inline |
| void |
| assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| // Vector types that are not derived from sc_proxy must have a length() |
| // function and an operator []. |
| |
| template <class X, class T> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const T& a ); |
| |
| |
| // other functions; forward declarations |
| |
| const std::string convert_to_bin( const char* s ); |
| const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool ); |
| |
| // ---------------------------------------------------------------------------- |
| // CLASS TEMPLATE : sc_proxy_traits |
| // |
| // Template traits helper to select the correct bit/value/vector_types for |
| // sc_proxy-based vector classes. |
| // |
| // All types derived from/based on a bit-vector contain typedef to a plain bool, |
| // all others point to the sc_logic_value_t/sc_logic/sc_lv_base types. |
| // ---------------------------------------------------------------------------- |
| |
| template<typename X> struct sc_proxy_traits; |
| |
| template<> struct sc_proxy_traits<sc_bv_base> |
| { |
| typedef sc_proxy_traits<sc_bv_base> traits_type; |
| typedef bool value_type; |
| typedef bool bit_type; |
| typedef sc_bv_base vector_type; |
| typedef traits_type type; |
| }; |
| |
| template<> struct sc_proxy_traits<sc_lv_base> |
| { |
| typedef sc_proxy_traits<sc_lv_base> traits_type; |
| typedef sc_logic_value_t value_type; |
| typedef sc_logic bit_type; |
| typedef sc_lv_base vector_type; |
| typedef traits_type type; |
| }; |
| |
| |
| template<typename X> struct sc_proxy_traits<sc_bitref_r<X> > |
| : sc_proxy_traits<X> {}; |
| |
| template<typename X> struct sc_proxy_traits<sc_bitref<X> > |
| : sc_proxy_traits<X> {}; |
| |
| |
| template<typename X> struct sc_proxy_traits<sc_subref_r<X> > |
| : sc_proxy_traits<X> {}; |
| |
| template<typename X> struct sc_proxy_traits<sc_subref<X> > |
| : sc_proxy_traits<X> {}; |
| |
| |
| template<typename X> struct sc_proxy_traits<sc_proxy<X> > |
| : sc_proxy_traits<X> {}; |
| |
| |
| template< typename X, typename Y > struct sc_mixed_proxy_traits_helper |
| : sc_proxy_traits<sc_lv_base> {}; // logic vector by default |
| |
| template<typename X> struct sc_mixed_proxy_traits_helper<X,X> |
| : X {}; |
| |
| |
| template<typename X, typename Y> struct sc_proxy_traits< sc_concref_r<X,Y> > |
| : sc_mixed_proxy_traits_helper< typename X::traits_type::type |
| , typename Y::traits_type::type > |
| {}; |
| |
| template<typename X, typename Y> struct sc_proxy_traits<sc_concref<X,Y> > |
| : sc_mixed_proxy_traits_helper< typename X::traits_type::type |
| , typename Y::traits_type::type > |
| {}; |
| |
| |
| // ---------------------------------------------------------------------------- |
| // CLASS TEMPLATE : sc_proxy |
| // |
| // Base class template for bit/logic vector classes. |
| // (Barton/Nackmann implementation) |
| // ---------------------------------------------------------------------------- |
| |
| template <class X> |
| class sc_proxy // #### : public sc_value_base |
| { |
| public: |
| typedef typename sc_proxy_traits<X>::type traits_type; |
| typedef typename traits_type::bit_type bit_type; |
| |
| // virtual destructor |
| |
| virtual ~sc_proxy() {} |
| |
| |
| // casts |
| |
| X& back_cast() |
| { return SCAST<X&>( *this ); } |
| |
| const X& back_cast() const |
| { return SCAST<const X&>( *this ); } |
| |
| |
| // assignment operators |
| |
| template <class Y> |
| X& assign_( const sc_proxy<Y>& a ) |
| { assign_p_( *this, a ); return back_cast(); } |
| |
| X& assign_( const char* a ); |
| X& assign_( const bool* a ); |
| X& assign_( const sc_logic* a ); |
| |
| X& assign_( const sc_unsigned& a ) |
| { assign_v_( *this, a ); return back_cast(); } |
| |
| X& assign_( const sc_signed& a ) |
| { assign_v_( *this, a ); return back_cast(); } |
| |
| X& assign_( const sc_uint_base& a ) |
| { return assign_( (uint64) a ); } |
| |
| X& assign_( const sc_int_base& a ) |
| { return assign_( (int64) a ); } |
| |
| X& assign_( unsigned int a ); |
| X& assign_( int a ); |
| |
| X& assign_( unsigned long a ); |
| |
| X& assign_( long a ); |
| |
| X& assign_( uint64 a ); |
| X& assign_( int64 a ); |
| |
| |
| // bitwise operators and functions |
| |
| // bitwise complement |
| |
| X& b_not(); |
| |
| const sc_lv_base operator ~ () const; |
| |
| |
| // bitwise and |
| |
| X& operator &= ( const char* b ); |
| X& operator &= ( const bool* b ); |
| X& operator &= ( const sc_logic* b ); |
| X& operator &= ( const sc_unsigned& b ); |
| X& operator &= ( const sc_signed& b ); |
| |
| X& operator &= ( const sc_uint_base& b ) |
| { return operator &= ( (uint64) b ); } |
| |
| X& operator &= ( const sc_int_base& b ) |
| { return operator &= ( (int64) b ); } |
| |
| X& operator &= ( unsigned long b ); |
| X& operator &= ( long b ); |
| |
| X& operator &= ( unsigned int b ) |
| { return operator &= ( (unsigned long) b ); } |
| |
| X& operator &= ( int b ) |
| { return operator &= ( (long) b ); } |
| |
| X& operator &= ( uint64 b ); |
| X& operator &= ( int64 b ); |
| |
| |
| const sc_lv_base operator & ( const char* b ) const; |
| const sc_lv_base operator & ( const bool* b ) const; |
| const sc_lv_base operator & ( const sc_logic* b ) const; |
| const sc_lv_base operator & ( const sc_unsigned& b ) const; |
| const sc_lv_base operator & ( const sc_signed& b ) const; |
| const sc_lv_base operator & ( const sc_uint_base& b ) const; |
| const sc_lv_base operator & ( const sc_int_base& b ) const; |
| const sc_lv_base operator & ( unsigned long b ) const; |
| const sc_lv_base operator & ( long b ) const; |
| const sc_lv_base operator & ( unsigned int b ) const; |
| const sc_lv_base operator & ( int b ) const; |
| const sc_lv_base operator & ( uint64 b ) const; |
| const sc_lv_base operator & ( int64 b ) const; |
| |
| |
| // bitwise or |
| |
| X& operator |= ( const char* b ); |
| X& operator |= ( const bool* b ); |
| X& operator |= ( const sc_logic* b ); |
| X& operator |= ( const sc_unsigned& b ); |
| X& operator |= ( const sc_signed& b ); |
| |
| X& operator |= ( const sc_uint_base& b ) |
| { return operator |= ( (uint64) b ); } |
| |
| X& operator |= ( const sc_int_base& b ) |
| { return operator |= ( (int64) b ); } |
| |
| X& operator |= ( unsigned long b ); |
| X& operator |= ( long b ); |
| |
| X& operator |= ( unsigned int b ) |
| { return operator |= ( (unsigned long) b ); } |
| |
| X& operator |= ( int b ) |
| { return operator |= ( (long) b ); } |
| |
| X& operator |= ( uint64 b ); |
| X& operator |= ( int64 b ); |
| |
| |
| const sc_lv_base operator | ( const char* b ) const; |
| const sc_lv_base operator | ( const bool* b ) const; |
| const sc_lv_base operator | ( const sc_logic* b ) const; |
| const sc_lv_base operator | ( const sc_unsigned& b ) const; |
| const sc_lv_base operator | ( const sc_signed& b ) const; |
| const sc_lv_base operator | ( const sc_uint_base& b ) const; |
| const sc_lv_base operator | ( const sc_int_base& b ) const; |
| const sc_lv_base operator | ( unsigned long b ) const; |
| const sc_lv_base operator | ( long b ) const; |
| const sc_lv_base operator | ( unsigned int b ) const; |
| const sc_lv_base operator | ( int b ) const; |
| const sc_lv_base operator | ( uint64 b ) const; |
| const sc_lv_base operator | ( int64 b ) const; |
| |
| |
| // bitwise xor |
| |
| X& operator ^= ( const char* b ); |
| X& operator ^= ( const bool* b ); |
| X& operator ^= ( const sc_logic* b ); |
| X& operator ^= ( const sc_unsigned& b ); |
| X& operator ^= ( const sc_signed& b ); |
| |
| X& operator ^= ( const sc_uint_base& b ) |
| { return operator ^= ( (uint64) b ); } |
| |
| X& operator ^= ( const sc_int_base& b ) |
| { return operator ^= ( (int64) b ); } |
| |
| X& operator ^= ( unsigned long b ); |
| X& operator ^= ( long b ); |
| |
| X& operator ^= ( unsigned int b ) |
| { return operator ^= ( (unsigned long) b ); } |
| |
| X& operator ^= ( int b ) |
| { return operator ^= ( (long) b ); } |
| |
| X& operator ^= ( uint64 b ); |
| X& operator ^= ( int64 b ); |
| |
| |
| const sc_lv_base operator ^ ( const char* b ) const; |
| const sc_lv_base operator ^ ( const bool* b ) const; |
| const sc_lv_base operator ^ ( const sc_logic* b ) const; |
| const sc_lv_base operator ^ ( const sc_unsigned& b ) const; |
| const sc_lv_base operator ^ ( const sc_signed& b ) const; |
| const sc_lv_base operator ^ ( const sc_uint_base& b ) const; |
| const sc_lv_base operator ^ ( const sc_int_base& b ) const; |
| const sc_lv_base operator ^ ( unsigned long b ) const; |
| const sc_lv_base operator ^ ( long b ) const; |
| const sc_lv_base operator ^ ( unsigned int b ) const; |
| const sc_lv_base operator ^ ( int b ) const; |
| const sc_lv_base operator ^ ( uint64 b ) const; |
| const sc_lv_base operator ^ ( int64 b ) const; |
| |
| |
| // bitwise left shift |
| |
| X& operator <<= ( int n ); |
| |
| const sc_lv_base operator << ( int n ) const; |
| |
| |
| // bitwise right shift |
| |
| X& operator >>= ( int n ); |
| |
| const sc_lv_base operator >> ( int n ) const; |
| |
| |
| // bitwise left rotate |
| |
| X& lrotate( int n ); |
| |
| |
| // bitwise right rotate |
| |
| X& rrotate( int n ); |
| |
| |
| // bitwise reverse |
| |
| X& reverse(); |
| |
| |
| // bit selection |
| |
| sc_bitref<X> operator [] ( int i ) |
| { return sc_bitref<X>( back_cast(), i ); } |
| |
| sc_bitref_r<X> operator [] ( int i ) const |
| { return sc_bitref_r<X>( back_cast(), i ); } |
| |
| sc_bitref<X> bit( int i ) |
| { return sc_bitref<X>( back_cast(), i ); } |
| |
| sc_bitref_r<X> bit( int i ) const |
| { return sc_bitref_r<X>( back_cast(), i ); } |
| |
| |
| // part selection |
| |
| sc_subref<X> operator () ( int hi, int lo ) |
| { return sc_subref<X>( back_cast(), hi, lo ); } |
| |
| sc_subref_r<X> operator () ( int hi, int lo ) const |
| { return sc_subref_r<X>( back_cast(), hi, lo ); } |
| |
| sc_subref<X> range( int hi, int lo ) |
| { return sc_subref<X>( back_cast(), hi, lo ); } |
| |
| sc_subref_r<X> range( int hi, int lo ) const |
| { return sc_subref_r<X>( back_cast(), hi, lo ); } |
| |
| |
| // reduce functions |
| |
| sc_logic_value_t and_reduce() const; |
| |
| sc_logic_value_t nand_reduce() const |
| { return sc_logic::not_table[and_reduce()]; } |
| |
| sc_logic_value_t or_reduce() const; |
| |
| sc_logic_value_t nor_reduce() const |
| { return sc_logic::not_table[or_reduce()]; } |
| |
| sc_logic_value_t xor_reduce() const; |
| |
| sc_logic_value_t xnor_reduce() const |
| { return sc_logic::not_table[xor_reduce()]; } |
| |
| |
| // relational operators |
| |
| bool operator == ( const char* b ) const; |
| bool operator == ( const bool* b ) const; |
| bool operator == ( const sc_logic* b ) const; |
| bool operator == ( const sc_unsigned& b ) const; |
| bool operator == ( const sc_signed& b ) const; |
| bool operator == ( const sc_uint_base& b ) const; |
| bool operator == ( const sc_int_base& b ) const; |
| bool operator == ( unsigned long b ) const; |
| bool operator == ( long b ) const; |
| bool operator == ( unsigned int b ) const; |
| bool operator == ( int b ) const; |
| bool operator == ( uint64 b ) const; |
| bool operator == ( int64 b ) const; |
| |
| |
| // explicit conversions to character string |
| |
| const std::string to_string() const; |
| const std::string to_string( sc_numrep ) const; |
| const std::string to_string( sc_numrep, bool ) const; |
| |
| |
| // explicit conversions |
| |
| inline int64 to_int64() const |
| { return to_anything_signed(); } |
| inline uint64 to_uint64() const; |
| int to_int() const |
| { return (int)to_anything_signed(); } |
| |
| unsigned int to_uint() const |
| { return (unsigned int)to_anything_unsigned(); } |
| |
| long to_long() const |
| { return (long)to_anything_signed(); } |
| |
| unsigned long to_ulong() const |
| { return (unsigned long)to_anything_unsigned(); } |
| |
| #ifdef SC_DT_DEPRECATED |
| |
| int to_signed() const |
| { return to_int(); } |
| |
| sc_digit to_unsigned() const |
| { return to_uint(); } |
| |
| #endif |
| |
| |
| // other methods |
| |
| void print( ::std::ostream& os = ::std::cout ) const |
| { |
| // the test below will force printing in binary if decimal is |
| // specified. |
| if ( sc_io_base(os, SC_DEC) == SC_DEC ) |
| os << to_string(); |
| else |
| os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os)); |
| } |
| |
| void scan( ::std::istream& is = ::std::cin ); |
| |
| protected: |
| |
| void check_bounds( int n ) const; // check if bit n accessible |
| void check_wbounds( int n ) const; // check if word n accessible |
| |
| sc_digit to_anything_unsigned() const; |
| int64 to_anything_signed() const; |
| }; |
| |
| |
| // ---------------------------------------------------------------------------- |
| |
| // bitwise operators and functions |
| |
| // bitwise and |
| |
| template <class X, class Y> |
| inline |
| X& |
| operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| template <class X, class Y> |
| inline |
| const sc_lv_base |
| operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| #define DECL_BITWISE_AND_OP_T(tp) \ |
| template <class X> \ |
| inline \ |
| const sc_lv_base \ |
| operator & ( tp b, const sc_proxy<X>& px ); |
| |
| DECL_BITWISE_AND_OP_T(const char*) |
| DECL_BITWISE_AND_OP_T(const bool*) |
| DECL_BITWISE_AND_OP_T(const sc_logic*) |
| DECL_BITWISE_AND_OP_T(const sc_unsigned&) |
| DECL_BITWISE_AND_OP_T(const sc_signed&) |
| DECL_BITWISE_AND_OP_T(const sc_uint_base&) |
| DECL_BITWISE_AND_OP_T(const sc_int_base&) |
| DECL_BITWISE_AND_OP_T(unsigned long) |
| DECL_BITWISE_AND_OP_T(long) |
| DECL_BITWISE_AND_OP_T(unsigned int) |
| DECL_BITWISE_AND_OP_T(int) |
| DECL_BITWISE_AND_OP_T(uint64) |
| DECL_BITWISE_AND_OP_T(int64) |
| |
| #undef DECL_BITWISE_AND_OP_T |
| |
| |
| // bitwise or |
| |
| template <class X, class Y> |
| inline |
| X& |
| operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| template <class X, class Y> |
| inline |
| const sc_lv_base |
| operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| #define DECL_BITWISE_OR_OP_T(tp) \ |
| template <class X> \ |
| inline \ |
| const sc_lv_base \ |
| operator | ( tp a, const sc_proxy<X>& px ); |
| |
| DECL_BITWISE_OR_OP_T(const char*) |
| DECL_BITWISE_OR_OP_T(const bool*) |
| DECL_BITWISE_OR_OP_T(const sc_logic*) |
| DECL_BITWISE_OR_OP_T(const sc_unsigned&) |
| DECL_BITWISE_OR_OP_T(const sc_signed&) |
| DECL_BITWISE_OR_OP_T(const sc_uint_base&) |
| DECL_BITWISE_OR_OP_T(const sc_int_base&) |
| DECL_BITWISE_OR_OP_T(unsigned long) |
| DECL_BITWISE_OR_OP_T(long) |
| DECL_BITWISE_OR_OP_T(unsigned int) |
| DECL_BITWISE_OR_OP_T(int) |
| DECL_BITWISE_OR_OP_T(uint64) |
| DECL_BITWISE_OR_OP_T(int64) |
| |
| #undef DECL_BITWISE_OR_OP_T |
| |
| |
| // bitwise xor |
| |
| template <class X, class Y> |
| inline |
| X& |
| operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| template <class X, class Y> |
| inline |
| const sc_lv_base |
| operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| #define DECL_BITWISE_XOR_OP_T(tp) \ |
| template <class X> \ |
| inline \ |
| const sc_lv_base \ |
| operator ^ ( tp a, const sc_proxy<X>& px ); |
| |
| DECL_BITWISE_XOR_OP_T(const char*) |
| DECL_BITWISE_XOR_OP_T(const bool*) |
| DECL_BITWISE_XOR_OP_T(const sc_logic*) |
| DECL_BITWISE_XOR_OP_T(const sc_unsigned&) |
| DECL_BITWISE_XOR_OP_T(const sc_signed&) |
| DECL_BITWISE_XOR_OP_T(const sc_uint_base&) |
| DECL_BITWISE_XOR_OP_T(const sc_int_base&) |
| DECL_BITWISE_XOR_OP_T(unsigned long) |
| DECL_BITWISE_XOR_OP_T(long) |
| DECL_BITWISE_XOR_OP_T(unsigned int) |
| DECL_BITWISE_XOR_OP_T(int) |
| DECL_BITWISE_XOR_OP_T(uint64) |
| DECL_BITWISE_XOR_OP_T(int64) |
| |
| #undef DECL_BITWISE_XOR_OP_T |
| |
| |
| // relational operators |
| |
| template <class X, class Y> |
| inline |
| bool |
| operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| template <class X, class Y> |
| inline |
| bool |
| operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); |
| |
| |
| #define DECL_REL_OP_T(tp) \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator == ( tp b, const sc_proxy<X>& px ); \ |
| \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator != ( const sc_proxy<X>& px, tp b ); \ |
| \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator != ( tp b, const sc_proxy<X>& px ); |
| |
| DECL_REL_OP_T(const char*) |
| DECL_REL_OP_T(const bool*) |
| DECL_REL_OP_T(const sc_logic*) |
| DECL_REL_OP_T(const sc_unsigned&) |
| DECL_REL_OP_T(const sc_signed&) |
| DECL_REL_OP_T(const sc_uint_base&) |
| DECL_REL_OP_T(const sc_int_base&) |
| DECL_REL_OP_T(unsigned long) |
| DECL_REL_OP_T(long) |
| DECL_REL_OP_T(unsigned int) |
| DECL_REL_OP_T(int) |
| DECL_REL_OP_T(uint64) |
| DECL_REL_OP_T(int64) |
| |
| #undef DECL_REL_OP_T |
| |
| |
| // l-value concatenation |
| |
| // Due to the fact that temporary objects cannot be passed to non-const |
| // references, we have to enumerate, use call by value, and use dynamic |
| // memory allocation (and deallocation). |
| |
| |
| // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII |
| |
| template <class X> |
| inline |
| void |
| get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw ) |
| { |
| x_dw = x.get_word( wi ); |
| x_cw = x.get_cword( wi ); |
| } |
| |
| template <class X> |
| inline |
| void |
| set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw ) |
| { |
| x.set_word( wi, x_dw ); |
| x.set_cword( wi, x_cw ); |
| } |
| |
| template <class X> |
| inline |
| void |
| extend_sign_w_( X& x, int wi, bool sign ) |
| { |
| int sz = x.size(); |
| unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO); |
| for( int i = wi; i < sz; ++ i ) { |
| set_words_( x, i, sgn, SC_DIGIT_ZERO ); |
| } |
| } |
| |
| |
| // assignment functions |
| |
| template <class X, class Y> |
| inline |
| void |
| assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ) |
| { |
| if( (void*) &px != (void*) &py ) { |
| X& x = px.back_cast(); |
| const Y& y = py.back_cast(); |
| int sz = x.size(); |
| int min_sz = sc_min( sz, y.size() ); |
| int i = 0; |
| for( ; i < min_sz; ++ i ) { |
| set_words_( x, i, y.get_word( i ), y.get_cword( i ) ); |
| } |
| // extend with zeros |
| extend_sign_w_( x, i, false ); |
| x.clean_tail(); |
| } |
| } |
| |
| // Vector types that are not derived from sc_proxy, sc_int_base, |
| // sc_uint_base, sc_signed, or sc_unsigned, must have a length() |
| // function and an operator []. The vector argument type must support |
| // accessing bits that are beyond the msb. The vector argument type |
| // decides what to do there (e.g. sign extension or zero padding). |
| |
| template <class X, class T> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const T& a ) |
| { |
| X& x = px.back_cast(); |
| int i; |
| int len_x = x.length(); |
| int len_a = a.length(); |
| if ( len_a > len_x ) len_a = len_x; |
| for( i = 0 ; i < len_a; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); |
| } |
| for( ; i < len_x; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( false ) ); |
| } |
| } |
| |
| template <class X> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const sc_int_base& a ) |
| { |
| X& x = px.back_cast(); |
| int i; |
| bool sign = a < 0; |
| int len_x = x.length(); |
| int len_a = a.length(); |
| if ( len_a > len_x ) len_a = len_x; |
| for( i = 0 ; i < len_a; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); |
| } |
| for( ; i < len_x; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( sign ) ); |
| } |
| } |
| |
| template <class X> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const sc_signed& a ) |
| { |
| X& x = px.back_cast(); |
| int i; |
| bool sign = a < 0; |
| int len_x = x.length(); |
| int len_a = a.length(); |
| if ( len_a > len_x ) len_a = len_x; |
| for( i = 0 ; i < len_a; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); |
| } |
| for( ; i < len_x; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( sign ) ); |
| } |
| } |
| |
| template <class X> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const sc_uint_base& a ) |
| { |
| X& x = px.back_cast(); |
| int i; |
| int len_x = x.length(); |
| int len_a = a.length(); |
| if ( len_a > len_x ) len_a = len_x; |
| for( i = 0 ; i < len_a; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); |
| } |
| for( ; i < len_x; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( false ) ); |
| } |
| } |
| |
| template <class X> |
| inline |
| void |
| assign_v_( sc_proxy<X>& px, const sc_unsigned& a ) |
| { |
| X& x = px.back_cast(); |
| int i; |
| int len_x = x.length(); |
| int len_a = a.length(); |
| if ( len_a > len_x ) len_a = len_x; |
| for( i = 0 ; i < len_a; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); |
| } |
| for( ; i < len_x; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( false ) ); |
| } |
| } |
| |
| |
| // assignment operators |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( const char* a ) |
| { |
| X& x = back_cast(); |
| std::string s = convert_to_bin( a ); |
| int len = x.length(); |
| int s_len = s.length() - 1; |
| int min_len = sc_min( len, s_len ); |
| int i = 0; |
| for( ; i < min_len; ++ i ) { |
| char c = s[s_len - i - 1]; |
| x.set_bit( i, sc_logic::char_to_logic[(int)c] ); |
| } |
| // if formatted, fill the rest with sign(s), otherwise fill with zeros |
| sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' ) |
| : sc_logic_value_t( 0 )); |
| for( ; i < len; ++ i ) { |
| x.set_bit( i, fill ); |
| } |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( const bool* a ) |
| { |
| // the length of 'a' must be larger than or equal to the length of 'this' |
| X& x = back_cast(); |
| int len = x.length(); |
| for( int i = 0; i < len; ++ i ) { |
| x.set_bit( i, sc_logic_value_t( a[i] ) ); |
| } |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( const sc_logic* a ) |
| { |
| // the length of 'a' must be larger than or equal to the length of 'this' |
| X& x = back_cast(); |
| int len = x.length(); |
| for( int i = 0; i < len; ++ i ) { |
| x.set_bit( i, a[i].value() ); |
| } |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( unsigned int a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); |
| // extend with zeros |
| extend_sign_w_( x, 1, false ); |
| x.clean_tail(); |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( int a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); |
| // extend with sign(a) |
| extend_sign_w_( x, 1, (a < 0) ); |
| x.clean_tail(); |
| return x; |
| } |
| |
| #if defined(SC_LONG_64) |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( unsigned long a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); |
| if( x.size() > 1 ) { |
| set_words_( x, 1, |
| ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), |
| SC_DIGIT_ZERO ); |
| // extend with zeros |
| extend_sign_w_( x, 2, false ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( long a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); |
| if( x.size() > 1 ) { |
| set_words_( x, 1, |
| ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), |
| SC_DIGIT_ZERO ); |
| // extend with sign(a) |
| extend_sign_w_( x, 2, (a < 0) ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| #else |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( unsigned long a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); |
| // extend with zeros |
| extend_sign_w_( x, 1, false ); |
| x.clean_tail(); |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( long a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); |
| // extend with sign(a) |
| extend_sign_w_( x, 1, (a < 0) ); |
| x.clean_tail(); |
| return x; |
| } |
| #endif |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( uint64 a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); |
| if( x.size() > 1 ) { |
| set_words_( x, 1, |
| ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), |
| SC_DIGIT_ZERO ); |
| // extend with zeros |
| extend_sign_w_( x, 2, false ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::assign_( int64 a ) |
| { |
| X& x = back_cast(); |
| set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); |
| if( x.size() > 1 ) { |
| set_words_( x, 1, |
| ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), |
| SC_DIGIT_ZERO ); |
| // extend with sign(a) |
| extend_sign_w_( x, 2, (a < 0) ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| |
| // bitwise operators and functions |
| |
| // bitwise complement |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::b_not() |
| { |
| X& x = back_cast(); |
| int sz = x.size(); |
| for( int i = 0; i < sz; ++ i ) { |
| sc_digit x_dw, x_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| x.set_word( i, x_cw | ~x_dw ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| |
| // bitwise and |
| |
| template <class X, class Y> |
| inline |
| X& |
| b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) |
| { |
| X& x = px.back_cast(); |
| const Y& y = py.back_cast(); |
| assert( x.length() == y.length() ); |
| int sz = x.size(); |
| for( int i = 0; i < sz; ++ i ) { |
| sc_digit x_dw, x_cw, y_dw, y_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| get_words_( y, i, y_dw, y_cw ); |
| sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw); |
| sc_digit dw = cw | (x_dw & y_dw); |
| set_words_( x, i, dw, cw ); |
| } |
| // tail cleaning not needed |
| return x; |
| } |
| |
| |
| // bitwise or |
| |
| template <class X, class Y> |
| inline |
| X& |
| b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) |
| { |
| X& x = px.back_cast(); |
| const Y& y = py.back_cast(); |
| assert( x.length() == y.length() ); |
| int sz = x.size(); |
| for( int i = 0; i < sz; ++ i ) { |
| sc_digit x_dw, x_cw, y_dw, y_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| get_words_( y, i, y_dw, y_cw ); |
| sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw); |
| sc_digit dw = cw | x_dw | y_dw; |
| set_words_( x, i, dw, cw ); |
| } |
| // tail cleaning not needed |
| return x; |
| } |
| |
| |
| // bitwise xor |
| |
| template <class X, class Y> |
| inline |
| X& |
| b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b ) |
| { |
| X& x = a.back_cast(); |
| const Y& y = b.back_cast(); |
| assert( x.length() == y.length() ); |
| int sz = x.size(); |
| for( int i = 0; i < sz; ++ i ) { |
| sc_digit x_dw, x_cw, y_dw, y_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| get_words_( y, i, y_dw, y_cw ); |
| sc_digit cw = x_cw | y_cw; |
| sc_digit dw = cw | (x_dw ^ y_dw); |
| set_words_( x, i, dw, cw ); |
| } |
| // tail cleaning not needed |
| return x; |
| } |
| |
| |
| // bitwise left shift |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::operator <<= ( int n ) |
| { |
| X& x = back_cast(); |
| if( n < 0 ) { |
| char msg[BUFSIZ]; |
| std::sprintf( msg, |
| "left shift operation is only allowed with positive " |
| "shift values, shift value = %d", n ); |
| SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); |
| } |
| if( n >= x.length() ) { |
| extend_sign_w_( x, 0, false ); |
| // no tail cleaning needed |
| return x; |
| } |
| int sz = x.size(); |
| int wn = n / SC_DIGIT_SIZE; |
| int bn = n % SC_DIGIT_SIZE; |
| if( wn != 0 ) { |
| // shift words |
| int i = sz - 1; |
| for( ; i >= wn; -- i ) { |
| set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) ); |
| } |
| for( ; i >= 0; -- i ) { |
| set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); |
| } |
| } |
| if( bn != 0 ) { |
| // shift bits |
| for( int i = sz - 1; i >= 1; -- i ) { |
| sc_digit x_dw, x_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| x_dw <<= bn; |
| x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn); |
| x_cw <<= bn; |
| x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn); |
| set_words_( x, i, x_dw, x_cw ); |
| } |
| sc_digit x_dw, x_cw; |
| get_words_( x, 0, x_dw, x_cw ); |
| x_dw <<= bn; |
| x_cw <<= bn; |
| set_words_( x, 0, x_dw, x_cw ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| |
| // bitwise right shift |
| |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::operator >>= ( int n ) |
| { |
| X& x = back_cast(); |
| if( n < 0 ) { |
| char msg[BUFSIZ]; |
| std::sprintf( msg, |
| "right shift operation is only allowed with positive " |
| "shift values, shift value = %d", n ); |
| SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); |
| } |
| if( n >= x.length() ) { |
| extend_sign_w_( x, 0, false ); |
| // no tail cleaning needed |
| return x; |
| } |
| int sz = x.size(); |
| int wn = n / SC_DIGIT_SIZE; |
| int bn = n % SC_DIGIT_SIZE; |
| if( wn != 0 ) { |
| // shift words |
| int i = 0; |
| for( ; i < (sz - wn); ++ i ) { |
| set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) ); |
| } |
| for( ; i < sz; ++ i ) { |
| set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); |
| } |
| } |
| if( bn != 0 ) { |
| // shift bits |
| for( int i = 0; i < (sz - 1); ++ i ) { |
| sc_digit x_dw, x_cw; |
| get_words_( x, i, x_dw, x_cw ); |
| x_dw >>= bn; |
| x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn); |
| x_cw >>= bn; |
| x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn); |
| set_words_( x, i, x_dw, x_cw ); |
| } |
| sc_digit x_dw, x_cw; |
| get_words_( x, sz - 1, x_dw, x_cw ); |
| x_dw >>= bn; |
| x_cw >>= bn; |
| set_words_( x, sz - 1, x_dw, x_cw ); |
| } |
| x.clean_tail(); |
| return x; |
| } |
| |
| |
| // bitwise left rotate |
| |
| template <class X> |
| inline |
| const sc_lv_base |
| lrotate( const sc_proxy<X>& x, int n ); |
| |
| |
| // bitwise right rotate |
| |
| template <class X> |
| inline |
| const sc_lv_base |
| rrotate( const sc_proxy<X>& x, int n ); |
| |
| |
| // bitwise reverse |
| |
| template <class X> |
| inline |
| X& |
| sc_proxy<X>::reverse() |
| { |
| X& x = back_cast(); |
| int len = x.length(); |
| int half_len = len / 2; |
| for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) { |
| sc_logic_value_t t = x.get_bit( i ); |
| x.set_bit( i, x.get_bit( j ) ); |
| x.set_bit( j, t ); |
| } |
| return x; |
| } |
| |
| template <class X> |
| inline |
| const sc_lv_base |
| reverse( const sc_proxy<X>& a ); |
| |
| |
| // reduce functions |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| sc_proxy<X>::and_reduce() const |
| { |
| const X& x = back_cast(); |
| sc_logic_value_t result = sc_logic_value_t( 1 ); |
| int len = x.length(); |
| for( int i = 0; i < len; ++ i ) { |
| result = sc_logic::and_table[result][x.get_bit( i )]; |
| } |
| return result; |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| sc_proxy<X>::or_reduce() const |
| { |
| const X& x = back_cast(); |
| sc_logic_value_t result = sc_logic_value_t( 0 ); |
| int len = x.length(); |
| for( int i = 0; i < len; ++ i ) { |
| result = sc_logic::or_table[result][x.get_bit( i )]; |
| } |
| return result; |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| sc_proxy<X>::xor_reduce() const |
| { |
| const X& x = back_cast(); |
| sc_logic_value_t result = sc_logic_value_t( 0 ); |
| int len = x.length(); |
| for( int i = 0; i < len; ++ i ) { |
| result = sc_logic::xor_table[result][x.get_bit( i )]; |
| } |
| return result; |
| } |
| |
| |
| // relational operators |
| |
| template <class X, class Y> |
| inline |
| bool |
| operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) |
| { |
| return !( px == py ); |
| } |
| |
| |
| #define DEFN_REL_OP_T(tp) \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator == ( tp b, const sc_proxy<X>& px ) \ |
| { \ |
| return ( px == b ); \ |
| } \ |
| \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator != ( const sc_proxy<X>& px, tp b ) \ |
| { \ |
| return !( px == b ); \ |
| } \ |
| \ |
| template <class X> \ |
| inline \ |
| bool \ |
| operator != ( tp b, const sc_proxy<X>& px ) \ |
| { \ |
| return !( px == b ); \ |
| } |
| |
| DEFN_REL_OP_T(const char*) |
| DEFN_REL_OP_T(const bool*) |
| DEFN_REL_OP_T(const sc_logic*) |
| DEFN_REL_OP_T(const sc_unsigned&) |
| DEFN_REL_OP_T(const sc_signed&) |
| DEFN_REL_OP_T(const sc_uint_base&) |
| DEFN_REL_OP_T(const sc_int_base&) |
| DEFN_REL_OP_T(unsigned long) |
| DEFN_REL_OP_T(long) |
| DEFN_REL_OP_T(unsigned int) |
| DEFN_REL_OP_T(int) |
| DEFN_REL_OP_T(uint64) |
| DEFN_REL_OP_T(int64) |
| |
| #undef DEFN_REL_OP_T |
| |
| |
| // explicit conversions to character string |
| |
| template <class X> |
| inline |
| const std::string |
| sc_proxy<X>::to_string() const |
| { |
| const X& x = back_cast(); |
| int len = x.length(); |
| std::string s; // ( len + 1 ); |
| for( int i = 0; i < len; ++ i ) { |
| s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )]; |
| } |
| return s; |
| } |
| |
| template <class X> |
| inline |
| const std::string |
| sc_proxy<X>::to_string( sc_numrep numrep ) const |
| { |
| return convert_to_fmt( to_string(), numrep, true ); |
| } |
| |
| template <class X> |
| inline |
| const std::string |
| sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const |
| { |
| return convert_to_fmt( to_string(), numrep, w_prefix ); |
| } |
| |
| |
| // other methods |
| |
| template <class X> |
| inline |
| void |
| sc_proxy<X>::scan( ::std::istream& is ) |
| { |
| std::string s; |
| is >> s; |
| back_cast() = s.c_str(); |
| } |
| |
| |
| template <class X> |
| inline |
| void |
| sc_proxy<X>::check_bounds( int n ) const // check if bit n accessible |
| { |
| if( n < 0 || n >= back_cast().length() ) { |
| SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); |
| } |
| } |
| |
| template <class X> |
| inline |
| void |
| sc_proxy<X>::check_wbounds( int n ) const // check if word n accessible |
| { |
| if( n < 0 || n >= back_cast().size() ) { |
| SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 ); |
| } |
| } |
| |
| |
| template <class X> |
| inline |
| sc_digit |
| sc_proxy<X>::to_anything_unsigned() const |
| { |
| // only 0 word is returned |
| // can't convert logic values other than 0 and 1 |
| const X& x = back_cast(); |
| int len = x.length(); |
| if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { |
| SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); |
| } |
| sc_digit w = x.get_word( 0 ); |
| if( len >= SC_DIGIT_SIZE ) { |
| return w; |
| } |
| return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); |
| } |
| |
| template <class X> |
| inline |
| uint64 |
| sc_proxy<X>::to_uint64() const |
| { |
| // words 1 and 0 returned. |
| // can't convert logic values other than 0 and 1 |
| const X& x = back_cast(); |
| int len = x.length(); |
| if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { |
| SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); |
| } |
| uint64 w = x.get_word( 0 ); |
| if( len > SC_DIGIT_SIZE ) |
| { |
| if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) { |
| SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); |
| } |
| uint64 w1 = x.get_word( 1 ); |
| w = w | (w1 << SC_DIGIT_SIZE); |
| return w; |
| } |
| else if( len == SC_DIGIT_SIZE ) |
| { |
| return w; |
| } |
| else |
| { |
| return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); |
| } |
| } |
| |
| template <class X> |
| inline |
| int64 |
| sc_proxy<X>::to_anything_signed() const |
| { |
| const X& x = back_cast(); |
| int len = x.length(); |
| int64 w = 0; |
| |
| if( len > SC_DIGIT_SIZE ) |
| { |
| if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) |
| SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); |
| w = x.get_word(1); |
| } |
| if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) |
| SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); |
| w = (w << SC_DIGIT_SIZE) | x.get_word( 0 ); |
| if( len >= 64 ) { |
| return w; |
| } |
| |
| uint64 zero = 0; |
| sc_logic_value_t sgn = x.get_bit( len - 1 ); |
| if( sgn == 0 ) { |
| return (int64)( w & (~zero >> (64 - len)) ); |
| } else { |
| return (int64)( w | (~zero << len) ); |
| } |
| } |
| |
| |
| // ---------------------------------------------------------------------------- |
| |
| // functional notation for the reduce methods |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| and_reduce( const sc_proxy<X>& a ) |
| { |
| return a.and_reduce(); |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| nand_reduce( const sc_proxy<X>& a ) |
| { |
| return a.nand_reduce(); |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| or_reduce( const sc_proxy<X>& a ) |
| { |
| return a.or_reduce(); |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| nor_reduce( const sc_proxy<X>& a ) |
| { |
| return a.nor_reduce(); |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| xor_reduce( const sc_proxy<X>& a ) |
| { |
| return a.xor_reduce(); |
| } |
| |
| template <class X> |
| inline |
| sc_logic_value_t |
| xnor_reduce( const sc_proxy<X>& a ) |
| { |
| return a.xnor_reduce(); |
| } |
| |
| |
| // ---------------------------------------------------------------------------- |
| |
| template <class X> |
| inline |
| ::std::ostream& |
| operator << ( ::std::ostream& os, const sc_proxy<X>& a ) |
| { |
| a.print( os ); |
| return os; |
| } |
| |
| template <class X> |
| inline |
| ::std::istream& |
| operator >> ( ::std::istream& is, sc_proxy<X>& a ) |
| { |
| a.scan( is ); |
| return is; |
| } |
| |
| } // namespace sc_dt |
| |
| |
| #endif |