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_uint_base.cpp -- contains interface definitions between sc_uint and
2312854Sgabeblack@google.com                 sc_signed, sc_unsigned, and definitions for sc_uint_subref.
2412854Sgabeblack@google.com
2512854Sgabeblack@google.com  Original Author: Ali Dasdan, Synopsys, Inc.
2612854Sgabeblack@google.com
2712854Sgabeblack@google.com *****************************************************************************/
2812854Sgabeblack@google.com
2912854Sgabeblack@google.com/*****************************************************************************
3012854Sgabeblack@google.com
3112854Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3212854Sgabeblack@google.com  changes you are making here.
3312854Sgabeblack@google.com
3412854Sgabeblack@google.com      Name, Affiliation, Date:
3512854Sgabeblack@google.com  Description of Modification:
3612854Sgabeblack@google.com
3712854Sgabeblack@google.com *****************************************************************************/
3812854Sgabeblack@google.com
3912854Sgabeblack@google.com
4012854Sgabeblack@google.com// $Log: sc_uint_base.cpp,v $
4112854Sgabeblack@google.com// Revision 1.5  2011/02/18 20:19:15  acg
4212854Sgabeblack@google.com//  Andy Goodrich: updating Copyright notice.
4312854Sgabeblack@google.com//
4412854Sgabeblack@google.com// Revision 1.4  2010/02/04 22:23:29  acg
4512854Sgabeblack@google.com//  Andy Goodrich: fixed bug in concatenation reads for part selections,
4612854Sgabeblack@google.com//  the mask being used was 32 bits and should have been 64 bits.
4712854Sgabeblack@google.com//
4812854Sgabeblack@google.com// Revision 1.3  2008/06/19 17:47:57  acg
4912854Sgabeblack@google.com//  Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
5012854Sgabeblack@google.com//
5112854Sgabeblack@google.com// Revision 1.2  2007/11/04 21:27:00  acg
5212854Sgabeblack@google.com//  Andy Goodrich: changes to make sure the proper value is returned from
5312854Sgabeblack@google.com//  concat_get_data().
5412854Sgabeblack@google.com//
5512854Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:05  acg
5612854Sgabeblack@google.com// SystemC 2.3
5712854Sgabeblack@google.com//
5812854Sgabeblack@google.com// Revision 1.3  2006/01/13 18:49:32  acg
5912854Sgabeblack@google.com// Added $Log command so that CVS check in comments are reproduced in the
6012854Sgabeblack@google.com// source.
6112854Sgabeblack@google.com//
6212854Sgabeblack@google.com
6312854Sgabeblack@google.com#include <sstream>
6412854Sgabeblack@google.com
6512854Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_bv_base.hh"
6612854Sgabeblack@google.com#include "systemc/ext/dt/bit/sc_lv_base.hh"
6712854Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_ufix.hh"
6812854Sgabeblack@google.com#include "systemc/ext/dt/fx/scfx_other_defs.hh"
6912854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_signed.hh"
7012854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_uint_base.hh"
7112854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_unsigned.hh"
7212854Sgabeblack@google.com#include "systemc/ext/dt/misc/sc_concatref.hh"
7312854Sgabeblack@google.com
7412854Sgabeblack@google.com// explicit template instantiations
7512854Sgabeblack@google.comnamespace sc_core
7612854Sgabeblack@google.com{
7712854Sgabeblack@google.com
7812854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_uint_bitref>;
7912854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_uint_subref>;
8012854Sgabeblack@google.com
8112854Sgabeblack@google.com} // namespace sc_core
8212854Sgabeblack@google.com
8312854Sgabeblack@google.comnamespace sc_dt
8412854Sgabeblack@google.com{
8512854Sgabeblack@google.com
8612854Sgabeblack@google.com// to avoid code bloat in sc_uint_concat<T1,T2>
8712854Sgabeblack@google.com
8812854Sgabeblack@google.comvoid
8912854Sgabeblack@google.comsc_uint_concref_invalid_length(int length)
9012854Sgabeblack@google.com{
9112854Sgabeblack@google.com    std::stringstream msg;
9212854Sgabeblack@google.com    msg << "sc_uint_concref<T1,T2> initialization: length = " << length <<
9312854Sgabeblack@google.com           "violates 1 <= length <= " << SC_INTWIDTH;
9413322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
9512854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
9612854Sgabeblack@google.com}
9712854Sgabeblack@google.com
9812854Sgabeblack@google.com
9912854Sgabeblack@google.com
10012854Sgabeblack@google.com// ----------------------------------------------------------------------------
10112854Sgabeblack@google.com//  CLASS : sc_uint_bitref
10212854Sgabeblack@google.com//
10312854Sgabeblack@google.com//  Proxy class for sc_uint bit selection (r-value and l-value).
10412854Sgabeblack@google.com// ----------------------------------------------------------------------------
10512854Sgabeblack@google.com
10612854Sgabeblack@google.comsc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
10712854Sgabeblack@google.com
10812854Sgabeblack@google.com// concatenation methods:
10912854Sgabeblack@google.com
11012854Sgabeblack@google.com// #### OPTIMIZE
11112854Sgabeblack@google.comvoid
11212854Sgabeblack@google.comsc_uint_bitref::concat_set(int64 src, int low_i)
11312854Sgabeblack@google.com{
11412854Sgabeblack@google.com    sc_uint_base aa(1);
11512854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
11612854Sgabeblack@google.com}
11712854Sgabeblack@google.com
11812854Sgabeblack@google.comvoid
11912854Sgabeblack@google.comsc_uint_bitref::concat_set(const sc_signed &src, int low_i)
12012854Sgabeblack@google.com{
12112854Sgabeblack@google.com    sc_uint_base aa(1);
12212854Sgabeblack@google.com    if (low_i < src.length())
12312854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
12412854Sgabeblack@google.com    else
12512854Sgabeblack@google.com        *this = aa = (src < 0) ? (int_type)-1 : 0;
12612854Sgabeblack@google.com}
12712854Sgabeblack@google.com
12812854Sgabeblack@google.comvoid
12912854Sgabeblack@google.comsc_uint_bitref::concat_set(const sc_unsigned &src, int low_i)
13012854Sgabeblack@google.com{
13112854Sgabeblack@google.com    sc_uint_base aa(1);
13212854Sgabeblack@google.com    if (low_i < src.length())
13312854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
13412854Sgabeblack@google.com    else
13512854Sgabeblack@google.com        *this = aa = 0;
13612854Sgabeblack@google.com}
13712854Sgabeblack@google.com
13812854Sgabeblack@google.comvoid
13912854Sgabeblack@google.comsc_uint_bitref::concat_set(uint64 src, int low_i)
14012854Sgabeblack@google.com{
14112854Sgabeblack@google.com    sc_uint_base aa(1);
14212854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
14312854Sgabeblack@google.com}
14412854Sgabeblack@google.com
14512854Sgabeblack@google.com
14612854Sgabeblack@google.com// other methods
14712854Sgabeblack@google.comvoid
14812854Sgabeblack@google.comsc_uint_bitref::scan(::std::istream &is)
14912854Sgabeblack@google.com{
15012854Sgabeblack@google.com    bool b;
15112854Sgabeblack@google.com    is >> b;
15212854Sgabeblack@google.com    *this = b;
15312854Sgabeblack@google.com}
15412854Sgabeblack@google.com
15512854Sgabeblack@google.com
15612854Sgabeblack@google.com// ----------------------------------------------------------------------------
15712854Sgabeblack@google.com//  CLASS : sc_uint_subref_r
15812854Sgabeblack@google.com//
15912854Sgabeblack@google.com//  Proxy class for sc_uint part selection (l-value).
16012854Sgabeblack@google.com// ----------------------------------------------------------------------------
16112854Sgabeblack@google.com
16212854Sgabeblack@google.combool
16312854Sgabeblack@google.comsc_uint_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
16412854Sgabeblack@google.com{
16512854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
16612854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
16712854Sgabeblack@google.com    int left_shift; // Left shift for val.
16812854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
16912854Sgabeblack@google.com
17012854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
17112854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
17212854Sgabeblack@google.com    end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT;
17312854Sgabeblack@google.com
17412854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
17512854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
17612854Sgabeblack@google.com
17712854Sgabeblack@google.com    dst_i++;
17812854Sgabeblack@google.com    for (; dst_i <= end_i; dst_i++)
17912854Sgabeblack@google.com        dst_p[dst_i] = 0;
18012854Sgabeblack@google.com
18112854Sgabeblack@google.com    return false;
18212854Sgabeblack@google.com}
18312854Sgabeblack@google.com
18412854Sgabeblack@google.combool
18512854Sgabeblack@google.comsc_uint_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
18612854Sgabeblack@google.com{
18712854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
18812854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
18912854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
19012854Sgabeblack@google.com    int left_shift; // Left shift for val.
19112854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
19212854Sgabeblack@google.com    bool result; // True if inserting non-zero value.
19312854Sgabeblack@google.com    uint_type val; // Selection value extracted from m_obj_p.
19412854Sgabeblack@google.com
19512854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
19612854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
19712854Sgabeblack@google.com    high_i = low_i + (m_left-m_right);
19812854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
19912854Sgabeblack@google.com    mask = ~mask_int[m_left][m_right];
20012854Sgabeblack@google.com    val = (m_obj_p->m_val & mask) >> m_right;
20112854Sgabeblack@google.com    result = val != 0;
20212854Sgabeblack@google.com
20312854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
20412854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
20512854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
20612854Sgabeblack@google.com        ((val << left_shift) & DIGIT_MASK));
20712854Sgabeblack@google.com
20812854Sgabeblack@google.com    switch (end_i - dst_i) {
20912854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
21012854Sgabeblack@google.com      case 1:
21112854Sgabeblack@google.com        dst_i++;
21212854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT-left_shift);
21312854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
21412854Sgabeblack@google.com        break;
21512854Sgabeblack@google.com
21612854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
21712854Sgabeblack@google.com      case 2:
21812854Sgabeblack@google.com        dst_i++;
21912854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT-left_shift);
22012854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
22112854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
22212854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
22312854Sgabeblack@google.com        break;
22412854Sgabeblack@google.com
22512854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
22612854Sgabeblack@google.com      case 3:
22712854Sgabeblack@google.com        dst_i++;
22812854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT-left_shift);
22912854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23012854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
23112854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23212854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
23312854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
23412854Sgabeblack@google.com        break;
23512854Sgabeblack@google.com    }
23612854Sgabeblack@google.com    return result;
23712854Sgabeblack@google.com}
23812854Sgabeblack@google.com
23912854Sgabeblack@google.com// ----------------------------------------------------------------------------
24012854Sgabeblack@google.com//  CLASS : sc_uint_subref
24112854Sgabeblack@google.com//
24212854Sgabeblack@google.com//  Proxy class for sc_uint part selection (r-value and l-value).
24312854Sgabeblack@google.com// ----------------------------------------------------------------------------
24412854Sgabeblack@google.com
24512854Sgabeblack@google.comsc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
24612854Sgabeblack@google.com
24712854Sgabeblack@google.com// assignment operators
24812854Sgabeblack@google.com
24912854Sgabeblack@google.comsc_uint_subref &
25012854Sgabeblack@google.comsc_uint_subref::operator = (uint_type v)
25112854Sgabeblack@google.com{
25212854Sgabeblack@google.com    uint_type val = m_obj_p->m_val;
25312854Sgabeblack@google.com    uint_type mask = mask_int[m_left][m_right];
25412854Sgabeblack@google.com    val &= mask;
25512854Sgabeblack@google.com    val |= (v << m_right) & ~mask;
25612854Sgabeblack@google.com    m_obj_p->m_val = val;
25712854Sgabeblack@google.com    m_obj_p->extend_sign();
25812854Sgabeblack@google.com    return *this;
25912854Sgabeblack@google.com}
26012854Sgabeblack@google.com
26112854Sgabeblack@google.comsc_uint_subref &
26212854Sgabeblack@google.comsc_uint_subref::operator = (const sc_signed &a)
26312854Sgabeblack@google.com{
26412854Sgabeblack@google.com    sc_uint_base aa(length());
26512854Sgabeblack@google.com    return (*this = aa = a);
26612854Sgabeblack@google.com}
26712854Sgabeblack@google.com
26812854Sgabeblack@google.comsc_uint_subref &
26912854Sgabeblack@google.comsc_uint_subref::operator = (const sc_unsigned &a)
27012854Sgabeblack@google.com{
27112854Sgabeblack@google.com    sc_uint_base aa(length());
27212854Sgabeblack@google.com    return (*this = aa = a);
27312854Sgabeblack@google.com}
27412854Sgabeblack@google.com
27512854Sgabeblack@google.comsc_uint_subref &
27612854Sgabeblack@google.comsc_uint_subref::operator = (const sc_bv_base &a)
27712854Sgabeblack@google.com{
27812854Sgabeblack@google.com    sc_uint_base aa(length());
27912854Sgabeblack@google.com    return (*this = aa = a);
28012854Sgabeblack@google.com}
28112854Sgabeblack@google.com
28212854Sgabeblack@google.comsc_uint_subref &
28312854Sgabeblack@google.comsc_uint_subref::operator = (const sc_lv_base &a)
28412854Sgabeblack@google.com{
28512854Sgabeblack@google.com    sc_uint_base aa(length());
28612854Sgabeblack@google.com    return (*this = aa = a);
28712854Sgabeblack@google.com}
28812854Sgabeblack@google.com
28912854Sgabeblack@google.com// concatenation methods:
29012854Sgabeblack@google.com
29112854Sgabeblack@google.com// #### OPTIMIZE
29212854Sgabeblack@google.comvoid
29312854Sgabeblack@google.comsc_uint_subref::concat_set(int64 src, int low_i)
29412854Sgabeblack@google.com{
29512854Sgabeblack@google.com    sc_uint_base aa(length());
29612854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
29712854Sgabeblack@google.com}
29812854Sgabeblack@google.com
29912854Sgabeblack@google.comvoid
30012854Sgabeblack@google.comsc_uint_subref::concat_set(const sc_signed &src, int low_i)
30112854Sgabeblack@google.com{
30212854Sgabeblack@google.com    sc_uint_base aa(length());
30312854Sgabeblack@google.com    if (low_i < src.length())
30412854Sgabeblack@google.com        *this = aa = src >> low_i;
30512854Sgabeblack@google.com    else
30612854Sgabeblack@google.com        *this = aa = (src < 0) ? (int_type)-1 : 0;
30712854Sgabeblack@google.com}
30812854Sgabeblack@google.com
30912854Sgabeblack@google.comvoid
31012854Sgabeblack@google.comsc_uint_subref::concat_set(const sc_unsigned &src, int low_i)
31112854Sgabeblack@google.com{
31212854Sgabeblack@google.com    sc_uint_base aa(length());
31312854Sgabeblack@google.com    if (low_i < src.length())
31412854Sgabeblack@google.com        *this = aa = src >> low_i;
31512854Sgabeblack@google.com    else
31612854Sgabeblack@google.com        *this = aa = 0;
31712854Sgabeblack@google.com}
31812854Sgabeblack@google.com
31912854Sgabeblack@google.comvoid
32012854Sgabeblack@google.comsc_uint_subref::concat_set(uint64 src, int low_i)
32112854Sgabeblack@google.com{
32212854Sgabeblack@google.com    sc_uint_base aa(length());
32312854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
32412854Sgabeblack@google.com}
32512854Sgabeblack@google.com
32612854Sgabeblack@google.com// other methods
32712854Sgabeblack@google.comvoid
32812854Sgabeblack@google.comsc_uint_subref::scan(::std::istream &is)
32912854Sgabeblack@google.com{
33012854Sgabeblack@google.com    std::string s;
33112854Sgabeblack@google.com    is >> s;
33212854Sgabeblack@google.com    *this = s.c_str();
33312854Sgabeblack@google.com}
33412854Sgabeblack@google.com
33512854Sgabeblack@google.com
33612854Sgabeblack@google.com// ----------------------------------------------------------------------------
33712854Sgabeblack@google.com//  CLASS : sc_uint_base
33812854Sgabeblack@google.com//
33912854Sgabeblack@google.com//  Base class for sc_uint.
34012854Sgabeblack@google.com// ----------------------------------------------------------------------------
34112854Sgabeblack@google.com
34212854Sgabeblack@google.com// support methods
34312854Sgabeblack@google.com
34412854Sgabeblack@google.comvoid
34512854Sgabeblack@google.comsc_uint_base::invalid_length() const
34612854Sgabeblack@google.com{
34712854Sgabeblack@google.com    std::stringstream msg;
34812854Sgabeblack@google.com    msg << "sc_uint[_base] initialization: length = " << m_len <<
34912854Sgabeblack@google.com           " violates 1 <= length <= " << SC_INTWIDTH;
35013322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
35112854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here}
35212854Sgabeblack@google.com}
35312854Sgabeblack@google.com
35412854Sgabeblack@google.comvoid
35512854Sgabeblack@google.comsc_uint_base::invalid_index(int i) const
35612854Sgabeblack@google.com{
35712854Sgabeblack@google.com    std::stringstream msg;
35812854Sgabeblack@google.com    msg << "sc_uint[_base] bit selection: index = " << i <<
35912854Sgabeblack@google.com           " violates 0 <= index <= " << (m_len - 1);
36013322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
36112854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
36212854Sgabeblack@google.com}
36312854Sgabeblack@google.com
36412854Sgabeblack@google.comvoid
36512854Sgabeblack@google.comsc_uint_base::invalid_range(int l, int r) const
36612854Sgabeblack@google.com{
36712854Sgabeblack@google.com    std::stringstream msg;
36812854Sgabeblack@google.com    msg << "sc_uint[_base] part selection: " <<
36912854Sgabeblack@google.com           "left = " << l << ", right = " << r << " violates " <<
37012854Sgabeblack@google.com           (m_len - 1) << " >= left >= right >= 0";
37113322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
37212854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
37312854Sgabeblack@google.com}
37412854Sgabeblack@google.com
37512854Sgabeblack@google.com
37612854Sgabeblack@google.comvoid
37712854Sgabeblack@google.comsc_uint_base::check_value() const
37812854Sgabeblack@google.com{
37912854Sgabeblack@google.com    uint_type limit = (~UINT_ZERO >> m_ulen);
38012854Sgabeblack@google.com    if (m_val > limit) {
38112854Sgabeblack@google.com        std::stringstream msg;
38212854Sgabeblack@google.com        msg << "sc_uint[_base]: value does not fit into a length of " << m_len;
38313322Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
38412854Sgabeblack@google.com    }
38512854Sgabeblack@google.com}
38612854Sgabeblack@google.com
38712854Sgabeblack@google.com
38812854Sgabeblack@google.com// constructors
38912854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_bv_base &v) :
39012854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
39112854Sgabeblack@google.com{
39212854Sgabeblack@google.com    check_length();
39312854Sgabeblack@google.com    *this = v;
39412854Sgabeblack@google.com}
39512854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_lv_base &v) :
39612854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
39712854Sgabeblack@google.com{
39812854Sgabeblack@google.com    check_length();
39912854Sgabeblack@google.com    *this = v;
40012854Sgabeblack@google.com}
40112854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_int_subref_r &v) :
40212854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
40312854Sgabeblack@google.com{
40412854Sgabeblack@google.com    check_length();
40512854Sgabeblack@google.com    *this = v.to_uint64();
40612854Sgabeblack@google.com}
40712854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_signed_subref_r &v) :
40812854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
40912854Sgabeblack@google.com{
41012854Sgabeblack@google.com    check_length();
41112854Sgabeblack@google.com    *this = v.to_uint64();
41212854Sgabeblack@google.com}
41312854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_unsigned_subref_r &v) :
41412854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
41512854Sgabeblack@google.com{
41612854Sgabeblack@google.com    check_length();
41712854Sgabeblack@google.com    *this = v.to_uint64();
41812854Sgabeblack@google.com}
41912854Sgabeblack@google.com
42012854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_signed &a) :
42112854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
42212854Sgabeblack@google.com{
42312854Sgabeblack@google.com    check_length();
42412854Sgabeblack@google.com    *this = a.to_uint64();
42512854Sgabeblack@google.com}
42612854Sgabeblack@google.com
42712854Sgabeblack@google.comsc_uint_base::sc_uint_base(const sc_unsigned &a) :
42812854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
42912854Sgabeblack@google.com{
43012854Sgabeblack@google.com    check_length();
43112854Sgabeblack@google.com    *this = a.to_uint64();
43212854Sgabeblack@google.com}
43312854Sgabeblack@google.com
43412854Sgabeblack@google.com// assignment operators
43512854Sgabeblack@google.com
43612854Sgabeblack@google.comsc_uint_base &
43712854Sgabeblack@google.comsc_uint_base::operator = (const sc_signed &a)
43812854Sgabeblack@google.com{
43912854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
44012854Sgabeblack@google.com    int i = 0;
44112854Sgabeblack@google.com    for (; i < minlen; ++i) {
44212854Sgabeblack@google.com        set(i, a.test(i));
44312854Sgabeblack@google.com    }
44412854Sgabeblack@google.com    bool sgn = a.sign();
44512854Sgabeblack@google.com    for (; i < m_len; ++i) {
44612854Sgabeblack@google.com        // sign extension
44712854Sgabeblack@google.com        set(i, sgn);
44812854Sgabeblack@google.com    }
44912854Sgabeblack@google.com    extend_sign();
45012854Sgabeblack@google.com    return *this;
45112854Sgabeblack@google.com}
45212854Sgabeblack@google.com
45312854Sgabeblack@google.comsc_uint_base &
45412854Sgabeblack@google.comsc_uint_base::operator = (const sc_unsigned &a)
45512854Sgabeblack@google.com{
45612854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
45712854Sgabeblack@google.com    int i = 0;
45812854Sgabeblack@google.com    for (; i < minlen; ++i) {
45912854Sgabeblack@google.com        set(i, a.test(i));
46012854Sgabeblack@google.com    }
46112854Sgabeblack@google.com    for (; i < m_len; ++i) {
46212854Sgabeblack@google.com        // zero extension
46312854Sgabeblack@google.com        set(i, 0);
46412854Sgabeblack@google.com    }
46512854Sgabeblack@google.com    extend_sign();
46612854Sgabeblack@google.com    return *this;
46712854Sgabeblack@google.com}
46812854Sgabeblack@google.com
46912854Sgabeblack@google.com
47012854Sgabeblack@google.comsc_uint_base &
47112854Sgabeblack@google.comsc_uint_base::operator = (const sc_bv_base &a)
47212854Sgabeblack@google.com{
47312854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
47412854Sgabeblack@google.com    int i = 0;
47512854Sgabeblack@google.com    for (; i < minlen; ++i) {
47612854Sgabeblack@google.com        set(i, a.get_bit(i));
47712854Sgabeblack@google.com    }
47812854Sgabeblack@google.com    for (; i < m_len; ++i) {
47912854Sgabeblack@google.com        // zero extension
48012854Sgabeblack@google.com        set(i, 0);
48112854Sgabeblack@google.com    }
48212854Sgabeblack@google.com    extend_sign();
48312854Sgabeblack@google.com    return *this;
48412854Sgabeblack@google.com}
48512854Sgabeblack@google.com
48612854Sgabeblack@google.comsc_uint_base &
48712854Sgabeblack@google.comsc_uint_base::operator = (const sc_lv_base &a)
48812854Sgabeblack@google.com{
48912854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
49012854Sgabeblack@google.com    int i = 0;
49112854Sgabeblack@google.com    for (; i < minlen; ++i) {
49212854Sgabeblack@google.com        set(i, sc_logic(a.get_bit(i)).to_bool());
49312854Sgabeblack@google.com    }
49412854Sgabeblack@google.com    for (; i < m_len; ++i) {
49512854Sgabeblack@google.com        // zero extension
49612854Sgabeblack@google.com        set(i, 0);
49712854Sgabeblack@google.com    }
49812854Sgabeblack@google.com    extend_sign();
49912854Sgabeblack@google.com    return *this;
50012854Sgabeblack@google.com}
50112854Sgabeblack@google.com
50212854Sgabeblack@google.comsc_uint_base &
50312854Sgabeblack@google.comsc_uint_base::operator = (const char *a)
50412854Sgabeblack@google.com{
50512854Sgabeblack@google.com    if (a == 0) {
50613325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
50712854Sgabeblack@google.com                        "character string is zero");
50812854Sgabeblack@google.com    } else if (*a == 0) {
50913325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
51012854Sgabeblack@google.com                        "character string is empty");
51112854Sgabeblack@google.com    } else try {
51212854Sgabeblack@google.com        int len = m_len;
51312854Sgabeblack@google.com        sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
51412854Sgabeblack@google.com        return this->operator = (aa);
51512854Sgabeblack@google.com    } catch(const sc_core::sc_report &) {
51612854Sgabeblack@google.com        std::stringstream msg;
51712854Sgabeblack@google.com        msg << "character string '" << a << "' is not valid";
51813325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg.str().c_str());
51912854Sgabeblack@google.com    }
52012854Sgabeblack@google.com    return *this;
52112854Sgabeblack@google.com}
52212854Sgabeblack@google.com
52312854Sgabeblack@google.com
52412854Sgabeblack@google.com// explicit conversion to character string
52512854Sgabeblack@google.comconst std::string
52612854Sgabeblack@google.comsc_uint_base::to_string(sc_numrep numrep) const
52712854Sgabeblack@google.com{
52812854Sgabeblack@google.com    int len = m_len;
52912854Sgabeblack@google.com    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
53012854Sgabeblack@google.com    return aa.to_string(numrep);
53112854Sgabeblack@google.com}
53212854Sgabeblack@google.com
53312854Sgabeblack@google.comconst std::string
53412854Sgabeblack@google.comsc_uint_base::to_string(sc_numrep numrep, bool w_prefix) const
53512854Sgabeblack@google.com{
53612854Sgabeblack@google.com    int len = m_len;
53712854Sgabeblack@google.com    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
53812854Sgabeblack@google.com    return aa.to_string(numrep, w_prefix);
53912854Sgabeblack@google.com}
54012854Sgabeblack@google.com
54112854Sgabeblack@google.com
54212854Sgabeblack@google.com// reduce methods
54312854Sgabeblack@google.combool
54412854Sgabeblack@google.comsc_uint_base::and_reduce() const
54512854Sgabeblack@google.com{
54612854Sgabeblack@google.com    return (m_val == (~UINT_ZERO >> m_ulen));
54712854Sgabeblack@google.com}
54812854Sgabeblack@google.com
54912854Sgabeblack@google.combool
55012854Sgabeblack@google.comsc_uint_base::or_reduce() const
55112854Sgabeblack@google.com{
55212854Sgabeblack@google.com    return (m_val != uint_type(0));
55312854Sgabeblack@google.com}
55412854Sgabeblack@google.com
55512854Sgabeblack@google.combool
55612854Sgabeblack@google.comsc_uint_base::xor_reduce() const
55712854Sgabeblack@google.com{
55812854Sgabeblack@google.com    uint_type mask = ~UINT_ZERO;
55912854Sgabeblack@google.com    uint_type val = m_val;
56012854Sgabeblack@google.com    int n = SC_INTWIDTH;
56112854Sgabeblack@google.com    do {
56212854Sgabeblack@google.com        n >>= 1;
56312854Sgabeblack@google.com        mask >>= n;
56412854Sgabeblack@google.com        val = ((val & (mask << n)) >> n) ^ (val & mask);
56512854Sgabeblack@google.com    } while (n != 1);
56612854Sgabeblack@google.com    return (val != uint_type(0));
56712854Sgabeblack@google.com}
56812854Sgabeblack@google.com
56912854Sgabeblack@google.com
57012854Sgabeblack@google.combool
57112854Sgabeblack@google.comsc_uint_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
57212854Sgabeblack@google.com{
57312854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
57412854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
57512854Sgabeblack@google.com    int left_shift; // Left shift for val.
57612854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
57712854Sgabeblack@google.com
57812854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
57912854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
58012854Sgabeblack@google.com    end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
58112854Sgabeblack@google.com
58212854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
58312854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
58412854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
58512854Sgabeblack@google.com
58612854Sgabeblack@google.com    dst_i++;
58712854Sgabeblack@google.com    for (; dst_i <= end_i; dst_i++)
58812854Sgabeblack@google.com        dst_p[dst_i] = 0;
58912854Sgabeblack@google.com    return false;
59012854Sgabeblack@google.com}
59112854Sgabeblack@google.com
59212854Sgabeblack@google.com//-----------------------------------------------------------------------------
59312854Sgabeblack@google.com//"sc_uint_base::concat_get_data"
59412854Sgabeblack@google.com//
59512854Sgabeblack@google.com// This method transfers the value of this object instance to the supplied
59612854Sgabeblack@google.com// array of sc_unsigned digits starting with the bit specified by low_i within
59712854Sgabeblack@google.com// the array of digits.
59812854Sgabeblack@google.com//
59912854Sgabeblack@google.com// Notes:
60012854Sgabeblack@google.com//   (1) we don't worry about masking the high order data we transfer since
60112854Sgabeblack@google.com//       concat_get_data() is called from low order bit to high order bit. So
60212854Sgabeblack@google.com//       the bits above where we place ours will be filled in by someone else.
60312854Sgabeblack@google.com//
60412854Sgabeblack@google.com//   dst_p -> array of sc_unsigned digits to be filled in.
60512854Sgabeblack@google.com//   low_i =  first bit within dst_p to be set.
60612854Sgabeblack@google.com//-----------------------------------------------------------------------------
60712854Sgabeblack@google.combool
60812854Sgabeblack@google.comsc_uint_base::concat_get_data(sc_digit *dst_p, int low_i) const
60912854Sgabeblack@google.com{
61012854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
61112854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
61212854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
61312854Sgabeblack@google.com    int left_shift; // Left shift for val.
61412854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
61512854Sgabeblack@google.com    bool result; // True if inserting non-zero value.
61612854Sgabeblack@google.com    uint_type val; // Value for this object.
61712854Sgabeblack@google.com
61812854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
61912854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
62012854Sgabeblack@google.com    high_i = low_i + (m_len - 1);
62112854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
62212854Sgabeblack@google.com    val = m_val;
62312854Sgabeblack@google.com    result = val != 0;
62412854Sgabeblack@google.com
62512854Sgabeblack@google.com    // MASK OFF DATA TO BE TRANSFERRED BASE ON WIDTH:
62612854Sgabeblack@google.com    if (m_len < 64) {
62712854Sgabeblack@google.com        mask = ~(~UINT_ZERO << m_len);
62812854Sgabeblack@google.com        val &=  mask;
62912854Sgabeblack@google.com    }
63012854Sgabeblack@google.com
63112854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
63212854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
63312854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
63412854Sgabeblack@google.com        ((val << left_shift) & DIGIT_MASK));
63512854Sgabeblack@google.com
63612854Sgabeblack@google.com    switch (end_i - dst_i) {
63712854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
63812854Sgabeblack@google.com      case 1:
63912854Sgabeblack@google.com        dst_i++;
64012854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
64112854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
64212854Sgabeblack@google.com        break;
64312854Sgabeblack@google.com
64412854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
64512854Sgabeblack@google.com      case 2:
64612854Sgabeblack@google.com        dst_i++;
64712854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
64812854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
64912854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
65012854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
65112854Sgabeblack@google.com        break;
65212854Sgabeblack@google.com
65312854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
65412854Sgabeblack@google.com      case 3:
65512854Sgabeblack@google.com        dst_i++;
65612854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
65712854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
65812854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
65912854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
66012854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
66112854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
66212854Sgabeblack@google.com        break;
66312854Sgabeblack@google.com    }
66412854Sgabeblack@google.com    return result;
66512854Sgabeblack@google.com}
66612854Sgabeblack@google.com
66712854Sgabeblack@google.com// #### OPTIMIZE
66812854Sgabeblack@google.comvoid
66912854Sgabeblack@google.comsc_uint_base::concat_set(int64 src, int low_i)
67012854Sgabeblack@google.com{
67112854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : src >> 63;
67212854Sgabeblack@google.com}
67312854Sgabeblack@google.com
67412854Sgabeblack@google.comvoid
67512854Sgabeblack@google.comsc_uint_base::concat_set(const sc_signed &src, int low_i)
67612854Sgabeblack@google.com{
67712854Sgabeblack@google.com    if (low_i < src.length())
67812854Sgabeblack@google.com        *this = src >> low_i;
67912854Sgabeblack@google.com    else
68012854Sgabeblack@google.com        *this = (src < 0) ? (int_type)-1 : 0;
68112854Sgabeblack@google.com}
68212854Sgabeblack@google.com
68312854Sgabeblack@google.comvoid
68412854Sgabeblack@google.comsc_uint_base::concat_set(const sc_unsigned &src, int low_i)
68512854Sgabeblack@google.com{
68612854Sgabeblack@google.com    if (low_i < src.length())
68712854Sgabeblack@google.com        *this = src >> low_i;
68812854Sgabeblack@google.com    else
68912854Sgabeblack@google.com        *this = 0;
69012854Sgabeblack@google.com}
69112854Sgabeblack@google.com
69212854Sgabeblack@google.comvoid
69312854Sgabeblack@google.comsc_uint_base::concat_set(uint64 src, int low_i)
69412854Sgabeblack@google.com{
69512854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : 0;
69612854Sgabeblack@google.com}
69712854Sgabeblack@google.com
69812854Sgabeblack@google.com
69912854Sgabeblack@google.com// other methods
70012854Sgabeblack@google.comvoid
70112854Sgabeblack@google.comsc_uint_base::scan(::std::istream &is)
70212854Sgabeblack@google.com{
70312854Sgabeblack@google.com    std::string s;
70412854Sgabeblack@google.com    is >> s;
70512854Sgabeblack@google.com    *this = s.c_str();
70612854Sgabeblack@google.com}
70712854Sgabeblack@google.com
70812854Sgabeblack@google.com} // namespace sc_dt
709