| /***************************************************************************** | |
| 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_concatref.h -- Concatenation support. | |
| Original Author: Andy Goodrich, Forte Design, Inc. | |
| *****************************************************************************/ | |
| /***************************************************************************** | |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and | |
| changes you are making here. | |
| Name, Affiliation, Date: | |
| Description of Modification: | |
| Andy Goodrich, Forte Design Systems, 17 Nov 2002 | |
| Creation of sc_concatref class by merging the capabilities of | |
| sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref, | |
| and implementing the capabilities of sc_signed_concref, sc_signed_concref, | |
| sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows | |
| mixed mode concatenations on the left and right sides of an assignment. | |
| *****************************************************************************/ | |
| // $Log: sc_concatref.h,v $ | |
| // Revision 1.6 2011/08/24 22:05:48 acg | |
| // Torsten Maehne: initialization changes to remove warnings. | |
| // | |
| // Revision 1.5 2009/11/17 19:58:15 acg | |
| // Andy Goodrich: fix of shift rhs possibilities to include "int". | |
| // | |
| // Revision 1.4 2009/02/28 00:26:29 acg | |
| // Andy Goodrich: bug fixes. | |
| // | |
| // Revision 1.3 2008/04/29 20:23:55 acg | |
| // Andy Goodrich: fixed the code that assigns the value of a string to | |
| // an sc_concatref instance. | |
| // | |
| // Revision 1.2 2008/02/14 20:57:26 acg | |
| // Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy. | |
| // | |
| // Revision 1.1.1.1 2006/12/15 20:20:05 acg | |
| // SystemC 2.3 | |
| // | |
| // Revision 1.4 2006/10/23 19:36:59 acg | |
| // Andy Goodrich: changed casts for operations on concatenation values to | |
| // mirror those of sc_unsigned. For instance, an sc_unsigned minus a value | |
| // returns an sc_signed result, whereas an sc_concatref minus a value was | |
| // returning an sc_unsigned result. Now both sc_unsigned and sc_concatref | |
| // minus a value return an sc_signed result. | |
| // | |
| // Revision 1.3 2006/01/13 18:54:01 acg | |
| // Andy Goodrich: added $Log command so that CVS comments are reproduced in | |
| // the source. | |
| // | |
| #ifndef __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__ | |
| #define __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__ | |
| #include <iostream> | |
| #include "../bit/sc_bv.hh" | |
| #include "../bit/sc_lv.hh" | |
| #include "../int/sc_int_base.hh" | |
| #include "../int/sc_signed.hh" | |
| #include "../int/sc_uint_base.hh" | |
| #include "../int/sc_unsigned.hh" | |
| #include "../sc_temporary.hh" | |
| #include "sc_value_base.hh" | |
| namespace sc_dt | |
| { | |
| // classes defined in this module | |
| class sc_concatref; | |
| class sc_concat_bool; | |
| } // namespace sc_dt | |
| namespace sc_core | |
| { | |
| extern sc_byte_heap sc_temp_heap; // Temporary storage. | |
| // explicit template instantiations | |
| extern template class sc_vpool<sc_dt::sc_concatref>; | |
| extern template class sc_vpool<sc_dt::sc_concat_bool>; | |
| } // namespace sc_core | |
| namespace sc_dt { | |
| // ---------------------------------------------------------------------------- | |
| // CLASS TEMPLATE : sc_concatref | |
| // | |
| // Proxy class for sized bit concatenation. | |
| // ---------------------------------------------------------------------------- | |
| class sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base | |
| { | |
| public: | |
| friend class sc_core::sc_vpool<sc_concatref>; | |
| inline void | |
| initialize(sc_value_base &left, sc_value_base &right) | |
| { | |
| bool left_xz; // True if x's and/or z's found in left. | |
| bool right_xz; // True if x's and/or z's found in right. | |
| m_left_p = (sc_value_base *)&left; | |
| m_right_p = (sc_value_base *)&right; | |
| m_len_r = right.concat_length(&right_xz); | |
| m_len = left.concat_length(&left_xz) + m_len_r; | |
| m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none; | |
| } | |
| inline void | |
| initialize(const sc_value_base &left, const sc_value_base &right) | |
| { | |
| bool left_xz; // True if x's and/or z's found in left. | |
| bool right_xz; // True if x's and/or z's found in right. | |
| m_left_p = (sc_value_base *)&left; | |
| m_right_p = (sc_value_base *)&right; | |
| m_len_r = right.concat_length(&right_xz); | |
| m_len = left.concat_length(&left_xz) + m_len_r; | |
| m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none; | |
| } | |
| // destructor | |
| virtual ~sc_concatref() {} | |
| // capacity | |
| unsigned int length() const { return m_len; } | |
| // concatenation | |
| virtual int | |
| concat_length(bool *xz_present_p) const | |
| { | |
| if (xz_present_p) | |
| *xz_present_p = m_flags & cf_xz_present ? true : false; | |
| return m_len; | |
| } | |
| virtual void | |
| concat_clear_data(bool to_ones) | |
| { | |
| m_left_p->concat_clear_data(to_ones); | |
| m_right_p->concat_clear_data(to_ones); | |
| } | |
| virtual bool | |
| concat_get_ctrl(sc_digit *dst_p, int low_i) const | |
| { | |
| bool rnz = m_right_p->concat_get_ctrl(dst_p, low_i); | |
| bool lnz = m_left_p->concat_get_ctrl(dst_p, low_i + m_len_r); | |
| return rnz || lnz; | |
| } | |
| virtual bool | |
| concat_get_data(sc_digit *dst_p, int low_i) const | |
| { | |
| bool rnz = m_right_p->concat_get_data(dst_p, low_i); | |
| bool lnz = m_left_p->concat_get_data(dst_p, low_i + m_len_r); | |
| return rnz || lnz; | |
| } | |
| virtual uint64 | |
| concat_get_uint64() const | |
| { | |
| if (m_len_r >= 64) { | |
| return m_right_p->concat_get_uint64(); | |
| } else { | |
| return (m_left_p->concat_get_uint64() << m_len_r) | | |
| m_right_p->concat_get_uint64(); | |
| } | |
| } | |
| virtual void | |
| concat_set(int64 src, int low_i) | |
| { | |
| m_right_p->concat_set(src, low_i); | |
| m_left_p->concat_set(src, low_i + m_len_r); | |
| } | |
| virtual void | |
| concat_set(const sc_signed &src, int low_i) | |
| { | |
| m_right_p->concat_set(src, low_i); | |
| m_left_p->concat_set(src, low_i + m_len_r); | |
| } | |
| virtual void | |
| concat_set(const sc_unsigned &src, int low_i) | |
| { | |
| m_right_p->concat_set(src, low_i); | |
| m_left_p->concat_set(src, low_i + m_len_r); | |
| } | |
| virtual void | |
| concat_set(uint64 src, int low_i) | |
| { | |
| m_right_p->concat_set(src, low_i); | |
| m_left_p->concat_set(src, low_i + m_len_r); | |
| } | |
| // explicit conversions | |
| uint64 | |
| to_uint64() const | |
| { | |
| uint64 mask; | |
| uint64 result; | |
| result = m_right_p->concat_get_uint64(); | |
| if (m_len_r < 64) { | |
| mask = (uint64)~0; | |
| result = (m_left_p->concat_get_uint64() << m_len_r) | | |
| (result & ~(mask << m_len_r)); | |
| } | |
| if (m_len < 64) { | |
| mask = (uint64)~0; | |
| result = result & ~(mask << m_len); | |
| } | |
| return result; | |
| } | |
| const sc_unsigned & | |
| value() const | |
| { | |
| bool left_non_zero; | |
| sc_unsigned *result_p = sc_unsigned::m_pool.allocate(); | |
| bool right_non_zero; | |
| result_p->nbits = result_p->num_bits(m_len); | |
| result_p->ndigits = DIV_CEIL(result_p->nbits); | |
| result_p->digit = (sc_digit *)sc_core::sc_temp_heap.allocate( | |
| sizeof(sc_digit) * result_p->ndigits); | |
| result_p->digit[result_p->ndigits - 1] = 0; | |
| right_non_zero = m_right_p->concat_get_data(result_p->digit, 0); | |
| left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r); | |
| if (left_non_zero || right_non_zero) | |
| result_p->sgn = SC_POS; | |
| else | |
| result_p->sgn = SC_ZERO; | |
| return *result_p; | |
| } | |
| int64 to_int64() const { return (int64)to_uint64(); } | |
| int to_int() const { return (int)to_int64(); } | |
| unsigned int to_uint() const { return (unsigned int)to_uint64(); } | |
| long to_long() const { return (long)to_int64(); } | |
| unsigned long to_ulong() const { return (unsigned long)to_uint64(); } | |
| double to_double() const { return value().to_double(); } | |
| void to_sc_signed(sc_signed &target) const { target = value(); } | |
| void to_sc_unsigned(sc_unsigned &target) const { target = value(); } | |
| // implicit conversions: | |
| operator uint64 () const { return to_uint64(); } | |
| operator const sc_unsigned & () const { return value(); } | |
| // unary operators: | |
| sc_unsigned operator + () const { return value(); } | |
| sc_signed operator - () const { return -value(); } | |
| sc_unsigned operator ~ () const { return ~value(); } | |
| // explicit conversion to character string | |
| const std::string | |
| to_string(sc_numrep numrep=SC_DEC) const | |
| { | |
| return value().to_string(numrep); | |
| } | |
| const std::string | |
| to_string(sc_numrep numrep, bool w_prefix) const | |
| { | |
| return value().to_string(numrep,w_prefix); | |
| } | |
| // assignments | |
| inline const sc_concatref & | |
| operator = (int v) | |
| { | |
| m_right_p->concat_set((int64)v, 0); | |
| m_left_p->concat_set((int64)v, m_len_r); | |
| return *this; | |
| } | |
| inline const sc_concatref & | |
| operator = (long v) | |
| { | |
| m_right_p->concat_set((int64)v, 0); | |
| m_left_p->concat_set((int64)v, m_len_r); | |
| return *this; | |
| } | |
| inline const sc_concatref & | |
| operator = (int64 v) | |
| { | |
| m_right_p->concat_set(v, 0); | |
| m_left_p->concat_set(v, m_len_r); | |
| return *this; | |
| } | |
| inline const sc_concatref & | |
| operator = (unsigned int v) | |
| { | |
| m_right_p->concat_set((uint64)v, 0); | |
| m_left_p->concat_set((uint64)v, m_len_r); | |
| return *this; | |
| } | |
| inline const sc_concatref & | |
| operator = (unsigned long v) | |
| { | |
| m_right_p->concat_set((uint64)v, 0); | |
| m_left_p->concat_set((uint64)v, m_len_r); | |
| return *this; | |
| } | |
| inline const sc_concatref & | |
| operator = (uint64 v) | |
| { | |
| m_right_p->concat_set(v, 0); | |
| m_left_p->concat_set(v, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const sc_concatref &v) | |
| { | |
| sc_unsigned temp(v.length()); | |
| temp = v.value(); | |
| m_right_p->concat_set(temp, 0); | |
| m_left_p->concat_set(temp, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const sc_signed &v) | |
| { | |
| m_right_p->concat_set(v, 0); | |
| m_left_p->concat_set(v, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const sc_unsigned &v) | |
| { | |
| m_right_p->concat_set(v, 0); | |
| m_left_p->concat_set(v, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const char *v_p) | |
| { | |
| sc_unsigned v(m_len); | |
| v = v_p; | |
| m_right_p->concat_set(v, 0); | |
| m_left_p->concat_set(v, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const sc_bv_base &v) | |
| { | |
| sc_unsigned temp(v.length()); | |
| temp = v; | |
| m_right_p->concat_set(temp, 0); | |
| m_left_p->concat_set(temp, m_len_r); | |
| return *this; | |
| } | |
| const sc_concatref & | |
| operator = (const sc_lv_base &v) | |
| { | |
| sc_unsigned data(v.length()); | |
| data = v; | |
| m_right_p->concat_set(data, 0); | |
| m_left_p->concat_set(data, m_len_r); | |
| return *this; | |
| } | |
| // reduce methods | |
| bool and_reduce() const { return value().and_reduce(); } | |
| bool nand_reduce() const { return value().nand_reduce(); } | |
| bool or_reduce() const { return value().or_reduce(); } | |
| bool nor_reduce() const { return value().nor_reduce(); } | |
| bool xor_reduce() const { return value().xor_reduce(); } | |
| bool xnor_reduce() const { return value().xnor_reduce(); } | |
| // other methods | |
| void print(::std::ostream &os=::std::cout) const { os << this->value(); } | |
| void | |
| scan(::std::istream &is) | |
| { | |
| std::string s; | |
| is >> s; | |
| *this = s.c_str(); | |
| } | |
| public: | |
| // Pool of temporary objects. | |
| static sc_core::sc_vpool<sc_concatref> m_pool; | |
| public: | |
| enum concat_flags { | |
| cf_none = 0, // Normal value. | |
| cf_xz_present = 1 // X and/or Z values present. | |
| }; | |
| protected: | |
| sc_value_base *m_left_p; // Left hand operand of concatenation. | |
| sc_value_base *m_right_p; // Right hand operand of concatenation. | |
| int m_len; // Length of concatenation. | |
| int m_len_r; // Length of m_rightt_p. | |
| concat_flags m_flags; // Value is read only. | |
| private: | |
| sc_concatref(const sc_concatref &); | |
| sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags() | |
| {} | |
| }; | |
| // functional notation for the reduce methods | |
| inline bool and_reduce(const sc_concatref &a) { return a.and_reduce(); } | |
| inline bool nand_reduce(const sc_concatref &a) { return a.nand_reduce(); } | |
| inline bool or_reduce(const sc_concatref &a) { return a.or_reduce(); } | |
| inline bool nor_reduce(const sc_concatref &a) { return a.nor_reduce(); } | |
| inline bool xor_reduce(const sc_concatref &a) { return a.xor_reduce(); } | |
| inline bool xnor_reduce(const sc_concatref &a) { return a.xnor_reduce(); } | |
| // SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES: | |
| // | |
| // Because sc_concatref has implicit casts to both uint64 and sc_unsigned | |
| // it is necessary to disambiguate the use of the shift operators. We do | |
| // this in favor of sc_unsigned so that precision is not lost. To get an | |
| // integer-based result use a cast to uint64 before performing the shift. | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, uint64 shift) | |
| { | |
| return target.value() << (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, int64 shift) | |
| { | |
| return target.value() << (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, unsigned long shift) | |
| { | |
| return target.value() << (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, int shift) | |
| { | |
| return target.value() << shift; | |
| } | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, unsigned int shift) | |
| { | |
| return target.value() << (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator << (const sc_concatref &target, long shift) | |
| { | |
| return target.value() << (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, uint64 shift) | |
| { | |
| return target.value() >> (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, int64 shift) | |
| { | |
| return target.value() >> (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, unsigned long shift) | |
| { | |
| return target.value() >> (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, int shift) | |
| { | |
| return target.value() >> shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, unsigned int shift) | |
| { | |
| return target.value() >> (int)shift; | |
| } | |
| inline const sc_unsigned | |
| operator >> (const sc_concatref &target, long shift) | |
| { | |
| return target.value() >> (int)shift; | |
| } | |
| // STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES: | |
| inline ::std::ostream & | |
| operator << (::std::ostream &os, const sc_concatref &v) | |
| { | |
| return os << v.value(); | |
| } | |
| inline ::std::istream & | |
| operator >> (::std::istream &is, sc_concatref &a) | |
| { | |
| sc_unsigned temp(a.concat_length(0)); | |
| temp.scan(is); | |
| a = temp; | |
| return is; | |
| } | |
| // ---------------------------------------------------------------------------- | |
| // CLASS TEMPLATE : sc_concat_bool | |
| // | |
| // Proxy class for read-only boolean values in concatenations. | |
| // ---------------------------------------------------------------------------- | |
| class sc_concat_bool : public sc_value_base | |
| { | |
| protected: | |
| static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool. | |
| bool m_value; // Value for this obj. | |
| public: | |
| // constructor: | |
| sc_concat_bool() : sc_value_base(), m_value() {} | |
| // destructor: | |
| virtual ~sc_concat_bool() { } | |
| // allocation of temporary object: | |
| static inline sc_concat_bool * | |
| allocate(bool v) | |
| { | |
| sc_concat_bool *result_p = m_pool.allocate(); | |
| result_p->m_value = v; | |
| return result_p; | |
| } | |
| // concatenation: | |
| 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 = 1 << (low_i % BITS_PER_DIGIT); | |
| int word_i = low_i / BITS_PER_DIGIT; | |
| dst_p[word_i] &= ~bit; | |
| return false; | |
| } | |
| virtual bool | |
| concat_get_data(sc_digit *dst_p, int low_i) const | |
| { | |
| int bit = 1 << (low_i % BITS_PER_DIGIT); | |
| int word_i = low_i / BITS_PER_DIGIT; | |
| if (m_value) | |
| dst_p[word_i] |= bit; | |
| else | |
| dst_p[word_i] &= ~bit; | |
| return m_value; | |
| } | |
| virtual uint64 | |
| concat_get_uint64() const | |
| { | |
| return m_value ? 1 : 0; | |
| } | |
| }; | |
| // ---------------------------------------------------------------------------- | |
| // ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref | |
| // ---------------------------------------------------------------------------- | |
| #define SC_CONCAT_OP_TYPE(RESULT, OP, OTHER_TYPE) \ | |
| inline RESULT \ | |
| operator OP (const sc_concatref &a, OTHER_TYPE b) \ | |
| { \ | |
| return a.value() OP b; \ | |
| } \ | |
| inline RESULT \ | |
| operator OP (OTHER_TYPE a, const sc_concatref &b) \ | |
| { \ | |
| return a OP b.value(); \ | |
| } | |
| #define SC_CONCAT_OP(RESULT, OP) \ | |
| inline RESULT \ | |
| operator OP (const sc_concatref &a, const sc_concatref &b) \ | |
| { \ | |
| return a.value() OP b.value(); \ | |
| } \ | |
| SC_CONCAT_OP_TYPE(const sc_signed, OP, int) \ | |
| SC_CONCAT_OP_TYPE(const sc_signed, OP, long) \ | |
| SC_CONCAT_OP_TYPE(const sc_signed, OP, int64) \ | |
| SC_CONCAT_OP_TYPE(RESULT, OP, unsigned int) \ | |
| SC_CONCAT_OP_TYPE(RESULT, OP, unsigned long) \ | |
| SC_CONCAT_OP_TYPE(RESULT, OP, uint64) \ | |
| SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_int_base &) \ | |
| SC_CONCAT_OP_TYPE(RESULT, OP, const sc_uint_base &) \ | |
| SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_signed &) \ | |
| SC_CONCAT_OP_TYPE(RESULT, OP, const sc_unsigned &) \ | |
| inline RESULT \ | |
| operator OP (const sc_concatref &a, bool b) \ | |
| { \ | |
| return a.value() OP (int)b; \ | |
| } \ | |
| inline RESULT \ | |
| operator OP (bool a, const sc_concatref &b) \ | |
| { \ | |
| return (int)a OP b.value(); \ | |
| } | |
| #define SC_CONCAT_BOOL_OP(OP) \ | |
| inline bool \ | |
| operator OP (const sc_concatref &a, const sc_concatref &b) \ | |
| { \ | |
| return a.value() OP b.value(); \ | |
| } \ | |
| SC_CONCAT_OP_TYPE(bool, OP, int) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, long) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, int64) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, unsigned int) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, unsigned long) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, uint64) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, const sc_int_base &) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, const sc_uint_base &) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, const sc_signed &) \ | |
| SC_CONCAT_OP_TYPE(bool, OP, const sc_unsigned &) \ | |
| inline bool \ | |
| operator OP (const sc_concatref &a, bool b) \ | |
| { \ | |
| return a.value() OP (int)b; \ | |
| } \ | |
| inline bool \ | |
| operator OP (bool a, const sc_concatref &b) \ | |
| { \ | |
| return (int)a OP b.value(); \ | |
| } | |
| SC_CONCAT_OP(const sc_unsigned, +) | |
| SC_CONCAT_OP(const sc_signed, -) | |
| SC_CONCAT_OP(const sc_unsigned, *) | |
| SC_CONCAT_OP(const sc_unsigned, /) | |
| SC_CONCAT_OP(const sc_unsigned, %) | |
| SC_CONCAT_OP(const sc_unsigned, &) | |
| SC_CONCAT_OP(const sc_unsigned, |) | |
| SC_CONCAT_OP(const sc_unsigned, ^) | |
| SC_CONCAT_BOOL_OP(==) | |
| SC_CONCAT_BOOL_OP(<=) | |
| SC_CONCAT_BOOL_OP(>=) | |
| SC_CONCAT_BOOL_OP(!=) | |
| SC_CONCAT_BOOL_OP(>) | |
| SC_CONCAT_BOOL_OP(<) | |
| #undef SC_CONCAT_OP | |
| #undef SC_CONCAT_OP_TYPE | |
| // ---------------------------------------------------------------------------- | |
| // CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES: | |
| // ---------------------------------------------------------------------------- | |
| inline sc_dt::sc_concatref & | |
| concat(sc_dt::sc_value_base &a, sc_dt::sc_value_base &b) | |
| { | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, b); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| concat(const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b) | |
| { | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, b); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| concat(const sc_dt::sc_value_base &a, bool b) | |
| { | |
| const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value. | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| b_p = sc_dt::sc_concat_bool::allocate(b); | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, *b_p); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| concat(bool a, const sc_dt::sc_value_base &b) | |
| { | |
| const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value. | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| a_p = sc_dt::sc_concat_bool::allocate(a); | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(*a_p, b); | |
| return *result_p; | |
| } | |
| inline sc_dt::sc_concatref & | |
| operator , (sc_dt::sc_value_base &a, sc_dt::sc_value_base &b) | |
| { | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, b); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| operator , (const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b) | |
| { | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, b); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| operator , (const sc_dt::sc_value_base &a, bool b) | |
| { | |
| const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value. | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| b_p = sc_dt::sc_concat_bool::allocate(b); | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(a, *b_p); | |
| return *result_p; | |
| } | |
| inline const sc_dt::sc_concatref & | |
| operator , (bool a, const sc_dt::sc_value_base &b) | |
| { | |
| const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value. | |
| sc_dt::sc_concatref *result_p; // Proxy for the concatenation. | |
| a_p = sc_dt::sc_concat_bool::allocate(a); | |
| result_p = sc_dt::sc_concatref::m_pool.allocate(); | |
| result_p->initialize(*a_p, b); | |
| return *result_p; | |
| } | |
| } // namespace sc_dt | |
| #endif // __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__ |