| /***************************************************************************** | |
| 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_int_base.h -- A signed integer whose length is less than 64 bit. | |
| Unlike arbitrary precision, arithmetic and bitwise operations | |
| are performed using the native types (hence capped at 64 bits). | |
| The sc_int integer is useful when the user does not need | |
| arbitrary precision and the performance is superior to | |
| sc_bigint/sc_biguint. | |
| Original Author: Amit Rao, Synopsys, Inc. | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and | |
| changes you are making here. | |
| Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. | |
| Description of Modification: - Resolved ambiguity with sc_(un)signed. | |
| - Merged the code for 64- and 32-bit versions | |
| via the constants in sc_nbdefs.h. | |
| - Eliminated redundant file inclusions. | |
| Name, Affiliation, Date: | |
| Description of Modification: | |
| *****************************************************************************/ | |
| // $Log: sc_int_base.h,v $ | |
| // Revision 1.3 2011/08/24 22:05:45 acg | |
| // Torsten Maehne: initialization changes to remove warnings. | |
| // | |
| // Revision 1.2 2011/02/18 20:19:15 acg | |
| // Andy Goodrich: updating Copyright notice. | |
| // | |
| // Revision 1.1.1.1 2006/12/15 20:20:05 acg | |
| // SystemC 2.3 | |
| // | |
| // Revision 1.4 2006/05/08 17:50:01 acg | |
| // Andy Goodrich: Added David Long's declarations for friend operators, | |
| // functions, and methods, to keep the Microsoft compiler happy. | |
| // | |
| // Revision 1.3 2006/01/13 18:49:31 acg | |
| // Added $Log command so that CVS check in comments are reproduced in the | |
| // source. | |
| // | |
| #ifndef __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ | |
| #define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ | |
| #include <iostream> | |
| #include "../misc/sc_value_base.hh" | |
| #include "../sc_temporary.hh" | |
| #include "sc_length_param.hh" | |
| #include "sc_nbdefs.hh" | |
| #include "sc_uint_base.hh" | |
| namespace sc_dt | |
| { | |
| class sc_concatref; | |
| // classes defined in this module | |
| class sc_int_bitref_r; | |
| class sc_int_bitref; | |
| class sc_int_subref_r; | |
| class sc_int_subref; | |
| class sc_int_base; | |
| class sc_signed_subref_r; | |
| class sc_unsigned_subref_r; | |
| // forward class declarations | |
| class sc_bv_base; | |
| class sc_lv_base; | |
| class sc_signed; | |
| class sc_unsigned; | |
| class sc_fxval; | |
| class sc_fxval_fast; | |
| class sc_fxnum; | |
| class sc_fxnum_fast; | |
| } // namespace sc_dt | |
| // extern template instantiations | |
| namespace sc_core | |
| { | |
| extern template class sc_vpool<sc_dt::sc_int_bitref>; | |
| extern template class sc_vpool<sc_dt::sc_int_subref>; | |
| } // namespace sc_core | |
| namespace sc_dt | |
| { | |
| extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; | |
| // friend operator declarations | |
| // relational operators | |
| inline bool operator == (const sc_int_base &a, const sc_int_base &b); | |
| inline bool operator != (const sc_int_base &a, const sc_int_base &b); | |
| inline bool operator < (const sc_int_base &a, const sc_int_base &b); | |
| inline bool operator <= (const sc_int_base &a, const sc_int_base &b); | |
| inline bool operator > (const sc_int_base &a, const sc_int_base &b); | |
| inline bool operator >= (const sc_int_base &a, const sc_int_base &b); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_bitref_r | |
| // | |
| // Proxy class for sc_int bit selection (r-value only). | |
| // ---------------------------------------------------------------------------- | |
| class sc_int_bitref_r : public sc_value_base | |
| { | |
| friend class sc_int_base; | |
| protected: | |
| // constructor | |
| sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {} | |
| // initializer for sc_core::sc_vpool: | |
| void initialize(const sc_int_base *obj_p, int index_) | |
| { | |
| m_obj_p = (sc_int_base *)obj_p; | |
| m_index = index_; | |
| } | |
| public: | |
| // copy constructor | |
| sc_int_bitref_r(const sc_int_bitref_r &a) : | |
| sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) | |
| {} | |
| // destructor | |
| virtual ~sc_int_bitref_r() {} | |
| // capacity | |
| int length() const { return 1; } | |
| #ifdef SC_DT_DEPRECATED | |
| int bitwidth() const { return length(); } | |
| #endif | |
| // concatenation support | |
| virtual int | |
| concat_length(bool *xz_present_p) const | |
| { | |
| if (xz_present_p) | |
| *xz_present_p = false; | |
| return 1; | |
| } | |
| virtual bool | |
| concat_get_ctrl(sc_digit *dst_p, int low_i) const | |
| { | |
| int bit_mask = 1 << (low_i % BITS_PER_DIGIT); | |
| int word_i = low_i / BITS_PER_DIGIT; | |
| dst_p[word_i] &= ~bit_mask; | |
| return false; | |
| } | |
| virtual bool | |
| concat_get_data(sc_digit *dst_p, int low_i) const | |
| { | |
| bool non_zero; | |
| int bit_mask = 1 << (low_i % BITS_PER_DIGIT); | |
| int word_i = low_i / BITS_PER_DIGIT; | |
| if (operator uint64()) { | |
| dst_p[word_i] |= bit_mask; | |
| non_zero = true; | |
| } else { | |
| dst_p[word_i] &= ~bit_mask; | |
| non_zero = false; | |
| } | |
| return non_zero; | |
| } | |
| virtual uint64 | |
| concat_get_uint64() const | |
| { | |
| return operator uint64(); | |
| } | |
| // implicit conversions | |
| operator uint64 () const; | |
| bool operator ! () const; | |
| bool operator ~ () const; | |
| // explicit conversions | |
| uint64 value() const { return operator uint64(); } | |
| bool to_bool() const { return operator uint64(); } | |
| // other methods | |
| void print(::std::ostream& os=::std::cout) const { os << to_bool(); } | |
| protected: | |
| int m_index; | |
| sc_int_base *m_obj_p; | |
| private: | |
| // Disabled | |
| sc_int_bitref_r &operator = (const sc_int_bitref_r &); | |
| }; | |
| inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_bitref | |
| // | |
| // Proxy class for sc_int bit selection (r-value and l-value). | |
| // ---------------------------------------------------------------------------- | |
| class sc_int_bitref : public sc_int_bitref_r | |
| { | |
| friend class sc_int_base; | |
| friend class sc_core::sc_vpool<sc_int_bitref>; | |
| // constructor | |
| sc_int_bitref() : sc_int_bitref_r() {} | |
| public: | |
| // copy constructor | |
| sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {} | |
| // assignment operators | |
| sc_int_bitref &operator = (const sc_int_bitref_r &b); | |
| sc_int_bitref &operator = (const sc_int_bitref &b); | |
| sc_int_bitref &operator = (bool b); | |
| sc_int_bitref &operator &= (bool b); | |
| sc_int_bitref &operator |= (bool b); | |
| sc_int_bitref &operator ^= (bool b); | |
| // concatenation methods | |
| virtual void concat_set(int64 src, int low_i); | |
| virtual void concat_set(const sc_signed &src, int low_i); | |
| virtual void concat_set(const sc_unsigned &src, int low_i); | |
| virtual void concat_set(uint64 src, int low_i); | |
| // other methods | |
| void scan(::std::istream &is=::std::cin); | |
| public: | |
| static sc_core::sc_vpool<sc_int_bitref> m_pool; | |
| }; | |
| inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_subref_r | |
| // | |
| // Proxy class for sc_int part selection (r-value only). | |
| // ---------------------------------------------------------------------------- | |
| class sc_int_subref_r : public sc_value_base | |
| { | |
| friend class sc_int_base; | |
| friend class sc_int_signal; | |
| friend class sc_int_subref; | |
| protected: | |
| // constructor | |
| sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {} | |
| // initializer for sc_core::sc_vpool: | |
| void initialize( const sc_int_base *obj_p, int left_i, int right_i) | |
| { | |
| m_obj_p = (sc_int_base *)obj_p; | |
| m_left = left_i; | |
| m_right = right_i; | |
| } | |
| public: | |
| // copy constructor | |
| sc_int_subref_r(const sc_int_subref_r &a) : | |
| sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p), | |
| m_right(a.m_right) | |
| {} | |
| // destructor | |
| virtual ~sc_int_subref_r() {} | |
| // capacity | |
| int length() const { return (m_left - m_right + 1); } | |
| // concatenation support | |
| virtual int | |
| concat_length(bool *xz_present_p) const | |
| { | |
| if (xz_present_p) | |
| *xz_present_p = false; | |
| return length(); | |
| } | |
| virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; | |
| virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; | |
| virtual uint64 | |
| concat_get_uint64() const | |
| { | |
| int len = length(); | |
| uint64 val = operator uint_type(); | |
| if (len < 64) | |
| return (uint64)(val & ~((uint_type)-1 << len)); | |
| else | |
| return (uint64)val; | |
| } | |
| // reduce methods | |
| bool and_reduce() const; | |
| bool nand_reduce() const { return !and_reduce(); } | |
| bool or_reduce() const; | |
| bool nor_reduce() const { return !or_reduce(); } | |
| bool xor_reduce() const; | |
| bool xnor_reduce() const { return !xor_reduce(); } | |
| // implicit conversion to uint_type | |
| operator uint_type () const; | |
| // explicit conversions | |
| uint_type value() const { return operator uint_type(); } | |
| int to_int() const; | |
| unsigned int to_uint() const; | |
| long to_long() const; | |
| unsigned long to_ulong() const; | |
| int64 to_int64() const; | |
| uint64 to_uint64() const; | |
| double to_double() const; | |
| // explicit conversion to character string | |
| const std::string to_string(sc_numrep numrep=SC_DEC) const; | |
| const std::string to_string(sc_numrep numrep, bool w_prefix) const; | |
| // other methods | |
| void | |
| print(::std::ostream &os=::std::cout) const | |
| { | |
| os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); | |
| } | |
| protected: | |
| int m_left; | |
| sc_int_base *m_obj_p; | |
| int m_right; | |
| private: | |
| const sc_int_subref_r &operator = (const sc_int_subref_r &); | |
| }; | |
| inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_subref | |
| // | |
| // Proxy class for sc_int part selection (r-value and l-value). | |
| // ---------------------------------------------------------------------------- | |
| class sc_int_subref : public sc_int_subref_r | |
| { | |
| friend class sc_int_base; | |
| friend class sc_core::sc_vpool<sc_int_subref>; | |
| protected: | |
| // constructor | |
| sc_int_subref() : sc_int_subref_r() {} | |
| public: | |
| // copy constructor | |
| sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {} | |
| // assignment operators | |
| sc_int_subref &operator = (int_type v); | |
| sc_int_subref &operator = (const sc_int_base &a); | |
| sc_int_subref & | |
| operator = (const sc_int_subref_r &a) | |
| { | |
| return operator = (a.operator uint_type()); | |
| } | |
| sc_int_subref & | |
| operator = (const sc_int_subref &a) | |
| { | |
| return operator = (a.operator uint_type()); | |
| } | |
| template< class T > | |
| sc_int_subref & | |
| operator = (const sc_generic_base<T> &a) | |
| { | |
| return operator = (a->to_int64()); | |
| } | |
| sc_int_subref &operator = (const char *a); | |
| sc_int_subref & | |
| operator = (unsigned long a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref & | |
| operator = (long a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref & | |
| operator = (unsigned int a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref & | |
| operator = (int a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref & | |
| operator = (uint64 a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref & | |
| operator = (double a) | |
| { | |
| return operator = ((int_type)a); | |
| } | |
| sc_int_subref &operator = (const sc_signed &); | |
| sc_int_subref &operator = (const sc_unsigned &); | |
| sc_int_subref &operator = (const sc_bv_base &); | |
| sc_int_subref &operator = (const sc_lv_base &); | |
| // concatenation methods | |
| virtual void concat_set(int64 src, int low_i); | |
| virtual void concat_set(const sc_signed &src, int low_i); | |
| virtual void concat_set(const sc_unsigned &src, int low_i); | |
| virtual void concat_set(uint64 src, int low_i); | |
| // other methods | |
| void scan(::std::istream &is=::std::cin); | |
| public: | |
| static sc_core::sc_vpool<sc_int_subref> m_pool; | |
| }; | |
| inline ::std::istream &operator >> (::std::istream &, sc_int_subref &); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_base | |
| // | |
| // Base class for sc_int. | |
| // ---------------------------------------------------------------------------- | |
| class sc_int_base : public sc_value_base | |
| { | |
| friend class sc_int_bitref_r; | |
| friend class sc_int_bitref; | |
| friend class sc_int_subref_r; | |
| friend class sc_int_subref; | |
| // support methods | |
| void invalid_length() const; | |
| void invalid_index(int i) const; | |
| void invalid_range(int l, int r) const; | |
| void | |
| check_length() const | |
| { | |
| if (m_len <= 0 || m_len > SC_INTWIDTH) { | |
| invalid_length(); | |
| } | |
| } | |
| void | |
| check_index(int i) const | |
| { | |
| if (i < 0 || i >= m_len) { | |
| invalid_index(i); | |
| } | |
| } | |
| void | |
| check_range(int l, int r) const | |
| { | |
| if (r < 0 || l >= m_len || l < r) { | |
| invalid_range(l, r); | |
| } | |
| } | |
| void check_value() const; | |
| void | |
| extend_sign() | |
| { | |
| #ifdef DEBUG_SYSTEMC | |
| check_value(); | |
| #endif | |
| m_val = (m_val << m_ulen >> m_ulen); | |
| } | |
| public: | |
| // constructors | |
| explicit sc_int_base(int w=sc_length_param().len()) : | |
| m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len) | |
| { | |
| check_length(); | |
| } | |
| sc_int_base(int_type v, int w) : | |
| m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len) | |
| { | |
| check_length(); | |
| extend_sign(); | |
| } | |
| sc_int_base(const sc_int_base &a) : | |
| sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) | |
| {} | |
| explicit sc_int_base(const sc_int_subref_r &a) : | |
| m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len) | |
| { | |
| extend_sign(); | |
| } | |
| template< class T > | |
| explicit sc_int_base(const sc_generic_base<T> &a) : | |
| m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len) | |
| { | |
| check_length(); | |
| extend_sign(); | |
| } | |
| explicit sc_int_base(const sc_signed &a); | |
| explicit sc_int_base(const sc_unsigned &a); | |
| explicit sc_int_base(const sc_bv_base &v); | |
| explicit sc_int_base(const sc_lv_base &v); | |
| explicit sc_int_base(const sc_uint_subref_r &v); | |
| explicit sc_int_base(const sc_signed_subref_r &v); | |
| explicit sc_int_base(const sc_unsigned_subref_r &v); | |
| // destructor | |
| virtual ~sc_int_base() {} | |
| // assignment operators | |
| sc_int_base & | |
| operator = (int_type v) | |
| { | |
| m_val = v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (const sc_int_base &a) | |
| { | |
| m_val = a.m_val; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (const sc_int_subref_r &a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| template<class T> | |
| sc_int_base & | |
| operator = (const sc_generic_base<T> &a) | |
| { | |
| m_val = a->to_int64(); | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base &operator = (const sc_signed &a); | |
| sc_int_base &operator = (const sc_unsigned &a); | |
| sc_int_base &operator = (const sc_fxval &a); | |
| sc_int_base &operator = (const sc_fxval_fast &a); | |
| sc_int_base &operator = (const sc_fxnum &a); | |
| sc_int_base &operator = (const sc_fxnum_fast &a); | |
| sc_int_base &operator = (const sc_bv_base &a); | |
| sc_int_base &operator = (const sc_lv_base &a); | |
| sc_int_base &operator = (const char *a); | |
| sc_int_base & | |
| operator = (unsigned long a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (long a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (unsigned int a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (int a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (uint64 a) | |
| { | |
| m_val = a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator = (double a) | |
| { | |
| m_val = (int_type)a; | |
| extend_sign(); | |
| return *this; | |
| } | |
| // arithmetic assignment operators | |
| sc_int_base & | |
| operator += (int_type v) | |
| { | |
| m_val += v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator -= (int_type v) | |
| { | |
| m_val -= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator *= (int_type v) | |
| { | |
| m_val *= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator /= (int_type v) | |
| { | |
| m_val /= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator %= (int_type v) | |
| { | |
| m_val %= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| // bitwise assignment operators | |
| sc_int_base & | |
| operator &= (int_type v) | |
| { | |
| m_val &= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator |= (int_type v) | |
| { | |
| m_val |= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator ^= (int_type v) | |
| { | |
| m_val ^= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator <<= (int_type v) | |
| { | |
| m_val <<= v; | |
| extend_sign(); | |
| return *this; | |
| } | |
| sc_int_base & | |
| operator >>= (int_type v) | |
| { | |
| m_val >>= v; | |
| /* no sign extension needed */ | |
| return *this; | |
| } | |
| // prefix and postfix increment and decrement operators | |
| sc_int_base & | |
| operator ++ () // prefix | |
| { | |
| ++m_val; | |
| extend_sign(); | |
| return *this; | |
| } | |
| const sc_int_base | |
| operator ++ (int) // postfix | |
| { | |
| sc_int_base tmp(*this); | |
| ++m_val; | |
| extend_sign(); | |
| return tmp; | |
| } | |
| sc_int_base & | |
| operator -- () // prefix | |
| { | |
| --m_val; | |
| extend_sign(); | |
| return *this; | |
| } | |
| const sc_int_base | |
| operator -- ( int ) // postfix | |
| { | |
| sc_int_base tmp(*this); | |
| --m_val; | |
| extend_sign(); | |
| return tmp; | |
| } | |
| // relational operators | |
| friend bool | |
| operator == (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val == b.m_val; | |
| } | |
| friend bool | |
| operator != (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val != b.m_val; | |
| } | |
| friend bool | |
| operator < (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val < b.m_val; | |
| } | |
| friend bool | |
| operator <= (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val <= b.m_val; | |
| } | |
| friend bool | |
| operator > (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val > b.m_val; | |
| } | |
| friend bool | |
| operator >= (const sc_int_base &a, const sc_int_base &b) | |
| { | |
| return a.m_val >= b.m_val; | |
| } | |
| // bit selection | |
| sc_int_bitref &operator [] (int i); | |
| const sc_int_bitref_r &operator [] (int i) const; | |
| sc_int_bitref &bit(int i); | |
| const sc_int_bitref_r &bit(int i) const; | |
| // part selection | |
| sc_int_subref &operator () (int left, int right); | |
| const sc_int_subref_r &operator () (int left, int right) const; | |
| sc_int_subref &range(int left, int right); | |
| const sc_int_subref_r &range(int left, int right) const; | |
| // bit access, without bounds checking or sign extension | |
| bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); } | |
| void set(int i) { m_val |= (UINT_ONE << i); } | |
| void | |
| set(int i, bool v) | |
| { | |
| v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); | |
| } | |
| // capacity | |
| int length() const { return m_len; } | |
| // concatenation support | |
| virtual int | |
| concat_length(bool* xz_present_p) const | |
| { | |
| if (xz_present_p) | |
| *xz_present_p = false; | |
| return length(); | |
| } | |
| virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; | |
| virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; | |
| virtual uint64 | |
| concat_get_uint64() const | |
| { | |
| if (m_len < 64) | |
| return (uint64)(m_val & ~((uint_type) - 1 << m_len)); | |
| else | |
| return (uint64)m_val; | |
| } | |
| virtual void concat_set(int64 src, int low_i); | |
| virtual void concat_set(const sc_signed &src, int low_i); | |
| virtual void concat_set(const sc_unsigned &src, int low_i); | |
| virtual void concat_set(uint64 src, int low_i); | |
| // reduce methods | |
| bool and_reduce() const; | |
| bool nand_reduce() const { return !and_reduce(); } | |
| bool or_reduce() const; | |
| bool nor_reduce() const { return !or_reduce(); } | |
| bool xor_reduce() const; | |
| bool xnor_reduce() const { return !xor_reduce(); } | |
| // implicit conversion to int_type | |
| operator int_type() const { return m_val; } | |
| // explicit conversions | |
| int_type value() const { return operator int_type(); } | |
| int to_int() const { return (int)m_val; } | |
| unsigned int to_uint() const { return (unsigned int)m_val; } | |
| long to_long() const { return (long)m_val; } | |
| unsigned long to_ulong() const { return (unsigned long)m_val; } | |
| int64 to_int64() const { return (int64)m_val; } | |
| uint64 to_uint64() const { return (uint64)m_val; } | |
| double to_double() const { return (double)m_val; } | |
| long long_low() const { return (long)(m_val & UINT64_32ONES); } | |
| long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); } | |
| // explicit conversion to character string | |
| const std::string to_string(sc_numrep numrep=SC_DEC) const; | |
| const std::string to_string(sc_numrep numrep, bool w_prefix) const; | |
| // other methods | |
| void | |
| print(::std::ostream &os=::std::cout) const | |
| { | |
| os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); | |
| } | |
| void scan(::std::istream &is=::std::cin); | |
| protected: | |
| int_type m_val; // value | |
| int m_len; // length | |
| int m_ulen; // unused length | |
| }; | |
| inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &); | |
| inline ::std::istream &operator >> (::std::istream &, sc_int_base &); | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_bitref_r | |
| // | |
| // Proxy class for sc_int bit selection (r-value only). | |
| // ---------------------------------------------------------------------------- | |
| // implicit conversion to uint64 | |
| inline sc_int_bitref_r::operator uint64 () const | |
| { | |
| return m_obj_p->test(m_index); | |
| } | |
| inline bool | |
| sc_int_bitref_r::operator ! () const | |
| { | |
| return ! m_obj_p->test(m_index); | |
| } | |
| inline bool | |
| sc_int_bitref_r::operator ~ () const | |
| { | |
| return !m_obj_p->test(m_index); | |
| } | |
| inline ::std::ostream & | |
| operator << (::std::ostream &os, const sc_int_bitref_r &a) | |
| { | |
| a.print(os); | |
| return os; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_bitref | |
| // | |
| // Proxy class for sc_int bit selection (r-value and l-value). | |
| // ---------------------------------------------------------------------------- | |
| // assignment operators | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator = (const sc_int_bitref_r &b) | |
| { | |
| m_obj_p->set(m_index, (bool)b); | |
| m_obj_p->extend_sign(); | |
| return *this; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator = (const sc_int_bitref &b) | |
| { | |
| m_obj_p->set(m_index, (bool)b); | |
| m_obj_p->extend_sign(); | |
| return *this; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator = (bool b) | |
| { | |
| m_obj_p->set(m_index, b); | |
| m_obj_p->extend_sign(); | |
| return *this; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator &= (bool b) | |
| { | |
| if (!b) { | |
| m_obj_p->set(m_index, b); | |
| m_obj_p->extend_sign(); | |
| } | |
| return *this; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator |= (bool b) | |
| { | |
| if (b) { | |
| m_obj_p->set(m_index, b); | |
| m_obj_p->extend_sign(); | |
| } | |
| return *this; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_bitref::operator ^= (bool b) | |
| { | |
| if (b) { | |
| m_obj_p->m_val ^= (UINT_ONE << m_index); | |
| m_obj_p->extend_sign(); | |
| } | |
| return *this; | |
| } | |
| inline ::std::istream & | |
| operator >> (::std::istream &is, sc_int_bitref &a) | |
| { | |
| a.scan(is); | |
| return is; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_subref_r | |
| // | |
| // Proxy class for sc_int part selection (r-value only). | |
| // ---------------------------------------------------------------------------- | |
| // implicit conversion to int_type | |
| inline sc_int_subref_r::operator uint_type() const | |
| { | |
| uint_type /*int_type*/ val = m_obj_p->m_val; | |
| int uleft = SC_INTWIDTH - (m_left + 1); | |
| int uright = uleft + m_right; | |
| return (val << uleft >> uright); | |
| } | |
| // reduce methods | |
| inline bool | |
| sc_int_subref_r::and_reduce() const | |
| { | |
| sc_int_base a(*this); | |
| return a.and_reduce(); | |
| } | |
| inline bool | |
| sc_int_subref_r::or_reduce() const | |
| { | |
| sc_int_base a(*this); | |
| return a.or_reduce(); | |
| } | |
| inline bool | |
| sc_int_subref_r::xor_reduce() const | |
| { | |
| sc_int_base a(*this); | |
| return a.xor_reduce(); | |
| } | |
| // explicit conversions | |
| inline int | |
| sc_int_subref_r::to_int() const | |
| { | |
| int result = static_cast<int>(operator uint_type()); | |
| return result; | |
| } | |
| inline unsigned int | |
| sc_int_subref_r::to_uint() const | |
| { | |
| unsigned int result = static_cast<unsigned int>(operator uint_type()); | |
| return result; | |
| } | |
| inline long | |
| sc_int_subref_r::to_long() const | |
| { | |
| long result = static_cast<long>(operator uint_type()); | |
| return result; | |
| } | |
| inline unsigned long | |
| sc_int_subref_r::to_ulong() const | |
| { | |
| unsigned long result = static_cast<unsigned long>(operator uint_type()); | |
| return result; | |
| } | |
| inline int64 | |
| sc_int_subref_r::to_int64() const | |
| { | |
| int64 result = operator uint_type(); | |
| return result; | |
| } | |
| inline uint64 | |
| sc_int_subref_r::to_uint64() const | |
| { | |
| uint64 result = operator uint_type(); | |
| return result; | |
| } | |
| inline double | |
| sc_int_subref_r::to_double() const | |
| { | |
| double result = static_cast<double>(operator uint_type()); | |
| return result; | |
| } | |
| // explicit conversion to character string | |
| inline const std::string | |
| sc_int_subref_r::to_string(sc_numrep numrep) const | |
| { | |
| sc_uint_base a(length()); | |
| a = operator uint_type(); | |
| return a.to_string(numrep); | |
| } | |
| inline const std::string | |
| sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const | |
| { | |
| sc_uint_base a(length()); | |
| a = operator uint_type(); | |
| return a.to_string(numrep, w_prefix); | |
| } | |
| // functional notation for the reduce methods | |
| inline bool | |
| and_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.and_reduce(); | |
| } | |
| inline bool | |
| nand_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.nand_reduce(); | |
| } | |
| inline bool | |
| or_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.or_reduce(); | |
| } | |
| inline bool | |
| nor_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.nor_reduce(); | |
| } | |
| inline bool | |
| xor_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.xor_reduce(); | |
| } | |
| inline bool | |
| xnor_reduce(const sc_int_subref_r &a) | |
| { | |
| return a.xnor_reduce(); | |
| } | |
| inline ::std::ostream & | |
| operator << (::std::ostream &os, const sc_int_subref_r &a) | |
| { | |
| a.print(os); | |
| return os; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_subref | |
| // | |
| // Proxy class for sc_int part selection (r-value and l-value). | |
| // ---------------------------------------------------------------------------- | |
| // assignment operators | |
| inline sc_int_subref & | |
| sc_int_subref::operator = (const sc_int_base &a) | |
| { | |
| return operator = (a.operator int_type()); | |
| } | |
| inline sc_int_subref & | |
| sc_int_subref::operator = (const char *a) | |
| { | |
| sc_int_base aa(length()); | |
| return (*this = aa = a); | |
| } | |
| inline ::std::istream & | |
| operator >> (::std::istream &is, sc_int_subref &a) | |
| { | |
| a.scan(is); | |
| return is; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS : sc_int_base | |
| // | |
| // Base class for sc_int. | |
| // ---------------------------------------------------------------------------- | |
| // bit selection | |
| inline sc_int_bitref & | |
| sc_int_base::operator [] (int i) | |
| { | |
| check_index(i); | |
| sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); | |
| result_p->initialize(this, i); | |
| return *result_p; | |
| } | |
| inline const sc_int_bitref_r & | |
| sc_int_base::operator [] (int i) const | |
| { | |
| check_index(i); | |
| sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); | |
| result_p->initialize(this, i); | |
| return *result_p; | |
| } | |
| inline sc_int_bitref & | |
| sc_int_base::bit(int i) | |
| { | |
| check_index(i); | |
| sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); | |
| result_p->initialize(this, i); | |
| return *result_p; | |
| } | |
| inline const sc_int_bitref_r & | |
| sc_int_base::bit(int i) const | |
| { | |
| check_index(i); | |
| sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); | |
| result_p->initialize(this, i); | |
| return *result_p; | |
| } | |
| // part selection | |
| inline sc_int_subref & | |
| sc_int_base::operator () (int left, int right) | |
| { | |
| check_range(left, right); | |
| sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); | |
| result_p->initialize(this, left, right); | |
| return *result_p; | |
| } | |
| inline const sc_int_subref_r & | |
| sc_int_base::operator () (int left, int right) const | |
| { | |
| check_range(left, right); | |
| sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); | |
| result_p->initialize(this, left, right); | |
| return *result_p; | |
| } | |
| inline sc_int_subref & | |
| sc_int_base::range(int left, int right) | |
| { | |
| check_range(left, right); | |
| sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); | |
| result_p->initialize(this, left, right); | |
| return *result_p; | |
| } | |
| inline const sc_int_subref_r & | |
| sc_int_base::range(int left, int right) const | |
| { | |
| check_range(left, right); | |
| sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); | |
| result_p->initialize(this, left, right); | |
| return *result_p; | |
| } | |
| // functional notation for the reduce methods | |
| inline bool | |
| and_reduce(const sc_int_base &a) | |
| { | |
| return a.and_reduce(); | |
| } | |
| inline bool | |
| nand_reduce(const sc_int_base &a) | |
| { | |
| return a.nand_reduce(); | |
| } | |
| inline bool | |
| or_reduce(const sc_int_base &a) | |
| { | |
| return a.or_reduce(); | |
| } | |
| inline bool | |
| nor_reduce(const sc_int_base &a) | |
| { | |
| return a.nor_reduce(); | |
| } | |
| inline bool | |
| xor_reduce(const sc_int_base &a) | |
| { | |
| return a.xor_reduce(); | |
| } | |
| inline bool | |
| xnor_reduce(const sc_int_base &a) | |
| { | |
| return a.xnor_reduce(); | |
| } | |
| inline ::std::ostream & | |
| operator << (::std::ostream &os, const sc_int_base &a) | |
| { | |
| a.print(os); | |
| return os; | |
| } | |
| inline ::std::istream & | |
| operator >> (::std::istream &is, sc_int_base &a) | |
| { | |
| a.scan(is); | |
| return is; | |
| } | |
| } // namespace sc_dt | |
| #endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ |