112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  sc_concatref.h -- Concatenation support.
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Andy Goodrich, Forte Design, Inc.
2512853Sgabeblack@google.com
2612853Sgabeblack@google.com *****************************************************************************/
2712853Sgabeblack@google.com
2812853Sgabeblack@google.com/*****************************************************************************
2912853Sgabeblack@google.com
3012853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112853Sgabeblack@google.com  changes you are making here.
3212853Sgabeblack@google.com
3312853Sgabeblack@google.com      Name, Affiliation, Date:
3412853Sgabeblack@google.com  Description of Modification:
3512853Sgabeblack@google.com
3612853Sgabeblack@google.com  Andy Goodrich, Forte Design Systems, 17 Nov 2002
3712853Sgabeblack@google.com  Creation of sc_concatref class by merging the capabilities of
3812853Sgabeblack@google.com  sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref,
3912853Sgabeblack@google.com  and implementing the capabilities of sc_signed_concref, sc_signed_concref,
4012853Sgabeblack@google.com  sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows
4112853Sgabeblack@google.com  mixed mode concatenations on the left and right sides of an assignment.
4212853Sgabeblack@google.com
4312853Sgabeblack@google.com *****************************************************************************/
4412853Sgabeblack@google.com
4512853Sgabeblack@google.com// $Log: sc_concatref.h,v $
4612853Sgabeblack@google.com// Revision 1.6  2011/08/24 22:05:48  acg
4712853Sgabeblack@google.com//  Torsten Maehne: initialization changes to remove warnings.
4812853Sgabeblack@google.com//
4912853Sgabeblack@google.com// Revision 1.5  2009/11/17 19:58:15  acg
5012853Sgabeblack@google.com//  Andy Goodrich: fix of shift rhs possibilities to include "int".
5112853Sgabeblack@google.com//
5212853Sgabeblack@google.com// Revision 1.4  2009/02/28 00:26:29  acg
5312853Sgabeblack@google.com//  Andy Goodrich: bug fixes.
5412853Sgabeblack@google.com//
5512853Sgabeblack@google.com// Revision 1.3  2008/04/29 20:23:55  acg
5612853Sgabeblack@google.com//  Andy Goodrich: fixed the code that assigns the value of a string to
5712853Sgabeblack@google.com//  an sc_concatref instance.
5812853Sgabeblack@google.com//
5912853Sgabeblack@google.com// Revision 1.2  2008/02/14 20:57:26  acg
6012853Sgabeblack@google.com//  Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy.
6112853Sgabeblack@google.com//
6212853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:05  acg
6312853Sgabeblack@google.com// SystemC 2.3
6412853Sgabeblack@google.com//
6512853Sgabeblack@google.com// Revision 1.4  2006/10/23 19:36:59  acg
6612853Sgabeblack@google.com//  Andy Goodrich: changed casts for operations on concatenation values to
6712853Sgabeblack@google.com//  mirror those of sc_unsigned. For instance, an sc_unsigned minus a value
6812853Sgabeblack@google.com//  returns an sc_signed result, whereas an sc_concatref minus a value was
6912853Sgabeblack@google.com//  returning an sc_unsigned result. Now both sc_unsigned and sc_concatref
7012853Sgabeblack@google.com//  minus a value return an sc_signed result.
7112853Sgabeblack@google.com//
7212853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:54:01  acg
7312853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
7412853Sgabeblack@google.com// the source.
7512853Sgabeblack@google.com//
7612853Sgabeblack@google.com
7712853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__
7812853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__
7912853Sgabeblack@google.com
8012853Sgabeblack@google.com#include <iostream>
8112853Sgabeblack@google.com
8212853Sgabeblack@google.com#include "../bit/sc_bv.hh"
8312853Sgabeblack@google.com#include "../bit/sc_lv.hh"
8412853Sgabeblack@google.com#include "../int/sc_int_base.hh"
8512853Sgabeblack@google.com#include "../int/sc_signed.hh"
8612853Sgabeblack@google.com#include "../int/sc_uint_base.hh"
8712853Sgabeblack@google.com#include "../int/sc_unsigned.hh"
8812853Sgabeblack@google.com#include "../sc_temporary.hh"
8912853Sgabeblack@google.com#include "sc_value_base.hh"
9012853Sgabeblack@google.com
9112853Sgabeblack@google.comnamespace sc_dt
9212853Sgabeblack@google.com{
9312853Sgabeblack@google.com
9412853Sgabeblack@google.com// classes defined in this module
9512853Sgabeblack@google.comclass sc_concatref;
9612853Sgabeblack@google.comclass sc_concat_bool;
9712853Sgabeblack@google.com
9812853Sgabeblack@google.com} // namespace sc_dt
9912853Sgabeblack@google.com
10012853Sgabeblack@google.comnamespace sc_core
10112853Sgabeblack@google.com{
10212853Sgabeblack@google.com
10312853Sgabeblack@google.comextern sc_byte_heap sc_temp_heap; // Temporary storage.
10412853Sgabeblack@google.com
10512853Sgabeblack@google.com// explicit template instantiations
10612853Sgabeblack@google.comextern template class sc_vpool<sc_dt::sc_concatref>;
10712853Sgabeblack@google.comextern template class sc_vpool<sc_dt::sc_concat_bool>;
10812853Sgabeblack@google.com
10912853Sgabeblack@google.com} // namespace sc_core
11012853Sgabeblack@google.com
11112853Sgabeblack@google.comnamespace sc_dt {
11212853Sgabeblack@google.com
11312853Sgabeblack@google.com// ----------------------------------------------------------------------------
11412853Sgabeblack@google.com//  CLASS TEMPLATE : sc_concatref
11512853Sgabeblack@google.com//
11612853Sgabeblack@google.com//  Proxy class for sized bit concatenation.
11712853Sgabeblack@google.com// ----------------------------------------------------------------------------
11812853Sgabeblack@google.com
11912853Sgabeblack@google.comclass sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base
12012853Sgabeblack@google.com{
12112853Sgabeblack@google.com  public:
12212853Sgabeblack@google.com    friend class sc_core::sc_vpool<sc_concatref>;
12312853Sgabeblack@google.com
12412853Sgabeblack@google.com    inline void
12512853Sgabeblack@google.com    initialize(sc_value_base &left, sc_value_base &right)
12612853Sgabeblack@google.com    {
12712853Sgabeblack@google.com        bool left_xz; // True if x's and/or z's found in left.
12812853Sgabeblack@google.com        bool right_xz; // True if x's and/or z's found in right.
12912853Sgabeblack@google.com
13012853Sgabeblack@google.com        m_left_p = (sc_value_base *)&left;
13112853Sgabeblack@google.com        m_right_p = (sc_value_base *)&right;
13212853Sgabeblack@google.com        m_len_r = right.concat_length(&right_xz);
13312853Sgabeblack@google.com        m_len = left.concat_length(&left_xz) + m_len_r;
13412853Sgabeblack@google.com        m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none;
13512853Sgabeblack@google.com    }
13612853Sgabeblack@google.com
13712853Sgabeblack@google.com
13812853Sgabeblack@google.com    inline void
13912853Sgabeblack@google.com    initialize(const sc_value_base &left, const sc_value_base &right)
14012853Sgabeblack@google.com    {
14112853Sgabeblack@google.com        bool left_xz;   // True if x's and/or z's found in left.
14212853Sgabeblack@google.com        bool right_xz;  // True if x's and/or z's found in right.
14312853Sgabeblack@google.com
14412853Sgabeblack@google.com        m_left_p = (sc_value_base *)&left;
14512853Sgabeblack@google.com        m_right_p = (sc_value_base *)&right;
14612853Sgabeblack@google.com        m_len_r = right.concat_length(&right_xz);
14712853Sgabeblack@google.com        m_len = left.concat_length(&left_xz) + m_len_r;
14812853Sgabeblack@google.com        m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none;
14912853Sgabeblack@google.com    }
15012853Sgabeblack@google.com
15112853Sgabeblack@google.com    // destructor
15212853Sgabeblack@google.com    virtual ~sc_concatref() {}
15312853Sgabeblack@google.com
15412853Sgabeblack@google.com    // capacity
15512853Sgabeblack@google.com    unsigned int length() const { return m_len; }
15612853Sgabeblack@google.com
15712853Sgabeblack@google.com    // concatenation
15812853Sgabeblack@google.com    virtual int
15912853Sgabeblack@google.com    concat_length(bool *xz_present_p) const
16012853Sgabeblack@google.com    {
16112853Sgabeblack@google.com        if (xz_present_p)
16212853Sgabeblack@google.com            *xz_present_p = m_flags & cf_xz_present ? true : false;
16312853Sgabeblack@google.com        return m_len;
16412853Sgabeblack@google.com    }
16512853Sgabeblack@google.com
16612853Sgabeblack@google.com    virtual void
16712853Sgabeblack@google.com    concat_clear_data(bool to_ones)
16812853Sgabeblack@google.com    {
16912853Sgabeblack@google.com        m_left_p->concat_clear_data(to_ones);
17012853Sgabeblack@google.com        m_right_p->concat_clear_data(to_ones);
17112853Sgabeblack@google.com    }
17212853Sgabeblack@google.com
17312853Sgabeblack@google.com    virtual bool
17412853Sgabeblack@google.com    concat_get_ctrl(sc_digit *dst_p, int low_i) const
17512853Sgabeblack@google.com    {
17612853Sgabeblack@google.com        bool rnz = m_right_p->concat_get_ctrl(dst_p, low_i);
17712853Sgabeblack@google.com        bool lnz = m_left_p->concat_get_ctrl(dst_p, low_i + m_len_r);
17812853Sgabeblack@google.com        return rnz || lnz;
17912853Sgabeblack@google.com    }
18012853Sgabeblack@google.com
18112853Sgabeblack@google.com    virtual bool
18212853Sgabeblack@google.com    concat_get_data(sc_digit *dst_p, int low_i) const
18312853Sgabeblack@google.com    {
18412853Sgabeblack@google.com        bool rnz = m_right_p->concat_get_data(dst_p, low_i);
18512853Sgabeblack@google.com        bool lnz = m_left_p->concat_get_data(dst_p, low_i + m_len_r);
18612853Sgabeblack@google.com        return rnz || lnz;
18712853Sgabeblack@google.com    }
18812853Sgabeblack@google.com
18912853Sgabeblack@google.com    virtual uint64
19012853Sgabeblack@google.com    concat_get_uint64() const
19112853Sgabeblack@google.com    {
19212853Sgabeblack@google.com        if (m_len_r >= 64) {
19312853Sgabeblack@google.com            return m_right_p->concat_get_uint64();
19412853Sgabeblack@google.com        } else {
19512853Sgabeblack@google.com            return (m_left_p->concat_get_uint64() << m_len_r) |
19612853Sgabeblack@google.com                m_right_p->concat_get_uint64();
19712853Sgabeblack@google.com        }
19812853Sgabeblack@google.com    }
19912853Sgabeblack@google.com
20012853Sgabeblack@google.com    virtual void
20112853Sgabeblack@google.com    concat_set(int64 src, int low_i)
20212853Sgabeblack@google.com    {
20312853Sgabeblack@google.com        m_right_p->concat_set(src, low_i);
20412853Sgabeblack@google.com        m_left_p->concat_set(src, low_i + m_len_r);
20512853Sgabeblack@google.com    }
20612853Sgabeblack@google.com
20712853Sgabeblack@google.com    virtual void
20812853Sgabeblack@google.com    concat_set(const sc_signed &src, int low_i)
20912853Sgabeblack@google.com    {
21012853Sgabeblack@google.com        m_right_p->concat_set(src, low_i);
21112853Sgabeblack@google.com        m_left_p->concat_set(src, low_i + m_len_r);
21212853Sgabeblack@google.com    }
21312853Sgabeblack@google.com
21412853Sgabeblack@google.com    virtual void
21512853Sgabeblack@google.com    concat_set(const sc_unsigned &src, int low_i)
21612853Sgabeblack@google.com    {
21712853Sgabeblack@google.com        m_right_p->concat_set(src, low_i);
21812853Sgabeblack@google.com        m_left_p->concat_set(src, low_i + m_len_r);
21912853Sgabeblack@google.com    }
22012853Sgabeblack@google.com
22112853Sgabeblack@google.com    virtual void
22212853Sgabeblack@google.com    concat_set(uint64 src, int low_i)
22312853Sgabeblack@google.com    {
22412853Sgabeblack@google.com        m_right_p->concat_set(src, low_i);
22512853Sgabeblack@google.com        m_left_p->concat_set(src, low_i + m_len_r);
22612853Sgabeblack@google.com    }
22712853Sgabeblack@google.com
22812853Sgabeblack@google.com    // explicit conversions
22912853Sgabeblack@google.com    uint64
23012853Sgabeblack@google.com    to_uint64() const
23112853Sgabeblack@google.com    {
23212853Sgabeblack@google.com        uint64 mask;
23312853Sgabeblack@google.com        uint64 result;
23412853Sgabeblack@google.com
23512853Sgabeblack@google.com        result = m_right_p->concat_get_uint64();
23612853Sgabeblack@google.com        if (m_len_r < 64) {
23712853Sgabeblack@google.com            mask = (uint64)~0;
23812853Sgabeblack@google.com            result = (m_left_p->concat_get_uint64() << m_len_r) |
23912853Sgabeblack@google.com                        (result & ~(mask << m_len_r));
24012853Sgabeblack@google.com        }
24112853Sgabeblack@google.com        if (m_len < 64) {
24212853Sgabeblack@google.com            mask = (uint64)~0;
24312853Sgabeblack@google.com            result = result & ~(mask << m_len);
24412853Sgabeblack@google.com        }
24512853Sgabeblack@google.com        return result;
24612853Sgabeblack@google.com    }
24712853Sgabeblack@google.com
24812853Sgabeblack@google.com    const sc_unsigned &
24912853Sgabeblack@google.com    value() const
25012853Sgabeblack@google.com    {
25112853Sgabeblack@google.com        bool left_non_zero;
25212853Sgabeblack@google.com        sc_unsigned *result_p = sc_unsigned::m_pool.allocate();
25312853Sgabeblack@google.com        bool right_non_zero;
25412853Sgabeblack@google.com
25512853Sgabeblack@google.com        result_p->nbits = result_p->num_bits(m_len);
25612853Sgabeblack@google.com        result_p->ndigits = DIV_CEIL(result_p->nbits);
25712853Sgabeblack@google.com        result_p->digit = (sc_digit *)sc_core::sc_temp_heap.allocate(
25812853Sgabeblack@google.com            sizeof(sc_digit) * result_p->ndigits);
25912853Sgabeblack@google.com        result_p->digit[result_p->ndigits - 1] = 0;
26012853Sgabeblack@google.com        right_non_zero = m_right_p->concat_get_data(result_p->digit, 0);
26112853Sgabeblack@google.com        left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r);
26212853Sgabeblack@google.com        if (left_non_zero || right_non_zero)
26312853Sgabeblack@google.com            result_p->sgn = SC_POS;
26412853Sgabeblack@google.com        else
26512853Sgabeblack@google.com            result_p->sgn = SC_ZERO;
26612853Sgabeblack@google.com        return *result_p;
26712853Sgabeblack@google.com    }
26812853Sgabeblack@google.com
26912853Sgabeblack@google.com    int64 to_int64() const { return (int64)to_uint64(); }
27012853Sgabeblack@google.com    int to_int() const { return (int)to_int64(); }
27112853Sgabeblack@google.com    unsigned int to_uint() const { return (unsigned int)to_uint64(); }
27212853Sgabeblack@google.com    long to_long() const { return (long)to_int64(); }
27312853Sgabeblack@google.com    unsigned long to_ulong() const { return (unsigned long)to_uint64(); }
27412853Sgabeblack@google.com    double to_double() const { return value().to_double(); }
27512853Sgabeblack@google.com
27612853Sgabeblack@google.com    void to_sc_signed(sc_signed &target) const { target = value(); }
27712853Sgabeblack@google.com
27812853Sgabeblack@google.com    void to_sc_unsigned(sc_unsigned &target) const { target = value(); }
27912853Sgabeblack@google.com
28012853Sgabeblack@google.com    // implicit conversions:
28112853Sgabeblack@google.com    operator uint64 () const { return to_uint64(); }
28212853Sgabeblack@google.com
28312853Sgabeblack@google.com    operator const sc_unsigned & () const { return value(); }
28412853Sgabeblack@google.com
28512853Sgabeblack@google.com    // unary operators:
28612853Sgabeblack@google.com    sc_unsigned operator + () const { return value(); }
28712853Sgabeblack@google.com
28812853Sgabeblack@google.com    sc_signed operator - () const { return -value(); }
28912853Sgabeblack@google.com
29012853Sgabeblack@google.com    sc_unsigned operator ~ () const { return ~value(); }
29112853Sgabeblack@google.com
29212853Sgabeblack@google.com    // explicit conversion to character string
29312853Sgabeblack@google.com    const std::string
29412853Sgabeblack@google.com    to_string(sc_numrep numrep=SC_DEC) const
29512853Sgabeblack@google.com    {
29612853Sgabeblack@google.com        return value().to_string(numrep);
29712853Sgabeblack@google.com    }
29812853Sgabeblack@google.com
29912853Sgabeblack@google.com    const std::string
30012853Sgabeblack@google.com    to_string(sc_numrep numrep, bool w_prefix) const
30112853Sgabeblack@google.com    {
30212853Sgabeblack@google.com        return value().to_string(numrep,w_prefix);
30312853Sgabeblack@google.com    }
30412853Sgabeblack@google.com
30512853Sgabeblack@google.com    // assignments
30612853Sgabeblack@google.com    inline const sc_concatref &
30712853Sgabeblack@google.com    operator = (int v)
30812853Sgabeblack@google.com    {
30912853Sgabeblack@google.com        m_right_p->concat_set((int64)v, 0);
31012853Sgabeblack@google.com        m_left_p->concat_set((int64)v, m_len_r);
31112853Sgabeblack@google.com        return *this;
31212853Sgabeblack@google.com    }
31312853Sgabeblack@google.com
31412853Sgabeblack@google.com    inline const sc_concatref &
31512853Sgabeblack@google.com    operator = (long v)
31612853Sgabeblack@google.com    {
31712853Sgabeblack@google.com        m_right_p->concat_set((int64)v, 0);
31812853Sgabeblack@google.com        m_left_p->concat_set((int64)v, m_len_r);
31912853Sgabeblack@google.com        return *this;
32012853Sgabeblack@google.com    }
32112853Sgabeblack@google.com
32212853Sgabeblack@google.com    inline const sc_concatref &
32312853Sgabeblack@google.com    operator = (int64 v)
32412853Sgabeblack@google.com    {
32512853Sgabeblack@google.com        m_right_p->concat_set(v, 0);
32612853Sgabeblack@google.com        m_left_p->concat_set(v, m_len_r);
32712853Sgabeblack@google.com        return *this;
32812853Sgabeblack@google.com    }
32912853Sgabeblack@google.com
33012853Sgabeblack@google.com    inline const sc_concatref &
33112853Sgabeblack@google.com    operator = (unsigned int v)
33212853Sgabeblack@google.com    {
33312853Sgabeblack@google.com        m_right_p->concat_set((uint64)v, 0);
33412853Sgabeblack@google.com        m_left_p->concat_set((uint64)v, m_len_r);
33512853Sgabeblack@google.com        return *this;
33612853Sgabeblack@google.com    }
33712853Sgabeblack@google.com
33812853Sgabeblack@google.com    inline const sc_concatref &
33912853Sgabeblack@google.com    operator = (unsigned long v)
34012853Sgabeblack@google.com    {
34112853Sgabeblack@google.com        m_right_p->concat_set((uint64)v, 0);
34212853Sgabeblack@google.com        m_left_p->concat_set((uint64)v, m_len_r);
34312853Sgabeblack@google.com        return *this;
34412853Sgabeblack@google.com    }
34512853Sgabeblack@google.com
34612853Sgabeblack@google.com    inline const sc_concatref &
34712853Sgabeblack@google.com    operator = (uint64 v)
34812853Sgabeblack@google.com    {
34912853Sgabeblack@google.com        m_right_p->concat_set(v, 0);
35012853Sgabeblack@google.com        m_left_p->concat_set(v, m_len_r);
35112853Sgabeblack@google.com        return *this;
35212853Sgabeblack@google.com    }
35312853Sgabeblack@google.com
35412853Sgabeblack@google.com    const sc_concatref &
35512853Sgabeblack@google.com    operator = (const sc_concatref &v)
35612853Sgabeblack@google.com    {
35712853Sgabeblack@google.com        sc_unsigned temp(v.length());
35812853Sgabeblack@google.com        temp = v.value();
35912853Sgabeblack@google.com        m_right_p->concat_set(temp, 0);
36012853Sgabeblack@google.com        m_left_p->concat_set(temp, m_len_r);
36112853Sgabeblack@google.com        return *this;
36212853Sgabeblack@google.com    }
36312853Sgabeblack@google.com
36412853Sgabeblack@google.com    const sc_concatref &
36512853Sgabeblack@google.com    operator = (const sc_signed &v)
36612853Sgabeblack@google.com    {
36712853Sgabeblack@google.com        m_right_p->concat_set(v, 0);
36812853Sgabeblack@google.com        m_left_p->concat_set(v, m_len_r);
36912853Sgabeblack@google.com        return *this;
37012853Sgabeblack@google.com    }
37112853Sgabeblack@google.com
37212853Sgabeblack@google.com    const sc_concatref &
37312853Sgabeblack@google.com    operator = (const sc_unsigned &v)
37412853Sgabeblack@google.com    {
37512853Sgabeblack@google.com        m_right_p->concat_set(v, 0);
37612853Sgabeblack@google.com        m_left_p->concat_set(v, m_len_r);
37712853Sgabeblack@google.com        return *this;
37812853Sgabeblack@google.com    }
37912853Sgabeblack@google.com
38012853Sgabeblack@google.com    const sc_concatref &
38112853Sgabeblack@google.com    operator = (const char *v_p)
38212853Sgabeblack@google.com    {
38312853Sgabeblack@google.com        sc_unsigned v(m_len);
38412853Sgabeblack@google.com        v = v_p;
38512853Sgabeblack@google.com        m_right_p->concat_set(v, 0);
38612853Sgabeblack@google.com        m_left_p->concat_set(v, m_len_r);
38712853Sgabeblack@google.com        return *this;
38812853Sgabeblack@google.com    }
38912853Sgabeblack@google.com
39012853Sgabeblack@google.com    const sc_concatref &
39112853Sgabeblack@google.com    operator = (const sc_bv_base &v)
39212853Sgabeblack@google.com    {
39312853Sgabeblack@google.com        sc_unsigned temp(v.length());
39412853Sgabeblack@google.com        temp = v;
39512853Sgabeblack@google.com        m_right_p->concat_set(temp, 0);
39612853Sgabeblack@google.com        m_left_p->concat_set(temp, m_len_r);
39712853Sgabeblack@google.com        return *this;
39812853Sgabeblack@google.com    }
39912853Sgabeblack@google.com
40012853Sgabeblack@google.com    const sc_concatref &
40112853Sgabeblack@google.com    operator = (const sc_lv_base &v)
40212853Sgabeblack@google.com    {
40312853Sgabeblack@google.com        sc_unsigned data(v.length());
40412853Sgabeblack@google.com        data = v;
40512853Sgabeblack@google.com        m_right_p->concat_set(data, 0);
40612853Sgabeblack@google.com        m_left_p->concat_set(data, m_len_r);
40712853Sgabeblack@google.com        return *this;
40812853Sgabeblack@google.com    }
40912853Sgabeblack@google.com
41012853Sgabeblack@google.com    // reduce methods
41112853Sgabeblack@google.com    bool and_reduce() const { return value().and_reduce(); }
41212853Sgabeblack@google.com    bool nand_reduce() const { return value().nand_reduce(); }
41312853Sgabeblack@google.com    bool or_reduce() const { return value().or_reduce(); }
41412853Sgabeblack@google.com    bool nor_reduce() const { return value().nor_reduce(); }
41512853Sgabeblack@google.com    bool xor_reduce() const { return value().xor_reduce(); }
41612853Sgabeblack@google.com    bool xnor_reduce() const { return value().xnor_reduce(); }
41712853Sgabeblack@google.com
41812853Sgabeblack@google.com    // other methods
41912853Sgabeblack@google.com    void print(::std::ostream &os=::std::cout) const { os << this->value(); }
42012853Sgabeblack@google.com
42112853Sgabeblack@google.com    void
42212853Sgabeblack@google.com    scan(::std::istream &is)
42312853Sgabeblack@google.com    {
42412853Sgabeblack@google.com        std::string s;
42512853Sgabeblack@google.com        is >> s;
42612853Sgabeblack@google.com        *this = s.c_str();
42712853Sgabeblack@google.com    }
42812853Sgabeblack@google.com
42912853Sgabeblack@google.com  public:
43012853Sgabeblack@google.com    // Pool of temporary objects.
43112853Sgabeblack@google.com    static sc_core::sc_vpool<sc_concatref> m_pool;
43212853Sgabeblack@google.com
43312853Sgabeblack@google.com  public:
43412853Sgabeblack@google.com    enum concat_flags {
43512853Sgabeblack@google.com        cf_none = 0,        // Normal value.
43612853Sgabeblack@google.com        cf_xz_present = 1   // X and/or Z values present.
43712853Sgabeblack@google.com    };
43812853Sgabeblack@google.com
43912853Sgabeblack@google.com  protected:
44012853Sgabeblack@google.com    sc_value_base *m_left_p;  // Left hand operand of concatenation.
44112853Sgabeblack@google.com    sc_value_base *m_right_p; // Right hand operand of concatenation.
44212853Sgabeblack@google.com    int m_len;                // Length of concatenation.
44312853Sgabeblack@google.com    int m_len_r;              // Length of m_rightt_p.
44412853Sgabeblack@google.com    concat_flags m_flags;     // Value is read only.
44512853Sgabeblack@google.com
44612853Sgabeblack@google.com  private:
44712853Sgabeblack@google.com    sc_concatref(const sc_concatref &);
44812853Sgabeblack@google.com    sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags()
44912853Sgabeblack@google.com    {}
45012853Sgabeblack@google.com};
45112853Sgabeblack@google.com
45212853Sgabeblack@google.com// functional notation for the reduce methods
45312853Sgabeblack@google.cominline bool and_reduce(const sc_concatref &a) { return a.and_reduce(); }
45412853Sgabeblack@google.cominline bool nand_reduce(const sc_concatref &a) { return a.nand_reduce(); }
45512853Sgabeblack@google.cominline bool or_reduce(const sc_concatref &a) { return a.or_reduce(); }
45612853Sgabeblack@google.cominline bool nor_reduce(const sc_concatref &a) { return a.nor_reduce(); }
45712853Sgabeblack@google.cominline bool xor_reduce(const sc_concatref &a) { return a.xor_reduce(); }
45812853Sgabeblack@google.cominline bool xnor_reduce(const sc_concatref &a) { return a.xnor_reduce(); }
45912853Sgabeblack@google.com
46012853Sgabeblack@google.com// SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES:
46112853Sgabeblack@google.com//
46212853Sgabeblack@google.com// Because sc_concatref has implicit casts to both uint64 and sc_unsigned
46312853Sgabeblack@google.com// it is necessary to disambiguate the use of the shift operators. We do
46412853Sgabeblack@google.com// this in favor of sc_unsigned so that precision is not lost. To get an
46512853Sgabeblack@google.com// integer-based result use a cast to uint64 before performing the shift.
46612853Sgabeblack@google.com
46712853Sgabeblack@google.cominline const sc_unsigned
46812853Sgabeblack@google.comoperator << (const sc_concatref &target, uint64 shift)
46912853Sgabeblack@google.com{
47012853Sgabeblack@google.com    return target.value() << (int)shift;
47112853Sgabeblack@google.com}
47212853Sgabeblack@google.com
47312853Sgabeblack@google.cominline const sc_unsigned
47412853Sgabeblack@google.comoperator << (const sc_concatref &target, int64 shift)
47512853Sgabeblack@google.com{
47612853Sgabeblack@google.com    return target.value() << (int)shift;
47712853Sgabeblack@google.com}
47812853Sgabeblack@google.com
47912853Sgabeblack@google.cominline const sc_unsigned
48012853Sgabeblack@google.comoperator << (const sc_concatref &target, unsigned long shift)
48112853Sgabeblack@google.com{
48212853Sgabeblack@google.com    return target.value() << (int)shift;
48312853Sgabeblack@google.com}
48412853Sgabeblack@google.com
48512853Sgabeblack@google.cominline const sc_unsigned
48612853Sgabeblack@google.comoperator << (const sc_concatref &target, int shift)
48712853Sgabeblack@google.com{
48812853Sgabeblack@google.com    return target.value() << shift;
48912853Sgabeblack@google.com}
49012853Sgabeblack@google.com
49112853Sgabeblack@google.cominline const sc_unsigned
49212853Sgabeblack@google.comoperator << (const sc_concatref &target, unsigned int shift)
49312853Sgabeblack@google.com{
49412853Sgabeblack@google.com    return target.value() << (int)shift;
49512853Sgabeblack@google.com}
49612853Sgabeblack@google.com
49712853Sgabeblack@google.cominline const sc_unsigned
49812853Sgabeblack@google.comoperator << (const sc_concatref &target, long shift)
49912853Sgabeblack@google.com{
50012853Sgabeblack@google.com    return target.value() << (int)shift;
50112853Sgabeblack@google.com}
50212853Sgabeblack@google.com
50312853Sgabeblack@google.cominline const sc_unsigned
50412853Sgabeblack@google.comoperator >> (const sc_concatref &target, uint64 shift)
50512853Sgabeblack@google.com{
50612853Sgabeblack@google.com    return target.value() >> (int)shift;
50712853Sgabeblack@google.com}
50812853Sgabeblack@google.com
50912853Sgabeblack@google.cominline const sc_unsigned
51012853Sgabeblack@google.comoperator >> (const sc_concatref &target, int64 shift)
51112853Sgabeblack@google.com{
51212853Sgabeblack@google.com    return target.value() >> (int)shift;
51312853Sgabeblack@google.com}
51412853Sgabeblack@google.com
51512853Sgabeblack@google.cominline const sc_unsigned
51612853Sgabeblack@google.comoperator >> (const sc_concatref &target, unsigned long shift)
51712853Sgabeblack@google.com{
51812853Sgabeblack@google.com    return target.value() >> (int)shift;
51912853Sgabeblack@google.com}
52012853Sgabeblack@google.com
52112853Sgabeblack@google.cominline const sc_unsigned
52212853Sgabeblack@google.comoperator >> (const sc_concatref &target, int shift)
52312853Sgabeblack@google.com{
52412853Sgabeblack@google.com    return target.value() >> shift;
52512853Sgabeblack@google.com}
52612853Sgabeblack@google.com
52712853Sgabeblack@google.cominline const sc_unsigned
52812853Sgabeblack@google.comoperator >> (const sc_concatref &target, unsigned int shift)
52912853Sgabeblack@google.com{
53012853Sgabeblack@google.com    return target.value() >> (int)shift;
53112853Sgabeblack@google.com}
53212853Sgabeblack@google.com
53312853Sgabeblack@google.cominline const sc_unsigned
53412853Sgabeblack@google.comoperator >> (const sc_concatref &target, long shift)
53512853Sgabeblack@google.com{
53612853Sgabeblack@google.com    return target.value() >> (int)shift;
53712853Sgabeblack@google.com}
53812853Sgabeblack@google.com
53912853Sgabeblack@google.com// STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES:
54012853Sgabeblack@google.cominline ::std::ostream &
54112853Sgabeblack@google.comoperator << (::std::ostream &os, const sc_concatref &v)
54212853Sgabeblack@google.com{
54312853Sgabeblack@google.com    return os << v.value();
54412853Sgabeblack@google.com}
54512853Sgabeblack@google.com
54612853Sgabeblack@google.cominline ::std::istream &
54712853Sgabeblack@google.comoperator >> (::std::istream &is, sc_concatref &a)
54812853Sgabeblack@google.com{
54912853Sgabeblack@google.com    sc_unsigned temp(a.concat_length(0));
55012853Sgabeblack@google.com    temp.scan(is);
55112853Sgabeblack@google.com    a = temp;
55212853Sgabeblack@google.com    return is;
55312853Sgabeblack@google.com}
55412853Sgabeblack@google.com
55512853Sgabeblack@google.com
55612853Sgabeblack@google.com// ----------------------------------------------------------------------------
55712853Sgabeblack@google.com//  CLASS TEMPLATE : sc_concat_bool
55812853Sgabeblack@google.com//
55912853Sgabeblack@google.com//  Proxy class for read-only boolean values in concatenations.
56012853Sgabeblack@google.com// ----------------------------------------------------------------------------
56112853Sgabeblack@google.com
56212853Sgabeblack@google.comclass sc_concat_bool : public sc_value_base
56312853Sgabeblack@google.com{
56412853Sgabeblack@google.com  protected:
56512853Sgabeblack@google.com    static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool.
56612853Sgabeblack@google.com    bool m_value;                                    // Value for this obj.
56712853Sgabeblack@google.com
56812853Sgabeblack@google.com  public:
56912853Sgabeblack@google.com    // constructor:
57012853Sgabeblack@google.com    sc_concat_bool() : sc_value_base(), m_value() {}
57112853Sgabeblack@google.com
57212853Sgabeblack@google.com    // destructor:
57312853Sgabeblack@google.com    virtual ~sc_concat_bool() { }
57412853Sgabeblack@google.com
57512853Sgabeblack@google.com    // allocation of temporary object:
57612853Sgabeblack@google.com    static inline sc_concat_bool *
57712853Sgabeblack@google.com    allocate(bool v)
57812853Sgabeblack@google.com    {
57912853Sgabeblack@google.com        sc_concat_bool *result_p = m_pool.allocate();
58012853Sgabeblack@google.com        result_p->m_value = v;
58112853Sgabeblack@google.com        return result_p;
58212853Sgabeblack@google.com    }
58312853Sgabeblack@google.com
58412853Sgabeblack@google.com    // concatenation:
58512853Sgabeblack@google.com    virtual int
58612853Sgabeblack@google.com    concat_length(bool *xz_present_p) const
58712853Sgabeblack@google.com    {
58812853Sgabeblack@google.com        if (xz_present_p)
58912853Sgabeblack@google.com            *xz_present_p = false;
59012853Sgabeblack@google.com        return 1;
59112853Sgabeblack@google.com    }
59212853Sgabeblack@google.com
59312853Sgabeblack@google.com    virtual bool
59412853Sgabeblack@google.com    concat_get_ctrl(sc_digit *dst_p, int low_i) const
59512853Sgabeblack@google.com    {
59612853Sgabeblack@google.com        int bit = 1 << (low_i % BITS_PER_DIGIT);
59712853Sgabeblack@google.com        int word_i = low_i / BITS_PER_DIGIT;
59812853Sgabeblack@google.com        dst_p[word_i] &= ~bit;
59912853Sgabeblack@google.com        return false;
60012853Sgabeblack@google.com    }
60112853Sgabeblack@google.com
60212853Sgabeblack@google.com    virtual bool
60312853Sgabeblack@google.com    concat_get_data(sc_digit *dst_p, int low_i) const
60412853Sgabeblack@google.com    {
60512853Sgabeblack@google.com        int bit = 1 << (low_i % BITS_PER_DIGIT);
60612853Sgabeblack@google.com        int word_i = low_i / BITS_PER_DIGIT;
60712853Sgabeblack@google.com        if (m_value)
60812853Sgabeblack@google.com            dst_p[word_i] |= bit;
60912853Sgabeblack@google.com        else
61012853Sgabeblack@google.com            dst_p[word_i] &= ~bit;
61112853Sgabeblack@google.com        return m_value;
61212853Sgabeblack@google.com    }
61312853Sgabeblack@google.com
61412853Sgabeblack@google.com    virtual uint64
61512853Sgabeblack@google.com    concat_get_uint64() const
61612853Sgabeblack@google.com    {
61712853Sgabeblack@google.com        return m_value ? 1 : 0;
61812853Sgabeblack@google.com    }
61912853Sgabeblack@google.com};
62012853Sgabeblack@google.com
62112853Sgabeblack@google.com
62212853Sgabeblack@google.com// ----------------------------------------------------------------------------
62312853Sgabeblack@google.com// ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref
62412853Sgabeblack@google.com// ----------------------------------------------------------------------------
62512853Sgabeblack@google.com
62612853Sgabeblack@google.com#define SC_CONCAT_OP_TYPE(RESULT, OP, OTHER_TYPE) \
62712853Sgabeblack@google.com    inline RESULT \
62812853Sgabeblack@google.com    operator OP (const sc_concatref &a, OTHER_TYPE b) \
62912853Sgabeblack@google.com    { \
63012853Sgabeblack@google.com        return a.value() OP b; \
63112853Sgabeblack@google.com    } \
63212853Sgabeblack@google.com    inline RESULT \
63312853Sgabeblack@google.com    operator OP (OTHER_TYPE a, const sc_concatref &b) \
63412853Sgabeblack@google.com    { \
63512853Sgabeblack@google.com        return a OP b.value(); \
63612853Sgabeblack@google.com    }
63712853Sgabeblack@google.com
63812853Sgabeblack@google.com
63912853Sgabeblack@google.com#define SC_CONCAT_OP(RESULT, OP) \
64012853Sgabeblack@google.com    inline RESULT \
64112853Sgabeblack@google.com    operator OP (const sc_concatref &a, const sc_concatref &b) \
64212853Sgabeblack@google.com    { \
64312853Sgabeblack@google.com        return a.value() OP b.value(); \
64412853Sgabeblack@google.com    }  \
64512853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(const sc_signed, OP, int) \
64612853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(const sc_signed, OP, long) \
64712853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(const sc_signed, OP, int64) \
64812853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(RESULT, OP, unsigned int) \
64912853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(RESULT, OP, unsigned long) \
65012853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(RESULT, OP, uint64) \
65112853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_int_base &) \
65212853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(RESULT, OP, const sc_uint_base &) \
65312853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_signed &) \
65412853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(RESULT, OP, const sc_unsigned &) \
65512853Sgabeblack@google.com    inline RESULT \
65612853Sgabeblack@google.com    operator OP (const sc_concatref &a, bool b) \
65712853Sgabeblack@google.com    { \
65812853Sgabeblack@google.com        return a.value() OP (int)b; \
65912853Sgabeblack@google.com    } \
66012853Sgabeblack@google.com    inline RESULT \
66112853Sgabeblack@google.com    operator OP (bool a, const sc_concatref &b) \
66212853Sgabeblack@google.com    { \
66312853Sgabeblack@google.com        return (int)a OP b.value(); \
66412853Sgabeblack@google.com    }
66512853Sgabeblack@google.com
66612853Sgabeblack@google.com#define SC_CONCAT_BOOL_OP(OP) \
66712853Sgabeblack@google.com    inline bool \
66812853Sgabeblack@google.com    operator OP (const sc_concatref &a, const sc_concatref &b) \
66912853Sgabeblack@google.com    { \
67012853Sgabeblack@google.com        return a.value() OP b.value(); \
67112853Sgabeblack@google.com    }  \
67212853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, int) \
67312853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, long) \
67412853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, int64) \
67512853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, unsigned int) \
67612853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, unsigned long) \
67712853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, uint64) \
67812853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, const sc_int_base &) \
67912853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, const sc_uint_base &) \
68012853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, const sc_signed &) \
68112853Sgabeblack@google.com    SC_CONCAT_OP_TYPE(bool, OP, const sc_unsigned &) \
68212853Sgabeblack@google.com    inline bool \
68312853Sgabeblack@google.com    operator OP (const sc_concatref &a, bool b) \
68412853Sgabeblack@google.com    { \
68512853Sgabeblack@google.com        return a.value() OP (int)b; \
68612853Sgabeblack@google.com    } \
68712853Sgabeblack@google.com    inline bool \
68812853Sgabeblack@google.com    operator OP (bool a, const sc_concatref &b) \
68912853Sgabeblack@google.com    { \
69012853Sgabeblack@google.com        return (int)a OP b.value(); \
69112853Sgabeblack@google.com    }
69212853Sgabeblack@google.com
69312853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, +)
69412853Sgabeblack@google.comSC_CONCAT_OP(const sc_signed, -)
69512853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, *)
69612853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, /)
69712853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, %)
69812853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, &)
69912853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, |)
70012853Sgabeblack@google.comSC_CONCAT_OP(const sc_unsigned, ^)
70112853Sgabeblack@google.comSC_CONCAT_BOOL_OP(==)
70212853Sgabeblack@google.comSC_CONCAT_BOOL_OP(<=)
70312853Sgabeblack@google.comSC_CONCAT_BOOL_OP(>=)
70412853Sgabeblack@google.comSC_CONCAT_BOOL_OP(!=)
70512853Sgabeblack@google.comSC_CONCAT_BOOL_OP(>)
70612853Sgabeblack@google.comSC_CONCAT_BOOL_OP(<)
70712853Sgabeblack@google.com
70812853Sgabeblack@google.com#undef SC_CONCAT_OP
70912853Sgabeblack@google.com#undef SC_CONCAT_OP_TYPE
71012853Sgabeblack@google.com
71112853Sgabeblack@google.com
71212853Sgabeblack@google.com// ----------------------------------------------------------------------------
71312853Sgabeblack@google.com// CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES:
71412853Sgabeblack@google.com// ----------------------------------------------------------------------------
71512853Sgabeblack@google.com
71612853Sgabeblack@google.cominline sc_dt::sc_concatref &
71712853Sgabeblack@google.comconcat(sc_dt::sc_value_base &a, sc_dt::sc_value_base &b)
71812853Sgabeblack@google.com{
71912853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
72012853Sgabeblack@google.com
72112853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
72212853Sgabeblack@google.com    result_p->initialize(a, b);
72312853Sgabeblack@google.com    return *result_p;
72412853Sgabeblack@google.com}
72512853Sgabeblack@google.com
72612853Sgabeblack@google.cominline const sc_dt::sc_concatref &
72712853Sgabeblack@google.comconcat(const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b)
72812853Sgabeblack@google.com{
72912853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
73012853Sgabeblack@google.com
73112853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
73212853Sgabeblack@google.com    result_p->initialize(a, b);
73312853Sgabeblack@google.com    return *result_p;
73412853Sgabeblack@google.com}
73512853Sgabeblack@google.com
73612853Sgabeblack@google.cominline const sc_dt::sc_concatref &
73712853Sgabeblack@google.comconcat(const sc_dt::sc_value_base &a, bool b)
73812853Sgabeblack@google.com{
73912853Sgabeblack@google.com    const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value.
74012853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
74112853Sgabeblack@google.com
74212853Sgabeblack@google.com    b_p = sc_dt::sc_concat_bool::allocate(b);
74312853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
74412853Sgabeblack@google.com    result_p->initialize(a, *b_p);
74512853Sgabeblack@google.com    return *result_p;
74612853Sgabeblack@google.com}
74712853Sgabeblack@google.com
74812853Sgabeblack@google.cominline const sc_dt::sc_concatref &
74912853Sgabeblack@google.comconcat(bool a, const sc_dt::sc_value_base &b)
75012853Sgabeblack@google.com{
75112853Sgabeblack@google.com    const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value.
75212853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
75312853Sgabeblack@google.com
75412853Sgabeblack@google.com    a_p = sc_dt::sc_concat_bool::allocate(a);
75512853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
75612853Sgabeblack@google.com    result_p->initialize(*a_p, b);
75712853Sgabeblack@google.com    return *result_p;
75812853Sgabeblack@google.com}
75912853Sgabeblack@google.com
76012853Sgabeblack@google.cominline sc_dt::sc_concatref &
76112853Sgabeblack@google.comoperator , (sc_dt::sc_value_base &a, sc_dt::sc_value_base &b)
76212853Sgabeblack@google.com{
76312853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
76412853Sgabeblack@google.com
76512853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
76612853Sgabeblack@google.com    result_p->initialize(a, b);
76712853Sgabeblack@google.com    return *result_p;
76812853Sgabeblack@google.com}
76912853Sgabeblack@google.com
77012853Sgabeblack@google.cominline const sc_dt::sc_concatref &
77112853Sgabeblack@google.comoperator , (const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b)
77212853Sgabeblack@google.com{
77312853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
77412853Sgabeblack@google.com
77512853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
77612853Sgabeblack@google.com    result_p->initialize(a, b);
77712853Sgabeblack@google.com    return *result_p;
77812853Sgabeblack@google.com}
77912853Sgabeblack@google.com
78012853Sgabeblack@google.cominline const sc_dt::sc_concatref &
78112853Sgabeblack@google.comoperator , (const sc_dt::sc_value_base &a, bool b)
78212853Sgabeblack@google.com{
78312853Sgabeblack@google.com    const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value.
78412853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
78512853Sgabeblack@google.com
78612853Sgabeblack@google.com    b_p = sc_dt::sc_concat_bool::allocate(b);
78712853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
78812853Sgabeblack@google.com    result_p->initialize(a, *b_p);
78912853Sgabeblack@google.com    return *result_p;
79012853Sgabeblack@google.com}
79112853Sgabeblack@google.com
79212853Sgabeblack@google.cominline const sc_dt::sc_concatref &
79312853Sgabeblack@google.comoperator , (bool a, const sc_dt::sc_value_base &b)
79412853Sgabeblack@google.com{
79512853Sgabeblack@google.com    const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value.
79612853Sgabeblack@google.com    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.
79712853Sgabeblack@google.com
79812853Sgabeblack@google.com    a_p = sc_dt::sc_concat_bool::allocate(a);
79912853Sgabeblack@google.com    result_p = sc_dt::sc_concatref::m_pool.allocate();
80012853Sgabeblack@google.com    result_p->initialize(*a_p, b);
80112853Sgabeblack@google.com    return *result_p;
80212853Sgabeblack@google.com}
80312853Sgabeblack@google.com
80412853Sgabeblack@google.com} // namespace sc_dt
80512853Sgabeblack@google.com
80612853Sgabeblack@google.com#endif //  __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__
807