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_int_base.cpp -- contains interface definitions between sc_int and
2312854Sgabeblack@google.com                sc_signed, sc_unsigned, and definitions for sc_int_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_int_base.cpp,v $
4112854Sgabeblack@google.com// Revision 1.5  2011/02/18 20:19:14  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:56  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:31  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_fix.hh"
6812854Sgabeblack@google.com#include "systemc/ext/dt/fx/scfx_other_defs.hh"
6912854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_int_base.hh"
7012854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_signed.hh"
7112854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_uint_base.hh"
7212854Sgabeblack@google.com#include "systemc/ext/dt/int/sc_unsigned.hh"
7312854Sgabeblack@google.com#include "systemc/ext/dt/misc/sc_concatref.hh"
7413322Sgabeblack@google.com#include "systemc/ext/utils/messages.hh"
7512854Sgabeblack@google.com
7612854Sgabeblack@google.com// explicit template instantiations
7712854Sgabeblack@google.comnamespace sc_core
7812854Sgabeblack@google.com{
7912854Sgabeblack@google.com
8012854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_int_bitref>;
8112854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_int_subref>;
8212854Sgabeblack@google.com
8312854Sgabeblack@google.com} // namespace sc_core
8412854Sgabeblack@google.com
8512854Sgabeblack@google.comnamespace sc_dt
8612854Sgabeblack@google.com{
8712854Sgabeblack@google.com
8812854Sgabeblack@google.com// to avoid code bloat in sc_int_concref<T1,T2>
8912854Sgabeblack@google.com
9012854Sgabeblack@google.comvoid
9112854Sgabeblack@google.comsc_int_concref_invalid_length(int length)
9212854Sgabeblack@google.com{
9312854Sgabeblack@google.com    std::stringstream msg;
9412854Sgabeblack@google.com    msg << "sc_int_concref<T1,T2> initialization: length = " << length <<
9512854Sgabeblack@google.com           "violates 1 <= length <= " << SC_INTWIDTH;
9613322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
9712854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
9812854Sgabeblack@google.com}
9912854Sgabeblack@google.com
10012854Sgabeblack@google.com
10112854Sgabeblack@google.com// ----------------------------------------------------------------------------
10212854Sgabeblack@google.com//  CLASS : sc_int_bitref
10312854Sgabeblack@google.com//
10412854Sgabeblack@google.com//  Proxy class for sc_int bit selection (r-value and l-value).
10512854Sgabeblack@google.com// ----------------------------------------------------------------------------
10612854Sgabeblack@google.com
10712854Sgabeblack@google.comsc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9);
10812854Sgabeblack@google.com
10912854Sgabeblack@google.com// concatenation methods:
11012854Sgabeblack@google.com
11112854Sgabeblack@google.com// #### OPTIMIZE
11212854Sgabeblack@google.comvoid sc_int_bitref::concat_set(int64 src, int low_i)
11312854Sgabeblack@google.com{
11412854Sgabeblack@google.com    sc_int_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 sc_int_bitref::concat_set(const sc_signed &src, int low_i)
11912854Sgabeblack@google.com{
12012854Sgabeblack@google.com    sc_int_base aa(1);
12112854Sgabeblack@google.com    if (low_i < src.length())
12212854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
12312854Sgabeblack@google.com    else
12412854Sgabeblack@google.com        *this = aa = (src < 0) ? (int_type)-1 : 0;
12512854Sgabeblack@google.com}
12612854Sgabeblack@google.com
12712854Sgabeblack@google.comvoid sc_int_bitref::concat_set(const sc_unsigned &src, int low_i)
12812854Sgabeblack@google.com{
12912854Sgabeblack@google.com    sc_int_base aa(1);
13012854Sgabeblack@google.com    if (low_i < src.length())
13112854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
13212854Sgabeblack@google.com    else
13312854Sgabeblack@google.com        *this = aa = 0;
13412854Sgabeblack@google.com}
13512854Sgabeblack@google.com
13612854Sgabeblack@google.comvoid sc_int_bitref::concat_set(uint64 src, int low_i)
13712854Sgabeblack@google.com{
13812854Sgabeblack@google.com    sc_int_base aa(1);
13912854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
14012854Sgabeblack@google.com}
14112854Sgabeblack@google.com
14212854Sgabeblack@google.com
14312854Sgabeblack@google.com// other methods
14412854Sgabeblack@google.comvoid
14512854Sgabeblack@google.comsc_int_bitref::scan(::std::istream &is)
14612854Sgabeblack@google.com{
14712854Sgabeblack@google.com    bool b;
14812854Sgabeblack@google.com    is >> b;
14912854Sgabeblack@google.com    *this = b;
15012854Sgabeblack@google.com}
15112854Sgabeblack@google.com
15212854Sgabeblack@google.com
15312854Sgabeblack@google.com// ----------------------------------------------------------------------------
15412854Sgabeblack@google.com//  CLASS : sc_int_subref_r
15512854Sgabeblack@google.com//
15612854Sgabeblack@google.com//  Proxy class for sc_int part selection (l-value).
15712854Sgabeblack@google.com// ----------------------------------------------------------------------------
15812854Sgabeblack@google.com
15912854Sgabeblack@google.combool
16012854Sgabeblack@google.comsc_int_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
16112854Sgabeblack@google.com{
16212854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
16312854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
16412854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
16512854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
16612854Sgabeblack@google.com
16712854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
16812854Sgabeblack@google.com    high_i = low_i + (m_left - m_right);
16912854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
17012854Sgabeblack@google.com    mask = ~mask_int[m_left][m_right];
17112854Sgabeblack@google.com
17212854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
17312854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
17412854Sgabeblack@google.com    switch (end_i - dst_i) {
17512854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
17612854Sgabeblack@google.com      case 1:
17712854Sgabeblack@google.com        dst_i++;
17812854Sgabeblack@google.com        dst_p[dst_i] = 0;
17912854Sgabeblack@google.com        break;
18012854Sgabeblack@google.com
18112854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
18212854Sgabeblack@google.com      case 2:
18312854Sgabeblack@google.com        dst_i++;
18412854Sgabeblack@google.com        dst_p[dst_i++] = 0;
18512854Sgabeblack@google.com        dst_p[dst_i] = 0;
18612854Sgabeblack@google.com        break;
18712854Sgabeblack@google.com
18812854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
18912854Sgabeblack@google.com      case 3:
19012854Sgabeblack@google.com        dst_i++;
19112854Sgabeblack@google.com        dst_p[dst_i++] = 0;
19212854Sgabeblack@google.com        dst_p[dst_i++] = 0;
19312854Sgabeblack@google.com        dst_p[dst_i] = 0;
19412854Sgabeblack@google.com        break;
19512854Sgabeblack@google.com    }
19612854Sgabeblack@google.com    return false;
19712854Sgabeblack@google.com}
19812854Sgabeblack@google.com
19912854Sgabeblack@google.combool
20012854Sgabeblack@google.comsc_int_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
20112854Sgabeblack@google.com{
20212854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
20312854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
20412854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
20512854Sgabeblack@google.com    int left_shift; // Left shift for val.
20612854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
20712854Sgabeblack@google.com    bool non_zero; // True if value inserted is non-zero.
20812854Sgabeblack@google.com    uint_type val; // Selection value extracted from m_obj_p.
20912854Sgabeblack@google.com
21012854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
21112854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
21212854Sgabeblack@google.com    high_i = low_i + (m_left-m_right);
21312854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
21412854Sgabeblack@google.com    mask = ~mask_int[m_left][m_right];
21512854Sgabeblack@google.com    val = (m_obj_p->m_val & mask) >> m_right;
21612854Sgabeblack@google.com    non_zero = val != 0;
21712854Sgabeblack@google.com
21812854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
21912854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
22012854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) |
22112854Sgabeblack@google.com                ((val << left_shift) & DIGIT_MASK));
22212854Sgabeblack@google.com
22312854Sgabeblack@google.com    switch (end_i - dst_i) {
22412854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
22512854Sgabeblack@google.com      case 1:
22612854Sgabeblack@google.com        dst_i++;
22712854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
22812854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK);
22912854Sgabeblack@google.com        break;
23012854Sgabeblack@google.com
23112854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
23212854Sgabeblack@google.com      case 2:
23312854Sgabeblack@google.com        dst_i++;
23412854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
23512854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23612854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
23712854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
23812854Sgabeblack@google.com        break;
23912854Sgabeblack@google.com
24012854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
24112854Sgabeblack@google.com      case 3:
24212854Sgabeblack@google.com        dst_i++;
24312854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
24412854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
24512854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
24612854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
24712854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
24812854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
24912854Sgabeblack@google.com        break;
25012854Sgabeblack@google.com    }
25112854Sgabeblack@google.com    return non_zero;
25212854Sgabeblack@google.com}
25312854Sgabeblack@google.com
25412854Sgabeblack@google.com// ----------------------------------------------------------------------------
25512854Sgabeblack@google.com//  CLASS : sc_int_subref
25612854Sgabeblack@google.com//
25712854Sgabeblack@google.com//  Proxy class for sc_int part selection (r-value and l-value).
25812854Sgabeblack@google.com// ----------------------------------------------------------------------------
25912854Sgabeblack@google.com
26012854Sgabeblack@google.comsc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9);
26112854Sgabeblack@google.com
26212854Sgabeblack@google.com// assignment operators
26312854Sgabeblack@google.com
26412854Sgabeblack@google.comsc_int_subref &
26512854Sgabeblack@google.comsc_int_subref::operator = (int_type v)
26612854Sgabeblack@google.com{
26712854Sgabeblack@google.com    int_type val = m_obj_p->m_val;
26812854Sgabeblack@google.com    uint_type mask = mask_int[m_left][m_right];
26912854Sgabeblack@google.com    val &= mask;
27012854Sgabeblack@google.com    val |= (v << m_right) & ~mask;
27112854Sgabeblack@google.com    m_obj_p->m_val = val;
27212854Sgabeblack@google.com    m_obj_p->extend_sign();
27312854Sgabeblack@google.com    return *this;
27412854Sgabeblack@google.com}
27512854Sgabeblack@google.com
27612854Sgabeblack@google.comsc_int_subref &
27712854Sgabeblack@google.comsc_int_subref::operator = (const sc_signed &a)
27812854Sgabeblack@google.com{
27912854Sgabeblack@google.com    sc_int_base aa(length());
28012854Sgabeblack@google.com    return (*this = aa = a);
28112854Sgabeblack@google.com}
28212854Sgabeblack@google.com
28312854Sgabeblack@google.comsc_int_subref &
28412854Sgabeblack@google.comsc_int_subref::operator = (const sc_unsigned &a)
28512854Sgabeblack@google.com{
28612854Sgabeblack@google.com    sc_int_base aa(length());
28712854Sgabeblack@google.com    return (*this = aa = a);
28812854Sgabeblack@google.com}
28912854Sgabeblack@google.com
29012854Sgabeblack@google.comsc_int_subref &
29112854Sgabeblack@google.comsc_int_subref::operator = (const sc_bv_base &a)
29212854Sgabeblack@google.com{
29312854Sgabeblack@google.com    sc_int_base aa(length());
29412854Sgabeblack@google.com    return (*this = aa = a);
29512854Sgabeblack@google.com}
29612854Sgabeblack@google.com
29712854Sgabeblack@google.comsc_int_subref &
29812854Sgabeblack@google.comsc_int_subref::operator = (const sc_lv_base &a)
29912854Sgabeblack@google.com{
30012854Sgabeblack@google.com    sc_int_base aa(length());
30112854Sgabeblack@google.com    return (*this = aa = a);
30212854Sgabeblack@google.com}
30312854Sgabeblack@google.com
30412854Sgabeblack@google.com
30512854Sgabeblack@google.com// concatenation methods:
30612854Sgabeblack@google.com// #### OPTIMIZE
30712854Sgabeblack@google.comvoid
30812854Sgabeblack@google.comsc_int_subref::concat_set(int64 src, int low_i)
30912854Sgabeblack@google.com{
31012854Sgabeblack@google.com    sc_int_base aa(length());
31112854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
31212854Sgabeblack@google.com}
31312854Sgabeblack@google.com
31412854Sgabeblack@google.comvoid
31512854Sgabeblack@google.comsc_int_subref::concat_set(const sc_signed &src, int low_i)
31612854Sgabeblack@google.com{
31712854Sgabeblack@google.com    sc_int_base aa(length());
31812854Sgabeblack@google.com    if (low_i < src.length())
31912854Sgabeblack@google.com        *this = aa = src >> low_i;
32012854Sgabeblack@google.com    else
32112854Sgabeblack@google.com        *this = (src < 0) ? (int_type)-1 : 0;
32212854Sgabeblack@google.com}
32312854Sgabeblack@google.com
32412854Sgabeblack@google.comvoid
32512854Sgabeblack@google.comsc_int_subref::concat_set(const sc_unsigned &src, int low_i)
32612854Sgabeblack@google.com{
32712854Sgabeblack@google.com    sc_int_base aa(length());
32812854Sgabeblack@google.com    if (low_i < src.length())
32912854Sgabeblack@google.com        *this = aa = src >> low_i;
33012854Sgabeblack@google.com    else
33112854Sgabeblack@google.com        *this = 0;
33212854Sgabeblack@google.com}
33312854Sgabeblack@google.com
33412854Sgabeblack@google.comvoid
33512854Sgabeblack@google.comsc_int_subref::concat_set(uint64 src, int low_i)
33612854Sgabeblack@google.com{
33712854Sgabeblack@google.com    sc_int_base aa (length());
33812854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
33912854Sgabeblack@google.com}
34012854Sgabeblack@google.com
34112854Sgabeblack@google.com
34212854Sgabeblack@google.com// other methods
34312854Sgabeblack@google.comvoid
34412854Sgabeblack@google.comsc_int_subref::scan(::std::istream &is)
34512854Sgabeblack@google.com{
34612854Sgabeblack@google.com    std::string s;
34712854Sgabeblack@google.com    is >> s;
34812854Sgabeblack@google.com    *this = s.c_str();
34912854Sgabeblack@google.com}
35012854Sgabeblack@google.com
35112854Sgabeblack@google.com
35212854Sgabeblack@google.com// ----------------------------------------------------------------------------
35312854Sgabeblack@google.com//  CLASS : sc_int_base
35412854Sgabeblack@google.com//
35512854Sgabeblack@google.com//  Base class for sc_int.
35612854Sgabeblack@google.com// ----------------------------------------------------------------------------
35712854Sgabeblack@google.com
35812854Sgabeblack@google.com// support methods
35912854Sgabeblack@google.comvoid
36012854Sgabeblack@google.comsc_int_base::invalid_length() const
36112854Sgabeblack@google.com{
36212854Sgabeblack@google.com    std::stringstream msg;
36312854Sgabeblack@google.com    msg << "sc_int[_base] initialization: length = " << m_len <<
36412854Sgabeblack@google.com           " violates 1 <= length <= " << SC_INTWIDTH;
36513322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
36612854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
36712854Sgabeblack@google.com}
36812854Sgabeblack@google.com
36912854Sgabeblack@google.comvoid
37012854Sgabeblack@google.comsc_int_base::invalid_index(int i) const
37112854Sgabeblack@google.com{
37212854Sgabeblack@google.com    std::stringstream msg;
37312854Sgabeblack@google.com    msg << "sc_int[_base] bit selection: index = " << i <<
37412854Sgabeblack@google.com           " violates 0 <= index <= " << (m_len - 1);
37513322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
37612854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
37712854Sgabeblack@google.com}
37812854Sgabeblack@google.com
37912854Sgabeblack@google.comvoid
38012854Sgabeblack@google.comsc_int_base::invalid_range(int l, int r) const
38112854Sgabeblack@google.com{
38212854Sgabeblack@google.com    std::stringstream msg;
38312854Sgabeblack@google.com    msg << "sc_int[_base] part selection: " <<
38412854Sgabeblack@google.com           "left = " << l << ", right = " << r << " violates " <<
38512854Sgabeblack@google.com           (m_len-1) << " >= left >= right >= 0";
38613322Sgabeblack@google.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
38712854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
38812854Sgabeblack@google.com}
38912854Sgabeblack@google.com
39012854Sgabeblack@google.comvoid
39112854Sgabeblack@google.comsc_int_base::check_value() const
39212854Sgabeblack@google.com{
39312854Sgabeblack@google.com    int_type limit = (int_type)1 << (m_len - 1);
39412854Sgabeblack@google.com    if (m_val < -limit || m_val >= limit) {
39512854Sgabeblack@google.com        std::stringstream msg;
39612854Sgabeblack@google.com        msg << "sc_int[_base]: value does not fit into a length of " << m_len;
39713322Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
39812854Sgabeblack@google.com    }
39912854Sgabeblack@google.com}
40012854Sgabeblack@google.com
40112854Sgabeblack@google.com
40212854Sgabeblack@google.com// constructors
40312854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_bv_base &v) :
40412854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
40512854Sgabeblack@google.com{
40612854Sgabeblack@google.com    check_length();
40712854Sgabeblack@google.com    *this = v;
40812854Sgabeblack@google.com}
40912854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_lv_base &v) :
41012854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
41112854Sgabeblack@google.com{
41212854Sgabeblack@google.com    check_length();
41312854Sgabeblack@google.com    *this = v;
41412854Sgabeblack@google.com}
41512854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_uint_subref_r &v) :
41612854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
41712854Sgabeblack@google.com{
41812854Sgabeblack@google.com    check_length();
41912854Sgabeblack@google.com    *this = v.to_uint64();
42012854Sgabeblack@google.com}
42112854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_signed_subref_r &v) :
42212854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
42312854Sgabeblack@google.com{
42412854Sgabeblack@google.com    check_length();
42512854Sgabeblack@google.com    *this = v.to_uint64();
42612854Sgabeblack@google.com}
42712854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_unsigned_subref_r &v) :
42812854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
42912854Sgabeblack@google.com{
43012854Sgabeblack@google.com    check_length();
43112854Sgabeblack@google.com    *this = v.to_uint64();
43212854Sgabeblack@google.com}
43312854Sgabeblack@google.com
43412854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_signed &a) :
43512854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
43612854Sgabeblack@google.com{
43712854Sgabeblack@google.com    check_length();
43812854Sgabeblack@google.com    *this = a.to_int64();
43912854Sgabeblack@google.com}
44012854Sgabeblack@google.com
44112854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_unsigned &a) :
44212854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
44312854Sgabeblack@google.com{
44412854Sgabeblack@google.com    check_length();
44512854Sgabeblack@google.com    *this = a.to_int64();
44612854Sgabeblack@google.com}
44712854Sgabeblack@google.com
44812854Sgabeblack@google.com
44912854Sgabeblack@google.com// assignment operators
45012854Sgabeblack@google.comsc_int_base &
45112854Sgabeblack@google.comsc_int_base::operator = (const sc_signed &a)
45212854Sgabeblack@google.com{
45312854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
45412854Sgabeblack@google.com    int i = 0;
45512854Sgabeblack@google.com    for (; i < minlen; ++i) {
45612854Sgabeblack@google.com        set(i, a.test(i));
45712854Sgabeblack@google.com    }
45812854Sgabeblack@google.com    bool sgn = a.sign();
45912854Sgabeblack@google.com    for (; i < m_len; ++i) {
46012854Sgabeblack@google.com        // sign extension
46112854Sgabeblack@google.com        set(i, sgn);
46212854Sgabeblack@google.com    }
46312854Sgabeblack@google.com    extend_sign();
46412854Sgabeblack@google.com    return *this;
46512854Sgabeblack@google.com}
46612854Sgabeblack@google.com
46712854Sgabeblack@google.comsc_int_base &
46812854Sgabeblack@google.comsc_int_base::operator = (const sc_unsigned &a)
46912854Sgabeblack@google.com{
47012854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
47112854Sgabeblack@google.com    int i = 0;
47212854Sgabeblack@google.com    for (; i < minlen; ++i) {
47312854Sgabeblack@google.com        set(i, a.test(i));
47412854Sgabeblack@google.com    }
47512854Sgabeblack@google.com    for (; i < m_len; ++i) {
47612854Sgabeblack@google.com        // zero extension
47712854Sgabeblack@google.com        set(i, 0);
47812854Sgabeblack@google.com    }
47912854Sgabeblack@google.com    extend_sign();
48012854Sgabeblack@google.com    return *this;
48112854Sgabeblack@google.com}
48212854Sgabeblack@google.com
48312854Sgabeblack@google.com
48412854Sgabeblack@google.comsc_int_base &
48512854Sgabeblack@google.comsc_int_base::operator = (const sc_bv_base &a)
48612854Sgabeblack@google.com{
48712854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
48812854Sgabeblack@google.com    int i = 0;
48912854Sgabeblack@google.com    for (; i < minlen; ++i) {
49012854Sgabeblack@google.com        set(i, a.get_bit(i));
49112854Sgabeblack@google.com    }
49212854Sgabeblack@google.com    for (; i < m_len; ++i) {
49312854Sgabeblack@google.com        // zero extension
49412854Sgabeblack@google.com        set(i, 0);
49512854Sgabeblack@google.com    }
49612854Sgabeblack@google.com    extend_sign();
49712854Sgabeblack@google.com    return *this;
49812854Sgabeblack@google.com}
49912854Sgabeblack@google.com
50012854Sgabeblack@google.comsc_int_base &
50112854Sgabeblack@google.comsc_int_base::operator = (const sc_lv_base &a)
50212854Sgabeblack@google.com{
50312854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
50412854Sgabeblack@google.com    int i = 0;
50512854Sgabeblack@google.com    for (; i < minlen; ++i) {
50612854Sgabeblack@google.com        set(i, sc_logic(a.get_bit(i)).to_bool());
50712854Sgabeblack@google.com    }
50812854Sgabeblack@google.com    for (; i < m_len; ++i) {
50912854Sgabeblack@google.com        // zero extension
51012854Sgabeblack@google.com        set(i, 0);
51112854Sgabeblack@google.com    }
51212854Sgabeblack@google.com    extend_sign();
51312854Sgabeblack@google.com    return *this;
51412854Sgabeblack@google.com}
51512854Sgabeblack@google.com
51612854Sgabeblack@google.comsc_int_base &
51712854Sgabeblack@google.comsc_int_base::operator = (const char *a)
51812854Sgabeblack@google.com{
51912854Sgabeblack@google.com    if (a == 0) {
52013325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
52112854Sgabeblack@google.com                        "character string is zero");
52212854Sgabeblack@google.com    } else if (*a == 0) {
52313325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
52412854Sgabeblack@google.com                        "character string is empty");
52512854Sgabeblack@google.com    } else try {
52612854Sgabeblack@google.com        int len = m_len;
52712854Sgabeblack@google.com        sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
52812854Sgabeblack@google.com        return this->operator = (aa);
52912854Sgabeblack@google.com    } catch(const sc_core::sc_report &) {
53012854Sgabeblack@google.com        std::stringstream msg;
53112854Sgabeblack@google.com        msg << "character string '" << a << "' is not valid";
53213325Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg.str().c_str());
53312854Sgabeblack@google.com    }
53412854Sgabeblack@google.com    return *this;
53512854Sgabeblack@google.com}
53612854Sgabeblack@google.com
53712854Sgabeblack@google.com// explicit conversion to character string
53812854Sgabeblack@google.comconst std::string
53912854Sgabeblack@google.comsc_int_base::to_string(sc_numrep numrep) const
54012854Sgabeblack@google.com{
54112854Sgabeblack@google.com    int len = m_len;
54212854Sgabeblack@google.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
54312854Sgabeblack@google.com    return aa.to_string(numrep);
54412854Sgabeblack@google.com}
54512854Sgabeblack@google.com
54612854Sgabeblack@google.comconst std::string
54712854Sgabeblack@google.comsc_int_base::to_string(sc_numrep numrep, bool w_prefix) const
54812854Sgabeblack@google.com{
54912854Sgabeblack@google.com    int len = m_len;
55012854Sgabeblack@google.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
55112854Sgabeblack@google.com    return aa.to_string(numrep, w_prefix);
55212854Sgabeblack@google.com}
55312854Sgabeblack@google.com
55412854Sgabeblack@google.com
55512854Sgabeblack@google.com// reduce methods
55612854Sgabeblack@google.combool sc_int_base::and_reduce() const { return (m_val == int_type(-1)); }
55712854Sgabeblack@google.combool sc_int_base::or_reduce() const { return (m_val != int_type(0)); }
55812854Sgabeblack@google.com
55912854Sgabeblack@google.combool
56012854Sgabeblack@google.comsc_int_base::xor_reduce() const
56112854Sgabeblack@google.com{
56212854Sgabeblack@google.com    uint_type mask = ~UINT_ZERO;
56312854Sgabeblack@google.com    uint_type val = m_val & (mask >> m_ulen);
56412854Sgabeblack@google.com    int n = SC_INTWIDTH;
56512854Sgabeblack@google.com    do {
56612854Sgabeblack@google.com        n >>= 1;
56712854Sgabeblack@google.com        mask >>= n;
56812854Sgabeblack@google.com        val = ((val & (mask << n)) >> n) ^ (val & mask);
56912854Sgabeblack@google.com    } while (n != 1);
57012854Sgabeblack@google.com    return (val != uint_type(0));
57112854Sgabeblack@google.com}
57212854Sgabeblack@google.com
57312854Sgabeblack@google.combool
57412854Sgabeblack@google.comsc_int_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
57512854Sgabeblack@google.com{
57612854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
57712854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
57812854Sgabeblack@google.com    int left_shift; // Left shift for val.
57912854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
58012854Sgabeblack@google.com
58112854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
58212854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
58312854Sgabeblack@google.com    end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
58412854Sgabeblack@google.com
58512854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
58612854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
58712854Sgabeblack@google.com        dst_i++;
58812854Sgabeblack@google.com        for (; dst_i <= end_i; dst_i++)
58912854Sgabeblack@google.com            dst_p[dst_i] = 0;
59012854Sgabeblack@google.com        return false;
59112854Sgabeblack@google.com}
59212854Sgabeblack@google.com
59312854Sgabeblack@google.com//-----------------------------------------------------------------------------
59412854Sgabeblack@google.com//"sc_int_base::concat_get_data"
59512854Sgabeblack@google.com//
59612854Sgabeblack@google.com// This method transfers the value of this object instance to the supplied
59712854Sgabeblack@google.com// array of sc_unsigned digits starting with the bit specified by low_i within
59812854Sgabeblack@google.com// the array of digits.
59912854Sgabeblack@google.com//
60012854Sgabeblack@google.com// Notes:
60112854Sgabeblack@google.com//   (1) we don't worry about masking the high order data we transfer since
60212854Sgabeblack@google.com//       concat_get_data() is called from low order bit to high order bit. So
60312854Sgabeblack@google.com//       the bits above where we place ours will be filled in by someone else.
60412854Sgabeblack@google.com//
60512854Sgabeblack@google.com//   dst_p -> array of sc_unsigned digits to be filled in.
60612854Sgabeblack@google.com//   low_i =  first bit within dst_p to be set.
60712854Sgabeblack@google.com//-----------------------------------------------------------------------------
60812854Sgabeblack@google.combool
60912854Sgabeblack@google.comsc_int_base::concat_get_data(sc_digit *dst_p, int low_i) const
61012854Sgabeblack@google.com{
61112854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
61212854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
61312854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
61412854Sgabeblack@google.com    int left_shift; // Left shift for val.
61512854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
61612854Sgabeblack@google.com    bool non_zero; // True if value inserted is non-zero.
61712854Sgabeblack@google.com    uint_type val; // Value for this object.
61812854Sgabeblack@google.com
61912854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
62012854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
62112854Sgabeblack@google.com    high_i = low_i + (m_len - 1);
62212854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
62312854Sgabeblack@google.com    val = m_val;
62412854Sgabeblack@google.com    non_zero = val != 0;
62512854Sgabeblack@google.com
62612854Sgabeblack@google.com    // MASK OFF DATA TO BE TRANSFERRED BASED ON WIDTH:
62712854Sgabeblack@google.com    if (m_len < 64) {
62812854Sgabeblack@google.com        mask = ~(~UINT_ZERO << m_len);
62912854Sgabeblack@google.com        val &=  mask;
63012854Sgabeblack@google.com    }
63112854Sgabeblack@google.com
63212854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
63312854Sgabeblack@google.com    mask = (~UINT_ZERO << left_shift);
63412854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & ~mask) |
63512854Sgabeblack@google.com            ((val <<left_shift) & DIGIT_MASK));
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 non_zero;
66512854Sgabeblack@google.com}
66612854Sgabeblack@google.com
66712854Sgabeblack@google.com// #### OPTIMIZE
66812854Sgabeblack@google.comvoid
66912854Sgabeblack@google.comsc_int_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_int_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_int_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_int_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// other methods
69912854Sgabeblack@google.comvoid
70012854Sgabeblack@google.comsc_int_base::scan(::std::istream &is)
70112854Sgabeblack@google.com{
70212854Sgabeblack@google.com    std::string s;
70312854Sgabeblack@google.com    is >> s;
70412854Sgabeblack@google.com    *this = s.c_str();
70512854Sgabeblack@google.com}
70612854Sgabeblack@google.com
70712854Sgabeblack@google.com} // namespace sc_dt;
708