sc_int_base.cc revision 12854
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"
7412854Sgabeblack@google.com
7512854Sgabeblack@google.com// explicit template instantiations
7612854Sgabeblack@google.comnamespace sc_core
7712854Sgabeblack@google.com{
7812854Sgabeblack@google.com
7912854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_int_bitref>;
8012854Sgabeblack@google.comtemplate class sc_vpool<sc_dt::sc_int_subref>;
8112854Sgabeblack@google.com
8212854Sgabeblack@google.com} // namespace sc_core
8312854Sgabeblack@google.com
8412854Sgabeblack@google.comnamespace sc_dt
8512854Sgabeblack@google.com{
8612854Sgabeblack@google.com
8712854Sgabeblack@google.com// to avoid code bloat in sc_int_concref<T1,T2>
8812854Sgabeblack@google.com
8912854Sgabeblack@google.comvoid
9012854Sgabeblack@google.comsc_int_concref_invalid_length(int length)
9112854Sgabeblack@google.com{
9212854Sgabeblack@google.com    std::stringstream msg;
9312854Sgabeblack@google.com    msg << "sc_int_concref<T1,T2> initialization: length = " << length <<
9412854Sgabeblack@google.com           "violates 1 <= length <= " << SC_INTWIDTH;
9512854Sgabeblack@google.com    SC_REPORT_ERROR("out of bounds", msg.str().c_str());
9612854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
9712854Sgabeblack@google.com}
9812854Sgabeblack@google.com
9912854Sgabeblack@google.com
10012854Sgabeblack@google.com// ----------------------------------------------------------------------------
10112854Sgabeblack@google.com//  CLASS : sc_int_bitref
10212854Sgabeblack@google.com//
10312854Sgabeblack@google.com//  Proxy class for sc_int bit selection (r-value and l-value).
10412854Sgabeblack@google.com// ----------------------------------------------------------------------------
10512854Sgabeblack@google.com
10612854Sgabeblack@google.comsc_core::sc_vpool<sc_int_bitref> sc_int_bitref::m_pool(9);
10712854Sgabeblack@google.com
10812854Sgabeblack@google.com// concatenation methods:
10912854Sgabeblack@google.com
11012854Sgabeblack@google.com// #### OPTIMIZE
11112854Sgabeblack@google.comvoid sc_int_bitref::concat_set(int64 src, int low_i)
11212854Sgabeblack@google.com{
11312854Sgabeblack@google.com    sc_int_base aa(1);
11412854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
11512854Sgabeblack@google.com}
11612854Sgabeblack@google.com
11712854Sgabeblack@google.comvoid sc_int_bitref::concat_set(const sc_signed &src, int low_i)
11812854Sgabeblack@google.com{
11912854Sgabeblack@google.com    sc_int_base aa(1);
12012854Sgabeblack@google.com    if (low_i < src.length())
12112854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
12212854Sgabeblack@google.com    else
12312854Sgabeblack@google.com        *this = aa = (src < 0) ? (int_type)-1 : 0;
12412854Sgabeblack@google.com}
12512854Sgabeblack@google.com
12612854Sgabeblack@google.comvoid sc_int_bitref::concat_set(const sc_unsigned &src, int low_i)
12712854Sgabeblack@google.com{
12812854Sgabeblack@google.com    sc_int_base aa(1);
12912854Sgabeblack@google.com    if (low_i < src.length())
13012854Sgabeblack@google.com        *this = aa = 1 & (src >> low_i);
13112854Sgabeblack@google.com    else
13212854Sgabeblack@google.com        *this = aa = 0;
13312854Sgabeblack@google.com}
13412854Sgabeblack@google.com
13512854Sgabeblack@google.comvoid sc_int_bitref::concat_set(uint64 src, int low_i)
13612854Sgabeblack@google.com{
13712854Sgabeblack@google.com    sc_int_base aa(1);
13812854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
13912854Sgabeblack@google.com}
14012854Sgabeblack@google.com
14112854Sgabeblack@google.com
14212854Sgabeblack@google.com// other methods
14312854Sgabeblack@google.comvoid
14412854Sgabeblack@google.comsc_int_bitref::scan(::std::istream &is)
14512854Sgabeblack@google.com{
14612854Sgabeblack@google.com    bool b;
14712854Sgabeblack@google.com    is >> b;
14812854Sgabeblack@google.com    *this = b;
14912854Sgabeblack@google.com}
15012854Sgabeblack@google.com
15112854Sgabeblack@google.com
15212854Sgabeblack@google.com// ----------------------------------------------------------------------------
15312854Sgabeblack@google.com//  CLASS : sc_int_subref_r
15412854Sgabeblack@google.com//
15512854Sgabeblack@google.com//  Proxy class for sc_int part selection (l-value).
15612854Sgabeblack@google.com// ----------------------------------------------------------------------------
15712854Sgabeblack@google.com
15812854Sgabeblack@google.combool
15912854Sgabeblack@google.comsc_int_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
16012854Sgabeblack@google.com{
16112854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
16212854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
16312854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
16412854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
16512854Sgabeblack@google.com
16612854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
16712854Sgabeblack@google.com    high_i = low_i + (m_left - m_right);
16812854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
16912854Sgabeblack@google.com    mask = ~mask_int[m_left][m_right];
17012854Sgabeblack@google.com
17112854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
17212854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
17312854Sgabeblack@google.com    switch (end_i - dst_i) {
17412854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
17512854Sgabeblack@google.com      case 1:
17612854Sgabeblack@google.com        dst_i++;
17712854Sgabeblack@google.com        dst_p[dst_i] = 0;
17812854Sgabeblack@google.com        break;
17912854Sgabeblack@google.com
18012854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
18112854Sgabeblack@google.com      case 2:
18212854Sgabeblack@google.com        dst_i++;
18312854Sgabeblack@google.com        dst_p[dst_i++] = 0;
18412854Sgabeblack@google.com        dst_p[dst_i] = 0;
18512854Sgabeblack@google.com        break;
18612854Sgabeblack@google.com
18712854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
18812854Sgabeblack@google.com      case 3:
18912854Sgabeblack@google.com        dst_i++;
19012854Sgabeblack@google.com        dst_p[dst_i++] = 0;
19112854Sgabeblack@google.com        dst_p[dst_i++] = 0;
19212854Sgabeblack@google.com        dst_p[dst_i] = 0;
19312854Sgabeblack@google.com        break;
19412854Sgabeblack@google.com    }
19512854Sgabeblack@google.com    return false;
19612854Sgabeblack@google.com}
19712854Sgabeblack@google.com
19812854Sgabeblack@google.combool
19912854Sgabeblack@google.comsc_int_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
20012854Sgabeblack@google.com{
20112854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
20212854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
20312854Sgabeblack@google.com    int high_i; // Index of high order bit in dst_p to set.
20412854Sgabeblack@google.com    int left_shift; // Left shift for val.
20512854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
20612854Sgabeblack@google.com    bool non_zero; // True if value inserted is non-zero.
20712854Sgabeblack@google.com    uint_type val; // Selection value extracted from m_obj_p.
20812854Sgabeblack@google.com
20912854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
21012854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
21112854Sgabeblack@google.com    high_i = low_i + (m_left-m_right);
21212854Sgabeblack@google.com    end_i = high_i / BITS_PER_DIGIT;
21312854Sgabeblack@google.com    mask = ~mask_int[m_left][m_right];
21412854Sgabeblack@google.com    val = (m_obj_p->m_val & mask) >> m_right;
21512854Sgabeblack@google.com    non_zero = val != 0;
21612854Sgabeblack@google.com
21712854Sgabeblack@google.com    // PROCESS THE FIRST WORD:
21812854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
21912854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask) |
22012854Sgabeblack@google.com                ((val << left_shift) & DIGIT_MASK));
22112854Sgabeblack@google.com
22212854Sgabeblack@google.com    switch (end_i - dst_i) {
22312854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
22412854Sgabeblack@google.com      case 1:
22512854Sgabeblack@google.com        dst_i++;
22612854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
22712854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)(val & DIGIT_MASK);
22812854Sgabeblack@google.com        break;
22912854Sgabeblack@google.com
23012854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
23112854Sgabeblack@google.com      case 2:
23212854Sgabeblack@google.com        dst_i++;
23312854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
23412854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23512854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
23612854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
23712854Sgabeblack@google.com        break;
23812854Sgabeblack@google.com
23912854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
24012854Sgabeblack@google.com      case 3:
24112854Sgabeblack@google.com        dst_i++;
24212854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
24312854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
24412854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
24512854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
24612854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
24712854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
24812854Sgabeblack@google.com        break;
24912854Sgabeblack@google.com    }
25012854Sgabeblack@google.com    return non_zero;
25112854Sgabeblack@google.com}
25212854Sgabeblack@google.com
25312854Sgabeblack@google.com// ----------------------------------------------------------------------------
25412854Sgabeblack@google.com//  CLASS : sc_int_subref
25512854Sgabeblack@google.com//
25612854Sgabeblack@google.com//  Proxy class for sc_int part selection (r-value and l-value).
25712854Sgabeblack@google.com// ----------------------------------------------------------------------------
25812854Sgabeblack@google.com
25912854Sgabeblack@google.comsc_core::sc_vpool<sc_int_subref> sc_int_subref::m_pool(9);
26012854Sgabeblack@google.com
26112854Sgabeblack@google.com// assignment operators
26212854Sgabeblack@google.com
26312854Sgabeblack@google.comsc_int_subref &
26412854Sgabeblack@google.comsc_int_subref::operator = (int_type v)
26512854Sgabeblack@google.com{
26612854Sgabeblack@google.com    int_type val = m_obj_p->m_val;
26712854Sgabeblack@google.com    uint_type mask = mask_int[m_left][m_right];
26812854Sgabeblack@google.com    val &= mask;
26912854Sgabeblack@google.com    val |= (v << m_right) & ~mask;
27012854Sgabeblack@google.com    m_obj_p->m_val = val;
27112854Sgabeblack@google.com    m_obj_p->extend_sign();
27212854Sgabeblack@google.com    return *this;
27312854Sgabeblack@google.com}
27412854Sgabeblack@google.com
27512854Sgabeblack@google.comsc_int_subref &
27612854Sgabeblack@google.comsc_int_subref::operator = (const sc_signed &a)
27712854Sgabeblack@google.com{
27812854Sgabeblack@google.com    sc_int_base aa(length());
27912854Sgabeblack@google.com    return (*this = aa = a);
28012854Sgabeblack@google.com}
28112854Sgabeblack@google.com
28212854Sgabeblack@google.comsc_int_subref &
28312854Sgabeblack@google.comsc_int_subref::operator = (const sc_unsigned &a)
28412854Sgabeblack@google.com{
28512854Sgabeblack@google.com    sc_int_base aa(length());
28612854Sgabeblack@google.com    return (*this = aa = a);
28712854Sgabeblack@google.com}
28812854Sgabeblack@google.com
28912854Sgabeblack@google.comsc_int_subref &
29012854Sgabeblack@google.comsc_int_subref::operator = (const sc_bv_base &a)
29112854Sgabeblack@google.com{
29212854Sgabeblack@google.com    sc_int_base aa(length());
29312854Sgabeblack@google.com    return (*this = aa = a);
29412854Sgabeblack@google.com}
29512854Sgabeblack@google.com
29612854Sgabeblack@google.comsc_int_subref &
29712854Sgabeblack@google.comsc_int_subref::operator = (const sc_lv_base &a)
29812854Sgabeblack@google.com{
29912854Sgabeblack@google.com    sc_int_base aa(length());
30012854Sgabeblack@google.com    return (*this = aa = a);
30112854Sgabeblack@google.com}
30212854Sgabeblack@google.com
30312854Sgabeblack@google.com
30412854Sgabeblack@google.com// concatenation methods:
30512854Sgabeblack@google.com// #### OPTIMIZE
30612854Sgabeblack@google.comvoid
30712854Sgabeblack@google.comsc_int_subref::concat_set(int64 src, int low_i)
30812854Sgabeblack@google.com{
30912854Sgabeblack@google.com    sc_int_base aa(length());
31012854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
31112854Sgabeblack@google.com}
31212854Sgabeblack@google.com
31312854Sgabeblack@google.comvoid
31412854Sgabeblack@google.comsc_int_subref::concat_set(const sc_signed &src, int low_i)
31512854Sgabeblack@google.com{
31612854Sgabeblack@google.com    sc_int_base aa(length());
31712854Sgabeblack@google.com    if (low_i < src.length())
31812854Sgabeblack@google.com        *this = aa = src >> low_i;
31912854Sgabeblack@google.com    else
32012854Sgabeblack@google.com        *this = (src < 0) ? (int_type)-1 : 0;
32112854Sgabeblack@google.com}
32212854Sgabeblack@google.com
32312854Sgabeblack@google.comvoid
32412854Sgabeblack@google.comsc_int_subref::concat_set(const sc_unsigned &src, int low_i)
32512854Sgabeblack@google.com{
32612854Sgabeblack@google.com    sc_int_base aa(length());
32712854Sgabeblack@google.com    if (low_i < src.length())
32812854Sgabeblack@google.com        *this = aa = src >> low_i;
32912854Sgabeblack@google.com    else
33012854Sgabeblack@google.com        *this = 0;
33112854Sgabeblack@google.com}
33212854Sgabeblack@google.com
33312854Sgabeblack@google.comvoid
33412854Sgabeblack@google.comsc_int_subref::concat_set(uint64 src, int low_i)
33512854Sgabeblack@google.com{
33612854Sgabeblack@google.com    sc_int_base aa (length());
33712854Sgabeblack@google.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
33812854Sgabeblack@google.com}
33912854Sgabeblack@google.com
34012854Sgabeblack@google.com
34112854Sgabeblack@google.com// other methods
34212854Sgabeblack@google.comvoid
34312854Sgabeblack@google.comsc_int_subref::scan(::std::istream &is)
34412854Sgabeblack@google.com{
34512854Sgabeblack@google.com    std::string s;
34612854Sgabeblack@google.com    is >> s;
34712854Sgabeblack@google.com    *this = s.c_str();
34812854Sgabeblack@google.com}
34912854Sgabeblack@google.com
35012854Sgabeblack@google.com
35112854Sgabeblack@google.com// ----------------------------------------------------------------------------
35212854Sgabeblack@google.com//  CLASS : sc_int_base
35312854Sgabeblack@google.com//
35412854Sgabeblack@google.com//  Base class for sc_int.
35512854Sgabeblack@google.com// ----------------------------------------------------------------------------
35612854Sgabeblack@google.com
35712854Sgabeblack@google.com// support methods
35812854Sgabeblack@google.comvoid
35912854Sgabeblack@google.comsc_int_base::invalid_length() const
36012854Sgabeblack@google.com{
36112854Sgabeblack@google.com    std::stringstream msg;
36212854Sgabeblack@google.com    msg << "sc_int[_base] initialization: length = " << m_len <<
36312854Sgabeblack@google.com           " violates 1 <= length <= " << SC_INTWIDTH;
36412854Sgabeblack@google.com    SC_REPORT_ERROR("out of bounds", msg.str().c_str());
36512854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
36612854Sgabeblack@google.com}
36712854Sgabeblack@google.com
36812854Sgabeblack@google.comvoid
36912854Sgabeblack@google.comsc_int_base::invalid_index(int i) const
37012854Sgabeblack@google.com{
37112854Sgabeblack@google.com    std::stringstream msg;
37212854Sgabeblack@google.com    msg << "sc_int[_base] bit selection: index = " << i <<
37312854Sgabeblack@google.com           " violates 0 <= index <= " << (m_len - 1);
37412854Sgabeblack@google.com    SC_REPORT_ERROR("out of bounds", msg.str().c_str());
37512854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
37612854Sgabeblack@google.com}
37712854Sgabeblack@google.com
37812854Sgabeblack@google.comvoid
37912854Sgabeblack@google.comsc_int_base::invalid_range(int l, int r) const
38012854Sgabeblack@google.com{
38112854Sgabeblack@google.com    std::stringstream msg;
38212854Sgabeblack@google.com    msg << "sc_int[_base] part selection: " <<
38312854Sgabeblack@google.com           "left = " << l << ", right = " << r << " violates " <<
38412854Sgabeblack@google.com           (m_len-1) << " >= left >= right >= 0";
38512854Sgabeblack@google.com    SC_REPORT_ERROR("out of bounds", msg.str().c_str());
38612854Sgabeblack@google.com    sc_core::sc_abort(); // can't recover from here
38712854Sgabeblack@google.com}
38812854Sgabeblack@google.com
38912854Sgabeblack@google.comvoid
39012854Sgabeblack@google.comsc_int_base::check_value() const
39112854Sgabeblack@google.com{
39212854Sgabeblack@google.com    int_type limit = (int_type)1 << (m_len - 1);
39312854Sgabeblack@google.com    if (m_val < -limit || m_val >= limit) {
39412854Sgabeblack@google.com        std::stringstream msg;
39512854Sgabeblack@google.com        msg << "sc_int[_base]: value does not fit into a length of " << m_len;
39612854Sgabeblack@google.com        SC_REPORT_WARNING("out of bounds", msg.str().c_str());
39712854Sgabeblack@google.com    }
39812854Sgabeblack@google.com}
39912854Sgabeblack@google.com
40012854Sgabeblack@google.com
40112854Sgabeblack@google.com// constructors
40212854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_bv_base &v) :
40312854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
40412854Sgabeblack@google.com{
40512854Sgabeblack@google.com    check_length();
40612854Sgabeblack@google.com    *this = v;
40712854Sgabeblack@google.com}
40812854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_lv_base &v) :
40912854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
41012854Sgabeblack@google.com{
41112854Sgabeblack@google.com    check_length();
41212854Sgabeblack@google.com    *this = v;
41312854Sgabeblack@google.com}
41412854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_uint_subref_r &v) :
41512854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
41612854Sgabeblack@google.com{
41712854Sgabeblack@google.com    check_length();
41812854Sgabeblack@google.com    *this = v.to_uint64();
41912854Sgabeblack@google.com}
42012854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_signed_subref_r &v) :
42112854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
42212854Sgabeblack@google.com{
42312854Sgabeblack@google.com    check_length();
42412854Sgabeblack@google.com    *this = v.to_uint64();
42512854Sgabeblack@google.com}
42612854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_unsigned_subref_r &v) :
42712854Sgabeblack@google.com    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
42812854Sgabeblack@google.com{
42912854Sgabeblack@google.com    check_length();
43012854Sgabeblack@google.com    *this = v.to_uint64();
43112854Sgabeblack@google.com}
43212854Sgabeblack@google.com
43312854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_signed &a) :
43412854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
43512854Sgabeblack@google.com{
43612854Sgabeblack@google.com    check_length();
43712854Sgabeblack@google.com    *this = a.to_int64();
43812854Sgabeblack@google.com}
43912854Sgabeblack@google.com
44012854Sgabeblack@google.comsc_int_base::sc_int_base(const sc_unsigned &a) :
44112854Sgabeblack@google.com    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
44212854Sgabeblack@google.com{
44312854Sgabeblack@google.com    check_length();
44412854Sgabeblack@google.com    *this = a.to_int64();
44512854Sgabeblack@google.com}
44612854Sgabeblack@google.com
44712854Sgabeblack@google.com
44812854Sgabeblack@google.com// assignment operators
44912854Sgabeblack@google.comsc_int_base &
45012854Sgabeblack@google.comsc_int_base::operator = (const sc_signed &a)
45112854Sgabeblack@google.com{
45212854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
45312854Sgabeblack@google.com    int i = 0;
45412854Sgabeblack@google.com    for (; i < minlen; ++i) {
45512854Sgabeblack@google.com        set(i, a.test(i));
45612854Sgabeblack@google.com    }
45712854Sgabeblack@google.com    bool sgn = a.sign();
45812854Sgabeblack@google.com    for (; i < m_len; ++i) {
45912854Sgabeblack@google.com        // sign extension
46012854Sgabeblack@google.com        set(i, sgn);
46112854Sgabeblack@google.com    }
46212854Sgabeblack@google.com    extend_sign();
46312854Sgabeblack@google.com    return *this;
46412854Sgabeblack@google.com}
46512854Sgabeblack@google.com
46612854Sgabeblack@google.comsc_int_base &
46712854Sgabeblack@google.comsc_int_base::operator = (const sc_unsigned &a)
46812854Sgabeblack@google.com{
46912854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
47012854Sgabeblack@google.com    int i = 0;
47112854Sgabeblack@google.com    for (; i < minlen; ++i) {
47212854Sgabeblack@google.com        set(i, a.test(i));
47312854Sgabeblack@google.com    }
47412854Sgabeblack@google.com    for (; i < m_len; ++i) {
47512854Sgabeblack@google.com        // zero extension
47612854Sgabeblack@google.com        set(i, 0);
47712854Sgabeblack@google.com    }
47812854Sgabeblack@google.com    extend_sign();
47912854Sgabeblack@google.com    return *this;
48012854Sgabeblack@google.com}
48112854Sgabeblack@google.com
48212854Sgabeblack@google.com
48312854Sgabeblack@google.comsc_int_base &
48412854Sgabeblack@google.comsc_int_base::operator = (const sc_bv_base &a)
48512854Sgabeblack@google.com{
48612854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
48712854Sgabeblack@google.com    int i = 0;
48812854Sgabeblack@google.com    for (; i < minlen; ++i) {
48912854Sgabeblack@google.com        set(i, a.get_bit(i));
49012854Sgabeblack@google.com    }
49112854Sgabeblack@google.com    for (; i < m_len; ++i) {
49212854Sgabeblack@google.com        // zero extension
49312854Sgabeblack@google.com        set(i, 0);
49412854Sgabeblack@google.com    }
49512854Sgabeblack@google.com    extend_sign();
49612854Sgabeblack@google.com    return *this;
49712854Sgabeblack@google.com}
49812854Sgabeblack@google.com
49912854Sgabeblack@google.comsc_int_base &
50012854Sgabeblack@google.comsc_int_base::operator = (const sc_lv_base &a)
50112854Sgabeblack@google.com{
50212854Sgabeblack@google.com    int minlen = sc_min(m_len, a.length());
50312854Sgabeblack@google.com    int i = 0;
50412854Sgabeblack@google.com    for (; i < minlen; ++i) {
50512854Sgabeblack@google.com        set(i, sc_logic(a.get_bit(i)).to_bool());
50612854Sgabeblack@google.com    }
50712854Sgabeblack@google.com    for (; i < m_len; ++i) {
50812854Sgabeblack@google.com        // zero extension
50912854Sgabeblack@google.com        set(i, 0);
51012854Sgabeblack@google.com    }
51112854Sgabeblack@google.com    extend_sign();
51212854Sgabeblack@google.com    return *this;
51312854Sgabeblack@google.com}
51412854Sgabeblack@google.com
51512854Sgabeblack@google.comsc_int_base &
51612854Sgabeblack@google.comsc_int_base::operator = (const char *a)
51712854Sgabeblack@google.com{
51812854Sgabeblack@google.com    if (a == 0) {
51912854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed",
52012854Sgabeblack@google.com                        "character string is zero");
52112854Sgabeblack@google.com    } else if (*a == 0) {
52212854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed",
52312854Sgabeblack@google.com                        "character string is empty");
52412854Sgabeblack@google.com    } else try {
52512854Sgabeblack@google.com        int len = m_len;
52612854Sgabeblack@google.com        sc_fix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
52712854Sgabeblack@google.com        return this->operator = (aa);
52812854Sgabeblack@google.com    } catch(const sc_core::sc_report &) {
52912854Sgabeblack@google.com        std::stringstream msg;
53012854Sgabeblack@google.com        msg << "character string '" << a << "' is not valid";
53112854Sgabeblack@google.com        SC_REPORT_ERROR("conversion failed", msg.str().c_str());
53212854Sgabeblack@google.com    }
53312854Sgabeblack@google.com    return *this;
53412854Sgabeblack@google.com}
53512854Sgabeblack@google.com
53612854Sgabeblack@google.com// explicit conversion to character string
53712854Sgabeblack@google.comconst std::string
53812854Sgabeblack@google.comsc_int_base::to_string(sc_numrep numrep) const
53912854Sgabeblack@google.com{
54012854Sgabeblack@google.com    int len = m_len;
54112854Sgabeblack@google.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
54212854Sgabeblack@google.com    return aa.to_string(numrep);
54312854Sgabeblack@google.com}
54412854Sgabeblack@google.com
54512854Sgabeblack@google.comconst std::string
54612854Sgabeblack@google.comsc_int_base::to_string(sc_numrep numrep, bool w_prefix) const
54712854Sgabeblack@google.com{
54812854Sgabeblack@google.com    int len = m_len;
54912854Sgabeblack@google.com    sc_fix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
55012854Sgabeblack@google.com    return aa.to_string(numrep, w_prefix);
55112854Sgabeblack@google.com}
55212854Sgabeblack@google.com
55312854Sgabeblack@google.com
55412854Sgabeblack@google.com// reduce methods
55512854Sgabeblack@google.combool sc_int_base::and_reduce() const { return (m_val == int_type(-1)); }
55612854Sgabeblack@google.combool sc_int_base::or_reduce() const { return (m_val != int_type(0)); }
55712854Sgabeblack@google.com
55812854Sgabeblack@google.combool
55912854Sgabeblack@google.comsc_int_base::xor_reduce() const
56012854Sgabeblack@google.com{
56112854Sgabeblack@google.com    uint_type mask = ~UINT_ZERO;
56212854Sgabeblack@google.com    uint_type val = m_val & (mask >> m_ulen);
56312854Sgabeblack@google.com    int n = SC_INTWIDTH;
56412854Sgabeblack@google.com    do {
56512854Sgabeblack@google.com        n >>= 1;
56612854Sgabeblack@google.com        mask >>= n;
56712854Sgabeblack@google.com        val = ((val & (mask << n)) >> n) ^ (val & mask);
56812854Sgabeblack@google.com    } while (n != 1);
56912854Sgabeblack@google.com    return (val != uint_type(0));
57012854Sgabeblack@google.com}
57112854Sgabeblack@google.com
57212854Sgabeblack@google.combool
57312854Sgabeblack@google.comsc_int_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
57412854Sgabeblack@google.com{
57512854Sgabeblack@google.com    int dst_i; // Word in dst_p now processing.
57612854Sgabeblack@google.com    int end_i; // Highest order word in dst_p to process.
57712854Sgabeblack@google.com    int left_shift; // Left shift for val.
57812854Sgabeblack@google.com    uint_type mask; // Mask for bits to extract or keep.
57912854Sgabeblack@google.com
58012854Sgabeblack@google.com    dst_i = low_i / BITS_PER_DIGIT;
58112854Sgabeblack@google.com    left_shift = low_i % BITS_PER_DIGIT;
58212854Sgabeblack@google.com    end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
58312854Sgabeblack@google.com
58412854Sgabeblack@google.com    mask = ~(~UINT_ZERO << left_shift);
58512854Sgabeblack@google.com    dst_p[dst_i] = (sc_digit)(dst_p[dst_i] & mask);
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_int_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_int_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 non_zero; // True if value inserted is non-zero.
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    non_zero = val != 0;
62412854Sgabeblack@google.com
62512854Sgabeblack@google.com    // MASK OFF DATA TO BE TRANSFERRED BASED 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    switch (end_i - dst_i) {
63612854Sgabeblack@google.com      // BITS ARE ACROSS TWO WORDS:
63712854Sgabeblack@google.com      case 1:
63812854Sgabeblack@google.com        dst_i++;
63912854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
64012854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
64112854Sgabeblack@google.com        break;
64212854Sgabeblack@google.com
64312854Sgabeblack@google.com      // BITS ARE ACROSS THREE WORDS:
64412854Sgabeblack@google.com      case 2:
64512854Sgabeblack@google.com        dst_i++;
64612854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
64712854Sgabeblack@google.com        dst_p[dst_i++] = ((sc_digit)val) & DIGIT_MASK;
64812854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
64912854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
65012854Sgabeblack@google.com        break;
65112854Sgabeblack@google.com
65212854Sgabeblack@google.com      // BITS ARE ACROSS FOUR WORDS:
65312854Sgabeblack@google.com      case 3:
65412854Sgabeblack@google.com        dst_i++;
65512854Sgabeblack@google.com        val >>= (BITS_PER_DIGIT - left_shift);
65612854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
65712854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
65812854Sgabeblack@google.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
65912854Sgabeblack@google.com        val >>= BITS_PER_DIGIT;
66012854Sgabeblack@google.com        dst_p[dst_i] = (sc_digit)val;
66112854Sgabeblack@google.com        break;
66212854Sgabeblack@google.com    }
66312854Sgabeblack@google.com    return non_zero;
66412854Sgabeblack@google.com}
66512854Sgabeblack@google.com
66612854Sgabeblack@google.com// #### OPTIMIZE
66712854Sgabeblack@google.comvoid
66812854Sgabeblack@google.comsc_int_base::concat_set(int64 src, int low_i)
66912854Sgabeblack@google.com{
67012854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : src >> 63;
67112854Sgabeblack@google.com}
67212854Sgabeblack@google.com
67312854Sgabeblack@google.comvoid
67412854Sgabeblack@google.comsc_int_base::concat_set(const sc_signed &src, int low_i)
67512854Sgabeblack@google.com{
67612854Sgabeblack@google.com    if (low_i < src.length())
67712854Sgabeblack@google.com        *this = src >> low_i;
67812854Sgabeblack@google.com    else
67912854Sgabeblack@google.com        *this = (src < 0) ? (int_type)-1 : 0;
68012854Sgabeblack@google.com}
68112854Sgabeblack@google.com
68212854Sgabeblack@google.comvoid
68312854Sgabeblack@google.comsc_int_base::concat_set(const sc_unsigned &src, int low_i)
68412854Sgabeblack@google.com{
68512854Sgabeblack@google.com    if (low_i < src.length())
68612854Sgabeblack@google.com        *this = src >> low_i;
68712854Sgabeblack@google.com    else
68812854Sgabeblack@google.com        *this = 0;
68912854Sgabeblack@google.com}
69012854Sgabeblack@google.com
69112854Sgabeblack@google.comvoid
69212854Sgabeblack@google.comsc_int_base::concat_set(uint64 src, int low_i)
69312854Sgabeblack@google.com{
69412854Sgabeblack@google.com    *this = (low_i < 64) ? src >> low_i : 0;
69512854Sgabeblack@google.com}
69612854Sgabeblack@google.com
69712854Sgabeblack@google.com// other methods
69812854Sgabeblack@google.comvoid
69912854Sgabeblack@google.comsc_int_base::scan(::std::istream &is)
70012854Sgabeblack@google.com{
70112854Sgabeblack@google.com    std::string s;
70212854Sgabeblack@google.com    is >> s;
70312854Sgabeblack@google.com    *this = s.c_str();
70412854Sgabeblack@google.com}
70512854Sgabeblack@google.com
70612854Sgabeblack@google.com} // namespace sc_dt;
707