summaryrefslogtreecommitdiff
path: root/src/systemc/ext/dt/misc/sc_concatref.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/ext/dt/misc/sc_concatref.hh')
-rw-r--r--src/systemc/ext/dt/misc/sc_concatref.hh806
1 files changed, 806 insertions, 0 deletions
diff --git a/src/systemc/ext/dt/misc/sc_concatref.hh b/src/systemc/ext/dt/misc/sc_concatref.hh
new file mode 100644
index 000000000..cd36eb526
--- /dev/null
+++ b/src/systemc/ext/dt/misc/sc_concatref.hh
@@ -0,0 +1,806 @@
+/*****************************************************************************
+
+ 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__