diff options
Diffstat (limited to 'ext/systemc/src/sysc/datatypes/bit/sc_proxy.h')
-rw-r--r-- | ext/systemc/src/sysc/datatypes/bit/sc_proxy.h | 1609 |
1 files changed, 1609 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h new file mode 100644 index 000000000..7c67b447d --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/bit/sc_proxy.h @@ -0,0 +1,1609 @@ +/***************************************************************************** + + 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 |