/***************************************************************************** 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_bit_proxies.h -- Proxy classes for vector data types. Original Author: Gene Bushuyev, Synopsys, Inc. CHANGE LOG AT THE END OF THE FILE *****************************************************************************/ #ifndef __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__ #define __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__ #include #include "../../utils/messages.hh" #include "sc_proxy.hh" namespace sc_dt { // classes defined in this module template class sc_bitref_conv_r; template class sc_bitref_r; template class sc_bitref; template class sc_subref_r; template class sc_subref; template class sc_concref_r; template class sc_concref; // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_bitref_conv_r // // Proxy class for sc_proxy bit selection (r-value only, boolean conversion). // ---------------------------------------------------------------------------- template class sc_bitref_conv_r { /* empty by default */ }; // specialization for bit-vector based sc_proxy classes template class sc_bitref_conv_r > { public: #if __cplusplus >= 201103L // explicit operator needs C++11 // explicit conversion to bool explicit operator bool() const { return static_cast &>(*this).to_bool(); } #endif // explicit (negating) conversion to bool bool operator ! () const { return !static_cast &>(*this).to_bool(); } }; // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_bitref_r // // Proxy class for sc_proxy bit selection (r-value only). // ---------------------------------------------------------------------------- template class sc_bitref_r : public sc_bitref_conv_r { friend class sc_bv_base; friend class sc_lv_base; public: // typedefs typedef typename T::traits_type traits_type; typedef typename traits_type::bit_type bit_type; typedef typename traits_type::value_type value_type; // constructor sc_bitref_r(const T &obj_, int index_) : m_obj(const_cast(obj_)), m_index(index_) {} // copy constructor sc_bitref_r(const sc_bitref_r &a) : m_obj(a.m_obj), m_index(a.m_index) {} // cloning sc_bitref_r *clone() const { return new sc_bitref_r(*this); } // bitwise operators and functions // bitwise complement bit_type operator ~ () const { return bit_type(sc_logic::not_table[value()]); } // implicit conversion to bit_type operator bit_type() const { return bit_type(m_obj.get_bit(m_index)); } // explicit conversions value_type value() const { return m_obj.get_bit(m_index); } bool is_01() const { return sc_logic(value()).is_01(); } bool to_bool() const { return sc_logic(value()).to_bool(); } char to_char() const { return sc_logic(value()).to_char(); } // common methods int length() const { return 1; } int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } value_type get_bit(int n) const; sc_digit get_word(int i) const; sc_digit get_cword(int i) const; // other methods void print(::std::ostream &os=::std::cout) const { os << to_char(); } protected: T &m_obj; int m_index; private: // Disabled sc_bitref_r(); sc_bitref_r &operator = (const sc_bitref_r &); }; // bitwise operators and functions // bitwise and template inline sc_logic operator & ( const sc_bitref_r &a, const sc_bitref_r &b); // bitwise or template inline sc_logic operator | ( const sc_bitref_r &a, const sc_bitref_r &b); // bitwise xor template inline sc_logic operator ^ ( const sc_bitref_r &a, const sc_bitref_r &b); // relational operators and functions template inline bool operator == (const sc_bitref_r &a, const sc_bitref_r &b); template inline bool operator != (const sc_bitref_r &a, const sc_bitref_r &b); // r-value concatenation operators and functions template inline sc_concref_r, sc_bitref_r > operator , ( sc_bitref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_bitref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_bitref_r, sc_concref_r); template inline sc_concref_r, T2> operator , ( sc_bitref_r, const sc_proxy &); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref_r, const char *); template inline sc_concref_r > operator , ( const char *, sc_bitref_r); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref_r, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_bitref_r); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref_r, bool); template inline sc_concref_r > operator , ( bool, sc_bitref_r); template inline sc_concref_r, sc_bitref_r > concat( sc_bitref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_bitref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_bitref_r, sc_concref_r); template inline sc_concref_r, T2> concat( sc_bitref_r, const sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_bitref_r, const char *); template inline sc_concref_r > concat( const char *, sc_bitref_r); template inline sc_concref_r, sc_lv_base> concat( sc_bitref_r, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_bitref_r); template inline sc_concref_r, sc_lv_base> concat( sc_bitref_r, bool); template inline sc_concref_r > concat( bool, sc_bitref_r); template inline sc_concref_r, sc_bitref_r > operator , ( sc_bitref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > operator , ( sc_bitref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_bitref_r, sc_subref); template inline sc_concref_r, sc_subref_r > operator , ( sc_bitref, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_bitref_r, sc_concref); template inline sc_concref_r, sc_concref_r > operator , ( sc_bitref, sc_concref_r); template inline sc_concref_r, T2> operator , ( sc_bitref, const sc_proxy &); template inline sc_concref_r, T2> operator , ( sc_bitref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref, const char *); template inline sc_concref_r > operator , ( const char *, sc_bitref); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_bitref); template inline sc_concref_r, sc_lv_base> operator , ( sc_bitref, bool); template inline sc_concref_r > operator , ( bool, sc_bitref); template inline sc_concref_r, sc_bitref_r > concat( sc_bitref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > concat( sc_bitref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_bitref_r, sc_subref); template inline sc_concref_r, sc_subref_r > concat( sc_bitref, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_bitref_r, sc_concref); template inline sc_concref_r, sc_concref_r > concat( sc_bitref, sc_concref_r); template inline sc_concref_r, T2> concat( sc_bitref, const sc_proxy &); template inline sc_concref_r, T2> concat( sc_bitref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_bitref, const char *); template inline sc_concref_r > concat( const char *, sc_bitref); template inline sc_concref_r, sc_lv_base> concat( sc_bitref, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_bitref); template inline sc_concref_r, sc_lv_base> concat(sc_bitref, bool); template inline sc_concref_r > concat(bool, sc_bitref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_bitref // // Proxy class for sc_proxy bit selection (r-value and l-value). // ---------------------------------------------------------------------------- template class sc_bitref : public sc_bitref_r { friend class sc_bv_base; friend class sc_lv_base; public: typedef typename sc_bitref_r::value_type value_type; // constructor sc_bitref(X &obj_, int index_) : sc_bitref_r(obj_, index_) {} // copy constructor sc_bitref(const sc_bitref &a) : sc_bitref_r(a) {} // cloning sc_bitref *clone() const { return new sc_bitref(*this); } // assignment operators sc_bitref &operator = (const sc_bitref_r &a); sc_bitref &operator = (const sc_bitref &a); sc_bitref & operator = (const sc_logic &a) { this->m_obj.set_bit(this->m_index, a.value()); return *this; } sc_bitref & operator = (sc_logic_value_t v) { *this = sc_logic(v); return *this; } sc_bitref & operator = (bool a) { *this = sc_logic(a); return *this; } sc_bitref & operator = (char a) { *this = sc_logic(a); return *this; } sc_bitref & operator = (int a) { *this = sc_logic(a); return *this; } sc_bitref & operator = (const sc_bit &a) { *this = sc_logic(a); return *this; } // bitwise assignment operators sc_bitref &operator &= (const sc_bitref_r &a); sc_bitref &operator &= (const sc_logic &a); sc_bitref & operator &= (sc_logic_value_t v) { *this &= sc_logic(v); return *this; } sc_bitref & operator &= (bool a) { *this &= sc_logic(a); return *this; } sc_bitref & operator &= (char a) { *this &= sc_logic(a); return *this; } sc_bitref & operator &= (int a) { *this &= sc_logic(a); return *this; } sc_bitref &operator |= (const sc_bitref_r &a); sc_bitref &operator |= (const sc_logic &a); sc_bitref & operator |= (sc_logic_value_t v) { *this |= sc_logic(v); return *this; } sc_bitref & operator |= (bool a) { *this |= sc_logic(a); return *this; } sc_bitref & operator |= (char a) { *this |= sc_logic(a); return *this; } sc_bitref & operator |= (int a) { *this |= sc_logic(a); return *this; } sc_bitref &operator ^= (const sc_bitref_r &a); sc_bitref &operator ^= (const sc_logic &a); sc_bitref & operator ^= (sc_logic_value_t v) { *this ^= sc_logic(v); return *this; } sc_bitref & operator ^= (bool a) { *this ^= sc_logic(a); return *this; } sc_bitref & operator ^= (char a) { *this ^= sc_logic(a); return *this; } sc_bitref & operator ^= (int a) { *this ^= sc_logic(a); return *this; } // bitwise operators and functions // bitwise complement sc_bitref &b_not(); // common methods void set_bit(int n, value_type value); void set_word(int i, sc_digit w); void set_cword(int i, sc_digit w); void clean_tail() { this->m_obj.clean_tail(); } // other methods void scan(::std::istream &is=::std::cin); private: // Disabled sc_bitref(); }; // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , ( sc_bitref, sc_bitref); template inline sc_concref, sc_subref > operator , ( sc_bitref, sc_subref); template inline sc_concref, sc_concref > operator , ( sc_bitref, sc_concref); template inline sc_concref, T2> operator , ( sc_bitref, sc_proxy &); template inline sc_concref, sc_bitref > concat( sc_bitref, sc_bitref); template inline sc_concref, sc_subref > concat( sc_bitref, sc_subref); template inline sc_concref, sc_concref > concat( sc_bitref, sc_concref); template inline sc_concref, T2> concat(sc_bitref, sc_proxy &); template ::std::istream &operator >> (::std::istream &, sc_bitref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_subref_r // // Proxy class for sc_proxy part selection (r-value only). // ---------------------------------------------------------------------------- template class sc_subref_r : public sc_proxy > { void check_bounds(); public: typedef typename sc_proxy >::value_type value_type; // constructor sc_subref_r(const X &obj_, int hi_, int lo_) : m_obj(const_cast(obj_)), m_hi(hi_), m_lo(lo_), m_len(0) { check_bounds(); } // copy constructor sc_subref_r(const sc_subref_r &a) : m_obj(a.m_obj), m_hi(a.m_hi), m_lo(a.m_lo), m_len(a.m_len) {} // cloning sc_subref_r *clone() const { return new sc_subref_r(*this); } // common methods int length() const { return m_len; } int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } value_type get_bit(int n) const; void set_bit(int n, value_type value); sc_digit get_word(int i) const; void set_word(int i, sc_digit w); sc_digit get_cword(int i) const; void set_cword(int i, sc_digit w); void clean_tail() { m_obj.clean_tail(); } // other methods bool is_01() const; bool reversed() const { return m_lo > m_hi; } protected: X &m_obj; int m_hi; int m_lo; int m_len; private: // Disabled sc_subref_r(); sc_subref_r &operator = (const sc_subref_r &); }; // r-value concatenation operators and functions template inline sc_concref_r, sc_bitref_r > operator , ( sc_subref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_subref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_subref_r, sc_concref_r); template inline sc_concref_r, T2> operator , ( sc_subref_r, const sc_proxy &); template inline sc_concref_r,sc_lv_base> operator , ( sc_subref_r, const char *); template inline sc_concref_r > operator , ( const char *, sc_subref_r); template inline sc_concref_r, sc_lv_base> operator , ( sc_subref_r, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_subref_r); template inline sc_concref_r, sc_bv_base> operator , ( sc_subref_r, bool); template inline sc_concref_r > operator , ( bool, sc_subref_r); template inline sc_concref_r, sc_bitref_r > concat( sc_subref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_subref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_subref_r, sc_concref_r); template inline sc_concref_r, T2> concat( sc_subref_r, const sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_subref_r, const char *); template inline sc_concref_r > concat( const char *, sc_subref_r); template inline sc_concref_r, sc_lv_base> concat( sc_subref_r, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_subref_r); template inline sc_concref_r, sc_bv_base> concat(sc_subref_r, bool); template inline sc_concref_r > concat(bool, sc_subref_r); template inline sc_concref_r, sc_bitref_r > operator , ( sc_subref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > operator , ( sc_subref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_subref_r, sc_subref); template inline sc_concref_r, sc_subref_r > operator , ( sc_subref, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_subref_r, sc_concref); template inline sc_concref_r, sc_concref_r > operator , ( sc_subref, sc_concref_r); template inline sc_concref_r, T2> operator , ( sc_subref, const sc_proxy &); template inline sc_concref_r, T2> operator , ( sc_subref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> operator , ( sc_subref, const char *); template inline sc_concref_r > operator , ( const char *, sc_subref); template inline sc_concref_r, sc_lv_base> operator , ( sc_subref, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_subref); template inline sc_concref_r, sc_bv_base> operator , ( sc_subref, bool); template inline sc_concref_r > operator , ( bool, sc_subref); template inline sc_concref_r, sc_bitref_r > concat( sc_subref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > concat( sc_subref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_subref_r, sc_subref); template inline sc_concref_r, sc_subref_r > concat( sc_subref, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_subref_r, sc_concref); template inline sc_concref_r, sc_concref_r > concat( sc_subref, sc_concref_r); template inline sc_concref_r, T2> concat( sc_subref, const sc_proxy &); template inline sc_concref_r, T2> concat( sc_subref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_subref, const char *); template inline sc_concref_r > concat( const char *, sc_subref); template inline sc_concref_r, sc_lv_base> concat( sc_subref, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_subref); template inline sc_concref_r, sc_bv_base> concat(sc_subref, bool); template inline sc_concref_r > concat(bool, sc_subref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_subref // // Proxy class for sc_proxy part selection (r-value and l-value). // ---------------------------------------------------------------------------- template class sc_subref : public sc_subref_r { public: // typedefs typedef sc_subref_r base_type; // constructor sc_subref(X &obj_, int hi_, int lo_) : sc_subref_r(obj_, hi_, lo_) {} // copy constructor sc_subref(const sc_subref &a) : sc_subref_r(a) {} // cloning sc_subref *clone() const { return new sc_subref(*this); } // assignment operators template sc_subref & operator = (const sc_proxy &a) { base_type::assign_(a); return *this; } sc_subref &operator = (const sc_subref_r &a); sc_subref &operator = (const sc_subref &a); sc_subref & operator = (const char *a) { base_type::assign_(a); return *this; } sc_subref & operator = (const bool *a) { base_type::assign_(a); return *this; } sc_subref & operator = (const sc_logic *a) { base_type::assign_(a); return *this; } sc_subref & operator = (const sc_unsigned &a) { base_type::assign_(a); return *this; } sc_subref & operator = (const sc_signed &a) { base_type::assign_(a); return *this; } sc_subref & operator = (const sc_uint_base &a) { base_type::assign_(a); return *this; } sc_subref & operator = (const sc_int_base &a) { base_type::assign_(a); return *this; } sc_subref & operator = (unsigned long a) { base_type::assign_(a); return *this; } sc_subref & operator = (long a) { base_type::assign_(a); return *this; } sc_subref & operator = (unsigned int a) { base_type::assign_(a); return *this; } sc_subref & operator = (int a) { base_type::assign_(a); return *this; } sc_subref & operator = (uint64 a) { base_type::assign_(a); return *this; } sc_subref & operator = (int64 a) { base_type::assign_(a); return *this; } // other methods void scan(::std::istream & =::std::cin); private: // Disabled sc_subref(); }; // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , ( sc_subref, sc_bitref); template inline sc_concref, sc_subref > operator , ( sc_subref, sc_subref); template inline sc_concref, sc_concref > operator , ( sc_subref, sc_concref); template inline sc_concref, T2> operator , ( sc_subref, sc_proxy &); template inline sc_concref, sc_bitref > concat( sc_subref, sc_bitref); template inline sc_concref, sc_subref > concat( sc_subref, sc_subref); template inline sc_concref, sc_concref > concat( sc_subref, sc_concref); template inline sc_concref, T2> concat(sc_subref, sc_proxy &); template inline ::std::istream &operator >> (::std::istream &, sc_subref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_concref_r // // Proxy class for sc_proxy concatenation (r-value only). // ---------------------------------------------------------------------------- template class sc_concref_r : public sc_proxy > { public: typedef typename sc_proxy >::value_type value_type; // constructor sc_concref_r(const X &left_, const Y &right_, int delete_=0) : m_left(const_cast(left_)), m_right(const_cast(right_)), m_delete(delete_), m_refs(*new int(1)) {} // copy constructor sc_concref_r(const sc_concref_r &a) : m_left(a.m_left), m_right(a.m_right), m_delete(a.m_delete), m_refs(a.m_refs) { ++ m_refs; } // destructor virtual ~sc_concref_r(); // cloning sc_concref_r *clone() const { return new sc_concref_r(*this); } // common methods int length() const { return (m_left.length() + m_right.length()); } int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } value_type get_bit(int n) const; void set_bit(int n, value_type value); sc_digit get_word(int i) const; void set_word(int i, sc_digit w); sc_digit get_cword(int i) const; void set_cword(int i, sc_digit w); void clean_tail() { m_left.clean_tail(); m_right.clean_tail(); } // other methods bool is_01() const { return (m_left.is_01() && m_right.is_01()); } protected: X &m_left; Y &m_right; mutable int m_delete; int &m_refs; private: // Disabled sc_concref_r(); sc_concref_r &operator = (const sc_concref_r &); }; // r-value concatenation operators and functions template inline sc_concref_r,sc_bitref_r > operator , ( sc_concref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_concref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_concref_r, sc_concref_r); template inline sc_concref_r, T3> operator , ( sc_concref_r, const sc_proxy &); template inline sc_concref_r, sc_lv_base> operator , ( sc_concref_r, const char *); template inline sc_concref_r > operator , ( const char *, sc_concref_r); template inline sc_concref_r, sc_lv_base> operator , ( sc_concref_r, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_concref_r); template inline sc_concref_r, sc_bv_base> operator , ( sc_concref_r, bool); template inline sc_concref_r > operator , ( bool, sc_concref_r); template inline sc_concref_r, sc_bitref_r > concat( sc_concref_r, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_concref_r, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_concref_r, sc_concref_r); template inline sc_concref_r, T3> concat( sc_concref_r, const sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_concref_r, const char *); template inline sc_concref_r > concat( const char *, sc_concref_r); template inline sc_concref_r, sc_lv_base> concat( sc_concref_r, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_concref_r); template inline sc_concref_r, sc_bv_base> concat( sc_concref_r, bool); template inline sc_concref_r > concat( bool, sc_concref_r); template inline sc_concref_r, sc_bitref_r > operator , ( sc_concref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > operator , ( sc_concref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > operator , ( sc_concref_r, sc_subref); template inline sc_concref_r, sc_subref_r > operator , ( sc_concref, sc_subref_r); template inline sc_concref_r, sc_concref_r > operator , ( sc_concref_r, sc_concref); template inline sc_concref_r, sc_concref_r > operator , ( sc_concref, sc_concref_r); template inline sc_concref_r, T3> operator , ( sc_concref, const sc_proxy &); template inline sc_concref_r, T3> operator , ( sc_concref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> operator , ( sc_concref, const char *); template inline sc_concref_r > operator , ( const char *, sc_concref); template inline sc_concref_r, sc_lv_base> operator , ( sc_concref, const sc_logic &); template inline sc_concref_r > operator , ( const sc_logic &, sc_concref); template inline sc_concref_r, sc_bv_base> operator , ( sc_concref, bool); template inline sc_concref_r > operator , ( bool, sc_concref); template inline sc_concref_r, sc_bitref_r > concat( sc_concref_r, sc_bitref); template inline sc_concref_r, sc_bitref_r > concat( sc_concref, sc_bitref_r); template inline sc_concref_r, sc_subref_r > concat( sc_concref_r, sc_subref); template inline sc_concref_r, sc_subref_r > concat( sc_concref, sc_subref_r); template inline sc_concref_r, sc_concref_r > concat( sc_concref_r, sc_concref); template inline sc_concref_r, sc_concref_r > concat( sc_concref, sc_concref_r ); template inline sc_concref_r, T3> concat( sc_concref, const sc_proxy &); template inline sc_concref_r, T3> concat( sc_concref_r, sc_proxy &); template inline sc_concref_r, sc_lv_base> concat( sc_concref, const char *); template inline sc_concref_r > concat( const char *, sc_concref); template inline sc_concref_r, sc_lv_base> concat( sc_concref, const sc_logic &); template inline sc_concref_r > concat( const sc_logic &, sc_concref); template inline sc_concref_r, sc_bv_base> concat( sc_concref, bool); template inline sc_concref_r > concat( bool, sc_concref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_concref // // Proxy class for sc_proxy concatenation (r-value and l-value). // ---------------------------------------------------------------------------- template class sc_concref : public sc_concref_r { public: // typedefs typedef sc_concref_r base_type; // constructor sc_concref(X &left_, Y &right_, int delete_=0) : sc_concref_r(left_, right_, delete_) {} // copy constructor sc_concref(const sc_concref &a) : sc_concref_r(a) {} // cloning sc_concref *clone() const { return new sc_concref(*this); } // assignment operators template sc_concref & operator = (const sc_proxy &a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_concref &a) { base_type::assign_(a); return *this; } sc_concref & operator = (const char *a) { base_type::assign_(a); return *this; } sc_concref & operator = (const bool *a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_logic *a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_unsigned &a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_signed &a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_uint_base &a) { base_type::assign_(a); return *this; } sc_concref & operator = (const sc_int_base &a) { base_type::assign_(a); return *this; } sc_concref & operator = (unsigned long a) { base_type::assign_(a); return *this; } sc_concref & operator = (long a) { base_type::assign_(a); return *this; } sc_concref & operator = (unsigned int a) { base_type::assign_(a); return *this; } sc_concref & operator = (int a) { base_type::assign_(a); return *this; } sc_concref & operator = (uint64 a) { base_type::assign_(a); return *this; } sc_concref & operator = (int64 a) { base_type::assign_(a); return *this; } // other methods void scan(::std::istream & =::std::cin); private: // Disabled sc_concref(); }; // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , ( sc_concref, sc_bitref); template inline sc_concref, sc_subref > operator , ( sc_concref, sc_subref); template inline sc_concref, sc_concref > operator , ( sc_concref, sc_concref); template inline sc_concref, T3> operator , ( sc_concref, sc_proxy &); template inline sc_concref, sc_bitref > concat( sc_concref, sc_bitref); template inline sc_concref, sc_subref > concat( sc_concref, sc_subref); template inline sc_concref, sc_concref > concat( sc_concref, sc_concref); template inline sc_concref, T3> concat( sc_concref, sc_proxy &); template inline ::std::istream &operator >> (::std::istream &, sc_concref); // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_proxy // // Base class template for bit/logic vector classes. // (Barton/Nackmann implementation) // ---------------------------------------------------------------------------- // r-value concatenation operators and functions template inline sc_concref_r > operator , ( const sc_proxy &, sc_bitref_r); template inline sc_concref_r > operator , ( const sc_proxy &, sc_subref_r); template inline sc_concref_r > operator , ( const sc_proxy &, sc_concref_r); template inline sc_concref_r operator , ( const sc_proxy &, const sc_proxy &); template inline sc_concref_r operator , ( const sc_proxy &, const char *); template inline sc_concref_r operator , ( const char *, const sc_proxy &); template inline sc_concref_r operator , ( const sc_proxy &, const sc_logic &); template inline sc_concref_r operator , ( const sc_logic &, const sc_proxy &); template inline sc_concref_r operator , (const sc_proxy &, bool); template inline sc_concref_r operator , (bool, const sc_proxy &); template inline sc_concref_r > concat( const sc_proxy &, sc_bitref_r); template inline sc_concref_r > concat( const sc_proxy &, sc_subref_r); template inline sc_concref_r > concat( const sc_proxy &, sc_concref_r); template inline sc_concref_r concat(const sc_proxy &, const sc_proxy &); template inline sc_concref_r concat(const sc_proxy &, const char *); template inline sc_concref_r concat(const char *, const sc_proxy &); template inline sc_concref_r concat( const sc_proxy &, const sc_logic &); template inline sc_concref_r concat( const sc_logic &, const sc_proxy &); template inline sc_concref_r concat(const sc_proxy &, bool); template inline sc_concref_r concat(bool, const sc_proxy &); template inline sc_concref_r > operator , ( const sc_proxy &, sc_bitref); template inline sc_concref_r > operator , ( sc_proxy &, sc_bitref_r); template inline sc_concref_r > operator , ( const sc_proxy &, sc_subref); template inline sc_concref_r > operator , ( sc_proxy &, sc_subref_r); template inline sc_concref_r > operator , ( const sc_proxy &, sc_concref); template inline sc_concref_r > operator , ( sc_proxy &, sc_concref_r); template inline sc_concref_r operator , (const sc_proxy &, sc_proxy &); template inline sc_concref_r operator , (sc_proxy &, const sc_proxy &); template inline sc_concref_r operator , (sc_proxy &, const char *); template inline sc_concref_r operator , (const char *, sc_proxy &); template inline sc_concref_r operator , ( sc_proxy &, const sc_logic &); template inline sc_concref_r operator , ( const sc_logic &, sc_proxy &); template inline sc_concref_r operator , (sc_proxy &, bool); template inline sc_concref_r operator , (bool, sc_proxy &); template inline sc_concref_r > concat( const sc_proxy &, sc_bitref); template inline sc_concref_r > concat( sc_proxy &, sc_bitref_r); template inline sc_concref_r > concat( const sc_proxy &, sc_subref); template inline sc_concref_r > concat( sc_proxy &, sc_subref_r); template inline sc_concref_r > concat( const sc_proxy &, sc_concref); template inline sc_concref_r > concat( sc_proxy &, sc_concref_r); template inline sc_concref_r concat(const sc_proxy &, sc_proxy &); template inline sc_concref_r concat(sc_proxy &, const sc_proxy &); template inline sc_concref_r concat(sc_proxy &, const char *); template inline sc_concref_r concat(const char *, sc_proxy &); template inline sc_concref_r concat(sc_proxy &, const sc_logic &); template inline sc_concref_r concat(const sc_logic &, sc_proxy &); template inline sc_concref_r concat(sc_proxy &, bool); template inline sc_concref_r concat(bool, sc_proxy &); // l-value concatenation operators and functions template inline sc_concref > operator , ( sc_proxy &, sc_bitref); template inline sc_concref > operator , ( sc_proxy &, sc_subref); template inline sc_concref > operator , ( sc_proxy &, sc_concref); template inline sc_concref operator , (sc_proxy &, sc_proxy &); template inline sc_concref > concat(sc_proxy &, sc_bitref); template inline sc_concref > concat(sc_proxy &, sc_subref); template inline sc_concref > concat( sc_proxy &, sc_concref); template inline sc_concref concat(sc_proxy &, sc_proxy &); // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_bitref_r // // Proxy class for sc_proxy bit selection (r-value only). // ---------------------------------------------------------------------------- // bitwise operators and functions // bitwise and template inline sc_logic operator & (const sc_bitref_r &a, const sc_bitref_r &b) { return sc_logic(sc_logic::and_table[a.value()][b.value()]); } // bitwise or template inline sc_logic operator | (const sc_bitref_r &a, const sc_bitref_r &b) { return sc_logic(sc_logic::or_table[a.value()][b.value()]); } // bitwise xor template inline sc_logic operator ^ (const sc_bitref_r &a, const sc_bitref_r &b) { return sc_logic(sc_logic::xor_table[a.value()][b.value()]); } // relational operators and functions template inline bool operator == (const sc_bitref_r &a, const sc_bitref_r &b) { return ((int)a.value() == b.value()); } template inline bool operator != (const sc_bitref_r &a, const sc_bitref_r &b) { return ((int)a.value() != b.value()); } // common methods template inline typename sc_bitref_r::value_type sc_bitref_r::get_bit(int n) const { if (n == 0) { return m_obj.get_bit(m_index); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); return Log_0; } } template inline sc_digit sc_bitref_r::get_word(int n) const { if (n == 0) { return (get_bit(n) & SC_DIGIT_ONE); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); return 0; } } template inline sc_digit sc_bitref_r::get_cword(int n) const { if (n == 0) { return ((get_bit(n) & SC_DIGIT_TWO) >> 1); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); return 0; } } // r-value concatenation operators and functions template inline sc_concref_r, sc_bitref_r > operator , (sc_bitref_r a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_bitref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_bitref_r a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> operator , (sc_bitref_r a, const sc_proxy &b) { return sc_concref_r, T2>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_bitref_r a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_bitref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_bitref_r a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> concat(sc_bitref_r a, const sc_proxy &b) { return sc_concref_r, T2>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > operator , (sc_bitref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > operator , (sc_bitref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_bitref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_bitref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_bitref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_bitref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> operator , (sc_bitref a, const sc_proxy &b) { return sc_concref_r, T2>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T2> operator , (sc_bitref_r a, sc_proxy &b) { return sc_concref_r, T2>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_bitref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > concat(sc_bitref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_bitref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_bitref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_bitref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_bitref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> concat(sc_bitref a, const sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T2> concat(sc_bitref_r a, sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_bitref // // Proxy class for sc_proxy bit selection (r-value and l-value). // ---------------------------------------------------------------------------- // assignment operators template inline sc_bitref & sc_bitref::operator = (const sc_bitref_r &a) { this->m_obj.set_bit(this->m_index, a.value()); return *this; } template inline sc_bitref & sc_bitref::operator = (const sc_bitref &a) { if (&a != this) { this->m_obj.set_bit(this->m_index, a.value()); } return *this; } // bitwise assignment operators template inline sc_bitref & sc_bitref::operator &= (const sc_bitref_r &a) { if (&a != this) { this->m_obj.set_bit( this->m_index, sc_logic::and_table[this->value()][a.value()]); } return *this; } template inline sc_bitref & sc_bitref::operator &= (const sc_logic &a) { this->m_obj.set_bit( this->m_index, sc_logic::and_table[this->value()][a.value()]); return *this; } template inline sc_bitref & sc_bitref::operator |= (const sc_bitref_r &a) { if (&a != this) { this->m_obj.set_bit( this->m_index, sc_logic::or_table[this->value()][a.value()]); } return *this; } template inline sc_bitref & sc_bitref::operator |= (const sc_logic &a) { this->m_obj.set_bit( this->m_index, sc_logic::or_table[this->value()][a.value()]); return *this; } template inline sc_bitref & sc_bitref::operator ^= (const sc_bitref_r &a) { if (&a != this) { this->m_obj.set_bit( this->m_index, sc_logic::xor_table[this->value()][a.value()]); } return *this; } template inline sc_bitref & sc_bitref::operator ^= (const sc_logic &a) { this->m_obj.set_bit( this->m_index, sc_logic::xor_table[this->value()][a.value()]); return *this; } // bitwise operators and functions // bitwise complement template inline sc_bitref & sc_bitref::b_not() { this->m_obj.set_bit(this->m_index, sc_logic::not_table[this->value()]); return *this; } // common methods template inline void sc_bitref::set_bit(int n, value_type value) { if (n == 0) { this->m_obj.set_bit(this->m_index, value); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } } template inline void sc_bitref::set_word(int n, sc_digit w) { unsigned int bi = this->m_index % (8 * sizeof(sc_digit)); sc_digit temp; unsigned int wi = this->m_index / (8 * sizeof(sc_digit)); if (n == 0) { temp = this->m_obj.get_word(wi); temp = (temp & ~(1 << bi)) | ((w & 1) << bi); this->m_obj.set_word(wi, temp); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } } template inline void sc_bitref::set_cword(int n, sc_digit w) { unsigned int bi = this->m_index % (8 * sizeof(sc_digit)); sc_digit temp; unsigned int wi = this->m_index / (8 * sizeof(sc_digit)); if (n == 0) { temp = this->m_obj.get_cword(wi); temp = (temp & ~(1 << bi)) | ((w & 1) << bi); this->m_obj.set_cword(wi, temp); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } } // other methods template inline void sc_bitref::scan(::std::istream &is) { char c; is >> c; *this = c; } // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , (sc_bitref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > operator , (sc_bitref a, sc_subref b) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > operator , (sc_bitref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T2> operator , (sc_bitref a, sc_proxy &b) { return sc_concref, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref, sc_bitref > concat(sc_bitref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > concat(sc_bitref a, sc_subref b) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > concat(sc_bitref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T2> concat(sc_bitref a, sc_proxy &b) { return sc_concref, T2>(*a.clone(), b.back_cast(), 1); } template inline ::std::istream & operator >> (::std::istream &is, sc_bitref a) { a.scan(is); return is; } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_subref_r // // Proxy class for sc_proxy part selection (r-value only). // ---------------------------------------------------------------------------- template inline void sc_subref_r::check_bounds() { int len = m_obj.length(); if (m_hi < 0 || m_hi >= len || m_lo < 0 || m_lo >= len) { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); sc_core::sc_abort(); // can't recover from here } if (reversed()) { m_len = m_lo - m_hi + 1; } else { m_len = m_hi - m_lo + 1; } } // common methods template inline typename sc_subref_r::value_type sc_subref_r::get_bit(int n) const { if (reversed()) { return m_obj.get_bit(m_lo - n); } else { return m_obj.get_bit(m_lo + n); } } template inline void sc_subref_r::set_bit(int n, value_type value) { if (reversed()) { m_obj.set_bit(m_lo - n, value); } else { m_obj.set_bit(m_lo + n, value); } } template inline sc_digit sc_subref_r::get_word(int i) const { int n1 = 0; int n2 = 0; sc_digit result = 0; int k = 0; if (reversed()) { n1 = m_lo - i * SC_DIGIT_SIZE; n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); for (int n = n1; n > n2; n--) { result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++; } } else { n1 = m_lo + i * SC_DIGIT_SIZE; n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); for (int n = n1; n < n2; n++) { result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++; } } return result; } template inline void sc_subref_r::set_word(int i, sc_digit w) { int n1 = 0; int n2 = 0; int k = 0; if (reversed()) { n1 = m_lo - i * SC_DIGIT_SIZE; n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); for (int n = n1; n > n2; n--) { m_obj.set_bit(n, value_type( ((w >> k++) & SC_DIGIT_ONE) | (m_obj[n].value() & SC_DIGIT_TWO))); } } else { n1 = m_lo + i * SC_DIGIT_SIZE; n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); for (int n = n1; n < n2; n++) { m_obj.set_bit(n, value_type( ((w >> k++) & SC_DIGIT_ONE) | (m_obj[n].value() & SC_DIGIT_TWO))); } } } template inline sc_digit sc_subref_r::get_cword(int i) const { int n1 = 0; int n2 = 0; sc_digit result = 0; int k = 0; if (reversed()) { n1 = m_lo - i * SC_DIGIT_SIZE; n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); for (int n = n1; n > n2; n--) { result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++; } } else { n1 = m_lo + i * SC_DIGIT_SIZE; n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); for (int n = n1; n < n2; n++) { result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++; } } return result; } template inline void sc_subref_r::set_cword(int i, sc_digit w) { int n1 = 0; int n2 = 0; int k = 0; if (reversed()) { n1 = m_lo - i * SC_DIGIT_SIZE; n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); for (int n = n1; n > n2; n--) { m_obj.set_bit(n, value_type( (((w >> k++) & SC_DIGIT_ONE) << 1) | (m_obj[n].value() & SC_DIGIT_ONE))); } } else { n1 = m_lo + i * SC_DIGIT_SIZE; n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); for (int n = n1; n < n2; n++) { m_obj.set_bit(n, value_type( (((w >> k++) & SC_DIGIT_ONE) << 1) | (m_obj[n].value() & SC_DIGIT_ONE))); } } } // other methods template inline bool sc_subref_r::is_01() const { int sz = size(); for (int i = 0; i < sz; ++i) { if (get_cword(i) != SC_DIGIT_ZERO) { return false; } } return true; } // r-value concatenation operators and functions template inline sc_concref_r, sc_bitref_r > operator , (sc_subref_r a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_subref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_subref_r a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> operator , (sc_subref_r a, const sc_proxy &b) { return sc_concref_r, T2>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_subref_r a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_subref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_subref_r a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> concat(sc_subref_r a, const sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > operator , (sc_subref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > operator , (sc_subref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_subref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_subref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_subref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_subref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> operator , (sc_subref a, const sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T2> operator , (sc_subref_r a, sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_subref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > concat(sc_subref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_subref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_subref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_subref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_subref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T2> concat(sc_subref a, const sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T2> concat(sc_subref_r a, sc_proxy &b) { return sc_concref_r, T2>(*a.clone(), b.back_cast(), 1); } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_subref // // Proxy class for sc_proxy part selection (r-value and l-value). // ---------------------------------------------------------------------------- // assignment operators // sc_subref::operator = ( const sc_subref_r& ) in sc_lv_base.h // sc_subref::operator = ( const sc_subref& ) in sc_lv_base.h // other methods template inline void sc_subref::scan(::std::istream &is) { std::string s; is >> s; *this = s.c_str(); } // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , (sc_subref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > operator , (sc_subref a, sc_subref b) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > operator , (sc_subref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T2> operator , (sc_subref a, sc_proxy &b) { return sc_concref, T2>(*a.clone(), b.back_cast(), 1); } template inline sc_concref, sc_bitref > concat(sc_subref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > concat(sc_subref a, sc_subref b) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > concat(sc_subref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T2> concat(sc_subref a, sc_proxy &b) { return sc_concref, T2>(*a.clone(), b.back_cast(), 1); } template inline ::std::istream & operator >> (::std::istream &is, sc_subref a) { a.scan(is); return is; } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_concref_r // // Proxy class for sc_proxy concatenation (r-value only). // ---------------------------------------------------------------------------- // destructor template inline sc_concref_r::~sc_concref_r() { if (--m_refs == 0) { delete &m_refs; if (m_delete == 0) { return; } if (m_delete & 1) { delete &m_left; } if (m_delete & 2) { delete &m_right; } } } // common methods template inline typename sc_concref_r::value_type sc_concref_r::get_bit(int n) const { int r_len = m_right.length(); if (n < r_len) { return value_type(m_right.get_bit(n)); } else if (n < r_len + m_left.length()) { return value_type(m_left.get_bit(n - r_len)); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); return Log_0; } } template inline void sc_concref_r::set_bit(int n, value_type v) { int r_len = m_right.length(); if (n < r_len) { m_right.set_bit(n, typename Y::value_type(v)); } else if (n < r_len + m_left.length()) { m_left.set_bit(n - r_len, typename X::value_type(v)); } else { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } } template inline sc_digit sc_concref_r::get_word(int i) const { if (i < 0 || i >= size()) { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } // 0 <= i < size() Y &r = m_right; int r_len = r.length(); int border = r_len / SC_DIGIT_SIZE; if (i < border) { return r.get_word(i); } // border <= i < size() X& l = m_left; int shift = r_len % SC_DIGIT_SIZE; int j = i - border; if (shift == 0) { return l.get_word(j); } // border <= i < size() && shift != 0 int nshift = SC_DIGIT_SIZE - shift; if (i == border) { sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; return ((r.get_word(i) & rl_mask) | (l.get_word(0) << shift)); } // border < i < size() && shift != 0 if (j < l.size()) return ((l.get_word(j - 1) >> nshift) | (l.get_word(j) << shift)); else return (l.get_word(j - 1) >> nshift); } template inline void sc_concref_r::set_word(int i, sc_digit w) { if (i < 0 || i >= size()) { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } // 0 <= i < size() Y &r = m_right; int r_len = r.length(); int border = r_len / SC_DIGIT_SIZE; if (i < border) { r.set_word(i, w); return; } // border <= i < size() X &l = m_left; int shift = r_len % SC_DIGIT_SIZE; int j = i - border; if (shift == 0) { l.set_word(j, w); return; } // border <= i < size() && shift != 0 int nshift = SC_DIGIT_SIZE - shift; sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; if (i == border) { sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; r.set_word(i, w & rl_mask); l.set_word(0, (l.get_word(0) & lh_mask) | (w >> shift)); return; } // border < i < size() && shift != 0 sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; l.set_word(j - 1, (l.get_word(j - 1) & ll_mask) | (w << nshift)); if (j < l.size()) l.set_word(j, (l.get_word(j) & lh_mask) | (w >> shift)); } template inline sc_digit sc_concref_r::get_cword(int i) const { if (i < 0 || i >= size()) { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } // 0 <= i < size() Y &r = m_right; int r_len = r.length(); int border = r_len / SC_DIGIT_SIZE; if (i < border) { return r.get_cword(i); } // border <= i < size() X &l = m_left; int shift = r_len % SC_DIGIT_SIZE; int j = i - border; if (shift == 0) { return l.get_cword(j); } // border <= i < size() && shift != 0 int nshift = SC_DIGIT_SIZE - shift; if (i == border) { sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; return ((r.get_cword(i) & rl_mask) | (l.get_cword(0) << shift)); } // border < i < size() && shift != 0 if (j < l.size()) return ((l.get_cword(j - 1) >> nshift) | (l.get_cword(j) << shift)); else return (l.get_cword( j - 1 ) >> nshift); } template inline void sc_concref_r::set_cword(int i, sc_digit w) { if (i < 0 || i >= size()) { SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0); } // 0 <= i < size() Y &r = m_right; int r_len = r.length(); int border = r_len / SC_DIGIT_SIZE; if (i < border) { r.set_cword(i, w); return; } // border <= i < size() X &l = m_left; int shift = r_len % SC_DIGIT_SIZE; int j = i - border; if (shift == 0) { l.set_cword(j, w); return; } // border <= i < size() && shift != 0 int nshift = SC_DIGIT_SIZE - shift; sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; if (i == border) { sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; r.set_cword(i, w & rl_mask); l.set_cword(0, (l.get_cword(0) & lh_mask) | (w >> shift)); return; } // border < i < size() && shift != 0 sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; l.set_cword(j - 1, (l.get_cword(j - 1) & ll_mask) | (w << nshift)); if (j < l.size()) l.set_cword(j, (l.get_cword(j) & lh_mask) | (w >> shift)); } // r-value concatenation operators and functions template inline sc_concref_r,sc_bitref_r > operator , (sc_concref_r a, sc_bitref_r b) { return sc_concref_r,sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_concref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_concref_r a, sc_concref_r b) { return sc_concref_r,sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T3> operator , (sc_concref_r a, const sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_concref_r a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_concref_r a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_concref_r a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T3> concat(sc_concref_r a, const sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > operator , (sc_concref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > operator , (sc_concref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_concref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > operator , (sc_concref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_concref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > operator , (sc_concref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T3> operator , (sc_concref a, const sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T3> operator , (sc_concref_r a, sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, sc_bitref_r > concat(sc_concref_r a, sc_bitref b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_bitref_r > concat(sc_concref a, sc_bitref_r b) { return sc_concref_r, sc_bitref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_concref_r a, sc_subref b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_subref_r > concat(sc_concref a, sc_subref_r b) { return sc_concref_r, sc_subref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_concref_r a, sc_concref b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, sc_concref_r > concat(sc_concref a, sc_concref_r b) { return sc_concref_r, sc_concref_r >( *a.clone(), *b.clone(), 3); } template inline sc_concref_r, T3> concat(sc_concref a, const sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref_r, T3> concat(sc_concref_r a, sc_proxy &b) { return sc_concref_r, T3>( *a.clone(), b.back_cast(), 1); } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_concref // // Proxy class for sc_proxy concatenation (r-value and l-value). // ---------------------------------------------------------------------------- // other methods template inline void sc_concref::scan(::std::istream &is) { std::string s; is >> s; *this = s.c_str(); } // l-value concatenation operators and functions template inline sc_concref, sc_bitref > operator , (sc_concref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > operator , (sc_concref a, sc_subrefb) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > operator , (sc_concref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T3> operator , (sc_concref a, sc_proxy &b) { return sc_concref, T3>( *a.clone(), b.back_cast(), 1); } template inline sc_concref, sc_bitref > concat(sc_concref a, sc_bitref b) { return sc_concref, sc_bitref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_subref > concat(sc_concref a, sc_subref b) { return sc_concref, sc_subref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, sc_concref > concat(sc_concref a, sc_concref b) { return sc_concref, sc_concref >( *a.clone(), *b.clone(), 3); } template inline sc_concref, T3> concat(sc_concref a, sc_proxy &b) { return sc_concref, T3>( *a.clone(), b.back_cast(), 1); } template inline ::std::istream & operator >> (::std::istream &is, sc_concref a) { a.scan(is); return is; } // ---------------------------------------------------------------------------- // CLASS TEMPLATE : sc_proxy // // Base class template for bit/logic vector classes. // (Barton/Nackmann implementation) // ---------------------------------------------------------------------------- // r-value concatenation operators and functions template inline sc_concref_r > operator , (const sc_proxy &a, sc_bitref_r b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (const sc_proxy &a, sc_subref_r b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (const sc_proxy &a, sc_concref_r b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r operator , (const sc_proxy &a, const sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } template inline sc_concref_r > concat(const sc_proxy &a, sc_bitref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(const sc_proxy &a, sc_subref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(const sc_proxy &a, sc_concref_r b ) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r concat(const sc_proxy &a, const sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } template inline sc_concref_r > operator , (const sc_proxy &a, sc_bitref b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (sc_proxy &a, sc_bitref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (const sc_proxy &a, sc_subref b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (sc_proxy &a, sc_subref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (const sc_proxy &a, sc_concref b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > operator , (sc_proxy &a, sc_concref_r b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r operator , (const sc_proxy &a, sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } template inline sc_concref_r operator , (sc_proxy &a, const sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } template inline sc_concref_r > concat(const sc_proxy &a, sc_bitref b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(sc_proxy &a, sc_bitref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(const sc_proxy &a, sc_subref b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(sc_proxy &a, sc_subref_r b) { return sc_concref_r >(a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(const sc_proxy &a, sc_concref b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r > concat(sc_proxy &a, sc_concref_r b) { return sc_concref_r >( a.back_cast(), *b.clone(), 2); } template inline sc_concref_r concat(const sc_proxy &a, sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } template inline sc_concref_r concat(sc_proxy &a, const sc_proxy &b) { return sc_concref_r(a.back_cast(), b.back_cast()); } // l-value concatenation operators and functions template inline sc_concref > operator , (sc_proxy &a, sc_bitref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref > operator , (sc_proxy &a, sc_subref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref > operator , (sc_proxy &a, sc_concref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref operator , (sc_proxy &a, sc_proxy &b) { return sc_concref(a.back_cast(), b.back_cast()); } template inline sc_concref > concat(sc_proxy &a, sc_bitref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref > concat(sc_proxy &a, sc_subref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref > concat(sc_proxy &a, sc_concref b) { return sc_concref >(a.back_cast(), *b.clone(), 2); } template inline sc_concref concat(sc_proxy &a, sc_proxy &b) { return sc_concref(a.back_cast(), b.back_cast()); } } // namespace sc_dt // $Log: sc_bit_proxies.h,v $ // Revision 1.10 2011/09/05 21:19:53 acg // Philipp A. Hartmann: added parentheses to expressions to eliminate // compiler warnings. // // Revision 1.9 2011/09/01 15:03:42 acg // Philipp A. Hartmann: add parentheses to eliminate compiler warnings. // // Revision 1.8 2011/08/29 18:04:32 acg // Philipp A. Hartmann: miscellaneous clean ups. // // Revision 1.7 2011/08/24 22:05:40 acg // Torsten Maehne: initialization changes to remove warnings. // // Revision 1.6 2010/02/22 14:25:43 acg // Andy Goodrich: removed 'mutable' directive from references, since it // is not a legal C++ construct. // // Revision 1.5 2009/02/28 00:26:14 acg // Andy Goodrich: bug fixes. // // Revision 1.4 2007/03/14 17:48:37 acg // Andy Goodrich: fixed bug. // // Revision 1.3 2007/01/18 19:29:18 acg // Andy Goodrich: fixed bug in concatenations of bit selects on sc_lv and // sc_bv types. The offending code was in sc_bitref::set_word and // sc_bitref::get_word. These methods were not writing the bit they // represented, but rather writing an entire word whose index was the // index of the bit they represented. This not only did not write the // correct bit, but clobbered a word that might not even be in the // variable the reference was for. // // Revision 1.2 2007/01/17 22:45:08 acg // Andy Goodrich: fixed sc_bitref::set_bit(). // // 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. // #endif // __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__