112854Sgabeblack@google.com/*****************************************************************************
212854Sgabeblack@google.com
312854Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412854Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512854Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612854Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712854Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812854Sgabeblack@google.com  License.  You may obtain a copy of the License at
912854Sgabeblack@google.com
1012854Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112854Sgabeblack@google.com
1212854Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312854Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412854Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512854Sgabeblack@google.com  implied.  See the License for the specific language governing
1612854Sgabeblack@google.com  permissions and limitations under the License.
1712854Sgabeblack@google.com
1812854Sgabeblack@google.com *****************************************************************************/
1912854Sgabeblack@google.com
2012854Sgabeblack@google.com/*****************************************************************************
2112854Sgabeblack@google.com
2212854Sgabeblack@google.com  sc_signed_subref.h -- Proxy class that is declared in sc_signed.h.
2312854Sgabeblack@google.com
2412854Sgabeblack@google.com  Original Author: Ali Dasdan, Synopsys, Inc.
2512854Sgabeblack@google.com
2612854Sgabeblack@google.com *****************************************************************************/
2712854Sgabeblack@google.com
2812854Sgabeblack@google.com/*****************************************************************************
2912854Sgabeblack@google.com
3012854Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112854Sgabeblack@google.com  changes you are making here.
3212854Sgabeblack@google.com
3312854Sgabeblack@google.com      Name, Affiliation, Date:
3412854Sgabeblack@google.com  Description of Modification:
3512854Sgabeblack@google.com
3612854Sgabeblack@google.com *****************************************************************************/
3712854Sgabeblack@google.com
3812854Sgabeblack@google.com
3912854Sgabeblack@google.com// ----------------------------------------------------------------------------
4012854Sgabeblack@google.com//  CLASS : sc_signed_subref_r
4112854Sgabeblack@google.com//
4212854Sgabeblack@google.com//  Proxy class for sc_signed part selection (r-value only).
4312854Sgabeblack@google.com// ----------------------------------------------------------------------------
4412854Sgabeblack@google.com
4512854Sgabeblack@google.com// concatenation support
4612854Sgabeblack@google.com
4712854Sgabeblack@google.comuint64
4812854Sgabeblack@google.comsc_signed_subref_r::concat_get_uint64() const
4912854Sgabeblack@google.com{
5012854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
5112854Sgabeblack@google.com    return a.to_uint64();
5212854Sgabeblack@google.com}
5312854Sgabeblack@google.com
5412854Sgabeblack@google.com
5512854Sgabeblack@google.combool
5612854Sgabeblack@google.comsc_signed_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
5712854Sgabeblack@google.com{
5812854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
5912854Sgabeblack@google.com    return a.concat_get_ctrl(dst_p, low_i);
6012854Sgabeblack@google.com}
6112854Sgabeblack@google.com
6212854Sgabeblack@google.com
6312854Sgabeblack@google.combool
6412854Sgabeblack@google.comsc_signed_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
6512854Sgabeblack@google.com{
6612854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
6712854Sgabeblack@google.com    return a.concat_get_data(dst_p, low_i);
6812854Sgabeblack@google.com}
6912854Sgabeblack@google.com
7012854Sgabeblack@google.com
7112854Sgabeblack@google.com// implicit conversion to sc_signed
7212854Sgabeblack@google.comsc_signed_subref_r::operator sc_unsigned () const
7312854Sgabeblack@google.com{
7412854Sgabeblack@google.com    return sc_unsigned(m_obj_p, m_left, m_right);
7512854Sgabeblack@google.com}
7612854Sgabeblack@google.com
7712854Sgabeblack@google.com
7812854Sgabeblack@google.com// explicit conversions
7912854Sgabeblack@google.comint
8012854Sgabeblack@google.comsc_signed_subref_r::to_int() const
8112854Sgabeblack@google.com{
8212854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
8312854Sgabeblack@google.com    return a.to_int();
8412854Sgabeblack@google.com}
8512854Sgabeblack@google.com
8612854Sgabeblack@google.comunsigned int
8712854Sgabeblack@google.comsc_signed_subref_r::to_uint() const
8812854Sgabeblack@google.com{
8912854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
9012854Sgabeblack@google.com    return a.to_uint();
9112854Sgabeblack@google.com}
9212854Sgabeblack@google.com
9312854Sgabeblack@google.comlong
9412854Sgabeblack@google.comsc_signed_subref_r::to_long() const
9512854Sgabeblack@google.com{
9612854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
9712854Sgabeblack@google.com    return a.to_long();
9812854Sgabeblack@google.com}
9912854Sgabeblack@google.com
10012854Sgabeblack@google.comunsigned long
10112854Sgabeblack@google.comsc_signed_subref_r::to_ulong() const
10212854Sgabeblack@google.com{
10312854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
10412854Sgabeblack@google.com    return a.to_ulong();
10512854Sgabeblack@google.com}
10612854Sgabeblack@google.com
10712854Sgabeblack@google.comint64
10812854Sgabeblack@google.comsc_signed_subref_r::to_int64() const
10912854Sgabeblack@google.com{
11012854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
11112854Sgabeblack@google.com    return a.to_int64();
11212854Sgabeblack@google.com}
11312854Sgabeblack@google.com
11412854Sgabeblack@google.comuint64
11512854Sgabeblack@google.comsc_signed_subref_r::to_uint64() const
11612854Sgabeblack@google.com{
11712854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
11812854Sgabeblack@google.com    return a.to_uint64();
11912854Sgabeblack@google.com}
12012854Sgabeblack@google.com
12112854Sgabeblack@google.comdouble
12212854Sgabeblack@google.comsc_signed_subref_r::to_double() const
12312854Sgabeblack@google.com{
12412854Sgabeblack@google.com    sc_unsigned a(m_obj_p, m_left, m_right);
12512854Sgabeblack@google.com    return a.to_double();
12612854Sgabeblack@google.com}
12712854Sgabeblack@google.com
12812854Sgabeblack@google.com
12912854Sgabeblack@google.com// explicit conversion to character string
13012854Sgabeblack@google.comconst std::string
13112854Sgabeblack@google.comsc_signed_subref_r::to_string(sc_numrep numrep) const
13212854Sgabeblack@google.com{
13312854Sgabeblack@google.com    sc_unsigned a(length());
13412854Sgabeblack@google.com    a = *this;
13512854Sgabeblack@google.com    return a.to_string(numrep);
13612854Sgabeblack@google.com}
13712854Sgabeblack@google.com
13812854Sgabeblack@google.comconst std::string
13912854Sgabeblack@google.comsc_signed_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
14012854Sgabeblack@google.com{
14112854Sgabeblack@google.com    sc_unsigned a(length());
14212854Sgabeblack@google.com    a = *this;
14312854Sgabeblack@google.com    return a.to_string(numrep, w_prefix);
14412854Sgabeblack@google.com}
14512854Sgabeblack@google.com
14612854Sgabeblack@google.com
14712854Sgabeblack@google.com// ----------------------------------------------------------------------------
14812854Sgabeblack@google.com//  CLASS : sc_signed_subref
14912854Sgabeblack@google.com//
15012854Sgabeblack@google.com//  Proxy class for sc_signed part selection (r-value and l-value).
15112854Sgabeblack@google.com// ----------------------------------------------------------------------------
15212854Sgabeblack@google.com
15312854Sgabeblack@google.com// assignment operators
15412854Sgabeblack@google.com
15512854Sgabeblack@google.comconst sc_signed_subref &
15612854Sgabeblack@google.comsc_signed_subref::operator = (const sc_signed_subref_r &a)
15712854Sgabeblack@google.com{
15812854Sgabeblack@google.com    return operator = ((sc_unsigned)(a));
15912854Sgabeblack@google.com}
16012854Sgabeblack@google.com
16112854Sgabeblack@google.comconst sc_signed_subref &
16212854Sgabeblack@google.comsc_signed_subref::operator = (const sc_signed_subref &v)
16312854Sgabeblack@google.com{
16412854Sgabeblack@google.com    if (this == &v) {
16512854Sgabeblack@google.com        return *this;
16612854Sgabeblack@google.com    }
16712854Sgabeblack@google.com    return operator = ((sc_unsigned)(v));
16812854Sgabeblack@google.com}
16912854Sgabeblack@google.com
17012854Sgabeblack@google.comconst sc_signed_subref &
17112854Sgabeblack@google.comsc_signed_subref::operator = (const sc_signed &v)
17212854Sgabeblack@google.com{
17312854Sgabeblack@google.com    int i;
17412854Sgabeblack@google.com    int l = sc_min(m_left, v.nbits - 1 + m_right);
17512854Sgabeblack@google.com
17612854Sgabeblack@google.com    for (i = m_right; i <= l; ++i)
17712854Sgabeblack@google.com        m_obj_p->set(i, v.test(i - m_right));
17812854Sgabeblack@google.com    for (; i <= m_left; i++)
17912854Sgabeblack@google.com        m_obj_p->set(i, v.test(l));
18012854Sgabeblack@google.com
18112854Sgabeblack@google.com    return *this;
18212854Sgabeblack@google.com}
18312854Sgabeblack@google.com
18412854Sgabeblack@google.comconst sc_signed_subref &
18512854Sgabeblack@google.comsc_signed_subref::operator = (const sc_unsigned_subref_r &v)
18612854Sgabeblack@google.com{
18712854Sgabeblack@google.com    return operator = ((sc_unsigned)(v));
18812854Sgabeblack@google.com}
18912854Sgabeblack@google.com
19012854Sgabeblack@google.comconst sc_signed_subref &
19112854Sgabeblack@google.comsc_signed_subref::operator = (const sc_unsigned &v)
19212854Sgabeblack@google.com{
19312854Sgabeblack@google.com    int i;
19412854Sgabeblack@google.com    int l = sc_min(m_left, v.nbits - 1 + m_right);
19512854Sgabeblack@google.com
19612854Sgabeblack@google.com    for (i = m_right; i <= l; ++i)
19712854Sgabeblack@google.com        m_obj_p->set(i, v.test(i - m_right));
19812854Sgabeblack@google.com    for (; i <= m_left; i++)
19912854Sgabeblack@google.com        m_obj_p->set(i, 0);
20012854Sgabeblack@google.com    return *this;
20112854Sgabeblack@google.com}
20212854Sgabeblack@google.com
20312854Sgabeblack@google.comconst sc_signed_subref &
20412854Sgabeblack@google.comsc_signed_subref::operator = (unsigned long v)
20512854Sgabeblack@google.com{
20612854Sgabeblack@google.com    for (int i = m_right; i <= m_left; ++i) {
20712854Sgabeblack@google.com        m_obj_p->set(i, static_cast<bool>(v & 1));
20812854Sgabeblack@google.com        v >>= 1;
20912854Sgabeblack@google.com    }
21012854Sgabeblack@google.com    return *this;
21112854Sgabeblack@google.com}
21212854Sgabeblack@google.com
21312854Sgabeblack@google.comconst sc_signed_subref &
21412854Sgabeblack@google.comsc_signed_subref::operator = (long v)
21512854Sgabeblack@google.com{
21612854Sgabeblack@google.com    unsigned long v2 = (unsigned long)v;
21712854Sgabeblack@google.com    for (int i = m_right; i <= m_left; ++i) {
21812854Sgabeblack@google.com        m_obj_p->set(i, static_cast<bool>(v2 & 1));
21912854Sgabeblack@google.com        v2 >>= 1;
22012854Sgabeblack@google.com    }
22112854Sgabeblack@google.com    return *this;
22212854Sgabeblack@google.com}
22312854Sgabeblack@google.com
22412854Sgabeblack@google.comconst sc_signed_subref &
22512854Sgabeblack@google.comsc_signed_subref::operator = (uint64 v)
22612854Sgabeblack@google.com{
22712854Sgabeblack@google.com    for (int i = m_right; i <= m_left; ++i) {
22812854Sgabeblack@google.com        m_obj_p->set(i, static_cast<bool>(v & 1));
22912854Sgabeblack@google.com        v >>= 1;
23012854Sgabeblack@google.com    }
23112854Sgabeblack@google.com    return *this;
23212854Sgabeblack@google.com}
23312854Sgabeblack@google.com
23412854Sgabeblack@google.comconst sc_signed_subref &
23512854Sgabeblack@google.comsc_signed_subref::operator = (int64 v)
23612854Sgabeblack@google.com{
23712854Sgabeblack@google.com    uint64 v2 = (uint64)v;
23812854Sgabeblack@google.com    for (int i = m_right; i <= m_left; ++i) {
23912854Sgabeblack@google.com        m_obj_p->set(i, static_cast<bool>(v2 & 1));
24012854Sgabeblack@google.com        v2 >>= 1;
24112854Sgabeblack@google.com    }
24212854Sgabeblack@google.com    return *this;
24312854Sgabeblack@google.com}
24412854Sgabeblack@google.com
24512854Sgabeblack@google.comconst sc_signed_subref &
24612854Sgabeblack@google.comsc_signed_subref::operator = (double v)
24712854Sgabeblack@google.com{
24812854Sgabeblack@google.com    is_bad_double(v);
24912854Sgabeblack@google.com
25012854Sgabeblack@google.com    int nb = m_left - m_right + 1;
25112854Sgabeblack@google.com    int nd = DIV_CEIL(nb);
25212854Sgabeblack@google.com
25312854Sgabeblack@google.com#ifdef SC_MAX_NBITS
25412854Sgabeblack@google.com    sc_digit d[MAX_NDIGITS];
25512854Sgabeblack@google.com#else
25612854Sgabeblack@google.com    sc_digit *d = new sc_digit[nd];
25712854Sgabeblack@google.com#endif
25812854Sgabeblack@google.com
25912854Sgabeblack@google.com    if (v < 0)
26012854Sgabeblack@google.com        v = -v;
26112854Sgabeblack@google.com
26212854Sgabeblack@google.com    int i = 0;
26312854Sgabeblack@google.com
26412854Sgabeblack@google.com    while (std::floor(v) && (i < nd)) {
26512854Sgabeblack@google.com#ifndef _WIN32
26612854Sgabeblack@google.com        d[i++] = (sc_digit) std::floor(remainder(v, DIGIT_RADIX));
26712854Sgabeblack@google.com#else
26812854Sgabeblack@google.com        d[i++] = (sc_digit) std::floor(std::fmod(v, DIGIT_RADIX));
26912854Sgabeblack@google.com#endif
27012854Sgabeblack@google.com        v /= DIGIT_RADIX;
27112854Sgabeblack@google.com    }
27212854Sgabeblack@google.com
27312854Sgabeblack@google.com    vec_zero(i, nd, d);
27412854Sgabeblack@google.com    sc_digit val = 1;  // Bit value.
27512854Sgabeblack@google.com    int j = 0;   // Current digit in d.
27612854Sgabeblack@google.com    i = 0;  // Current bit in d.
27712854Sgabeblack@google.com    while (i < nb) {
27812854Sgabeblack@google.com        m_obj_p->set(i + m_right, (bool)(d[j] & val));
27912854Sgabeblack@google.com        ++i;
28012854Sgabeblack@google.com        if (i % BITS_PER_DIGIT == 0) {
28112854Sgabeblack@google.com            val = 1;
28212854Sgabeblack@google.com            ++j;
28312854Sgabeblack@google.com        } else {
28412854Sgabeblack@google.com            val <<= 1;
28512854Sgabeblack@google.com        }
28612854Sgabeblack@google.com    }
28712854Sgabeblack@google.com
28812854Sgabeblack@google.com#ifndef SC_MAX_NBITS
28912854Sgabeblack@google.com    delete [] d;
29012854Sgabeblack@google.com#endif
29112854Sgabeblack@google.com    return *this;
29212854Sgabeblack@google.com}
29312854Sgabeblack@google.com
29412854Sgabeblack@google.comconst sc_signed_subref &
29512854Sgabeblack@google.comsc_signed_subref::operator = (const sc_int_base &a)
29612854Sgabeblack@google.com{
29712854Sgabeblack@google.com    return operator = ((int64)a);
29812854Sgabeblack@google.com}
29912854Sgabeblack@google.com
30012854Sgabeblack@google.comconst sc_signed_subref &
30112854Sgabeblack@google.comsc_signed_subref::operator = (const sc_uint_base &a)
30212854Sgabeblack@google.com{
30312854Sgabeblack@google.com    return operator = ((uint64)a);
30412854Sgabeblack@google.com}
30512854Sgabeblack@google.com
30612854Sgabeblack@google.com// concatenation methods
30712854Sgabeblack@google.com
30812854Sgabeblack@google.com
30912854Sgabeblack@google.comvoid
31012854Sgabeblack@google.comsc_signed_subref::concat_set(int64 src, int low_i)
31112854Sgabeblack@google.com{
31212854Sgabeblack@google.com    int  i;
31312854Sgabeblack@google.com    int  l;
31412854Sgabeblack@google.com    bool sign = src < 0;
31512854Sgabeblack@google.com
31612854Sgabeblack@google.com    if (low_i < 64) {
31712854Sgabeblack@google.com        src = src >> low_i;
31812854Sgabeblack@google.com        l = sc_min(m_left, (63 - low_i) + m_right);
31912854Sgabeblack@google.com        for (i = m_right; i <= l; ++i) {
32012854Sgabeblack@google.com            m_obj_p->set(i, src & 1);
32112854Sgabeblack@google.com            src = src >> 1;
32212854Sgabeblack@google.com        }
32312854Sgabeblack@google.com        for (; i <= m_left; i++)
32412854Sgabeblack@google.com            m_obj_p->set(i, sign);
32512854Sgabeblack@google.com    } else {
32612854Sgabeblack@google.com        for (i = m_right; i <= m_left; ++i)
32712854Sgabeblack@google.com            m_obj_p->set(i, sign);
32812854Sgabeblack@google.com    }
32912854Sgabeblack@google.com}
33012854Sgabeblack@google.com
33112854Sgabeblack@google.comvoid
33212854Sgabeblack@google.comsc_signed_subref::concat_set(const sc_signed &src, int low_i)
33312854Sgabeblack@google.com{
33412854Sgabeblack@google.com    int i;
33512854Sgabeblack@google.com    int l;
33612854Sgabeblack@google.com    int src_i;
33712854Sgabeblack@google.com    bool sign = src.test(src.nbits - 1);
33812854Sgabeblack@google.com    l = src.nbits - (low_i + 1);
33912854Sgabeblack@google.com    if (l >= 0) {
34012854Sgabeblack@google.com        l = sc_min(m_left, l + m_right);
34112854Sgabeblack@google.com        src_i = low_i;
34212854Sgabeblack@google.com        for (i = m_right; i <= l; ++i, src_i++) {
34312854Sgabeblack@google.com            m_obj_p->set(i, src.test(src_i));
34412854Sgabeblack@google.com        }
34512854Sgabeblack@google.com        for (; i <= m_left; i++)
34612854Sgabeblack@google.com            m_obj_p->set(i, sign);
34712854Sgabeblack@google.com    } else {
34812854Sgabeblack@google.com        for (i = m_right; i <= m_left; ++i)
34912854Sgabeblack@google.com            m_obj_p->set(i, sign);
35012854Sgabeblack@google.com    }
35112854Sgabeblack@google.com}
35212854Sgabeblack@google.com
35312854Sgabeblack@google.comvoid
35412854Sgabeblack@google.comsc_signed_subref::concat_set(const sc_unsigned &src, int low_i)
35512854Sgabeblack@google.com{
35612854Sgabeblack@google.com    int i;
35712854Sgabeblack@google.com    int l;
35812854Sgabeblack@google.com    int src_i;
35912854Sgabeblack@google.com    l = src.nbits - (low_i + 2);
36012854Sgabeblack@google.com    if (l >= 0) {
36112854Sgabeblack@google.com        l = sc_min(m_left, l + m_right);
36212854Sgabeblack@google.com        src_i = low_i;
36312854Sgabeblack@google.com        for (i = m_right; i <= l; ++i, src_i++) {
36412854Sgabeblack@google.com            m_obj_p->set(i, src.test(src_i));
36512854Sgabeblack@google.com        }
36612854Sgabeblack@google.com        for (; i <= m_left; i++)
36712854Sgabeblack@google.com            m_obj_p->set(false);
36812854Sgabeblack@google.com    } else {
36912854Sgabeblack@google.com        for (i = m_right; i <= m_left; ++i)
37012854Sgabeblack@google.com            m_obj_p->set(false);
37112854Sgabeblack@google.com    }
37212854Sgabeblack@google.com}
37312854Sgabeblack@google.com
37412854Sgabeblack@google.comvoid
37512854Sgabeblack@google.comsc_signed_subref::concat_set(uint64 src, int low_i)
37612854Sgabeblack@google.com{
37712854Sgabeblack@google.com    int  i;
37812854Sgabeblack@google.com    int  l;
37912854Sgabeblack@google.com
38012854Sgabeblack@google.com    if (low_i < 64) {
38112854Sgabeblack@google.com        src = src >> low_i;
38212854Sgabeblack@google.com        l = sc_min(m_left, (63 - low_i) + m_right);
38312854Sgabeblack@google.com        for (i = m_right; i <= l; ++i) {
38412854Sgabeblack@google.com            m_obj_p->set(i, src & 1);
38512854Sgabeblack@google.com            src = src >> 1;
38612854Sgabeblack@google.com        }
38712854Sgabeblack@google.com        for (; i <= m_left; i++)
38812854Sgabeblack@google.com            m_obj_p->set(false);
38912854Sgabeblack@google.com    } else {
39012854Sgabeblack@google.com        for (i = m_right; i <= m_left; ++i)
39112854Sgabeblack@google.com            m_obj_p->set(false);
39212854Sgabeblack@google.com    }
39312854Sgabeblack@google.com}
39412854Sgabeblack@google.com
39512854Sgabeblack@google.com// other methods
39612854Sgabeblack@google.comvoid
39712854Sgabeblack@google.comsc_signed_subref::scan(::std::istream &is)
39812854Sgabeblack@google.com{
39912854Sgabeblack@google.com    std::string s;
40012854Sgabeblack@google.com    is >> s;
40112854Sgabeblack@google.com    *this = s.c_str();
40212854Sgabeblack@google.com}
403