sc_uint_base.cc revision 13325:86323e6cc8ec
113481Sgiacomo.travaglini@arm.com/*****************************************************************************
213481Sgiacomo.travaglini@arm.com
313481Sgiacomo.travaglini@arm.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413481Sgiacomo.travaglini@arm.com  more contributor license agreements.  See the NOTICE file distributed
513481Sgiacomo.travaglini@arm.com  with this work for additional information regarding copyright ownership.
613481Sgiacomo.travaglini@arm.com  Accellera licenses this file to you under the Apache License, Version 2.0
713481Sgiacomo.travaglini@arm.com  (the "License"); you may not use this file except in compliance with the
813481Sgiacomo.travaglini@arm.com  License.  You may obtain a copy of the License at
913481Sgiacomo.travaglini@arm.com
1013481Sgiacomo.travaglini@arm.com    http://www.apache.org/licenses/LICENSE-2.0
1113481Sgiacomo.travaglini@arm.com
1213481Sgiacomo.travaglini@arm.com  Unless required by applicable law or agreed to in writing, software
1313481Sgiacomo.travaglini@arm.com  distributed under the License is distributed on an "AS IS" BASIS,
1413481Sgiacomo.travaglini@arm.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513481Sgiacomo.travaglini@arm.com  implied.  See the License for the specific language governing
1613481Sgiacomo.travaglini@arm.com  permissions and limitations under the License.
1713481Sgiacomo.travaglini@arm.com
1813481Sgiacomo.travaglini@arm.com *****************************************************************************/
1913481Sgiacomo.travaglini@arm.com
2013481Sgiacomo.travaglini@arm.com/*****************************************************************************
2113481Sgiacomo.travaglini@arm.com
2213481Sgiacomo.travaglini@arm.com  sc_uint_base.cpp -- contains interface definitions between sc_uint and
2313481Sgiacomo.travaglini@arm.com                 sc_signed, sc_unsigned, and definitions for sc_uint_subref.
2413481Sgiacomo.travaglini@arm.com
2513481Sgiacomo.travaglini@arm.com  Original Author: Ali Dasdan, Synopsys, Inc.
2613481Sgiacomo.travaglini@arm.com
2713481Sgiacomo.travaglini@arm.com *****************************************************************************/
2813481Sgiacomo.travaglini@arm.com
2913481Sgiacomo.travaglini@arm.com/*****************************************************************************
3013481Sgiacomo.travaglini@arm.com
3113481Sgiacomo.travaglini@arm.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3213481Sgiacomo.travaglini@arm.com  changes you are making here.
3313481Sgiacomo.travaglini@arm.com
3413481Sgiacomo.travaglini@arm.com      Name, Affiliation, Date:
3513481Sgiacomo.travaglini@arm.com  Description of Modification:
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com *****************************************************************************/
3813481Sgiacomo.travaglini@arm.com
3913481Sgiacomo.travaglini@arm.com
4013481Sgiacomo.travaglini@arm.com// $Log: sc_uint_base.cpp,v $
4113481Sgiacomo.travaglini@arm.com// Revision 1.5  2011/02/18 20:19:15  acg
4213481Sgiacomo.travaglini@arm.com//  Andy Goodrich: updating Copyright notice.
4313481Sgiacomo.travaglini@arm.com//
4413481Sgiacomo.travaglini@arm.com// Revision 1.4  2010/02/04 22:23:29  acg
4513481Sgiacomo.travaglini@arm.com//  Andy Goodrich: fixed bug in concatenation reads for part selections,
4613481Sgiacomo.travaglini@arm.com//  the mask being used was 32 bits and should have been 64 bits.
4713481Sgiacomo.travaglini@arm.com//
4813481Sgiacomo.travaglini@arm.com// Revision 1.3  2008/06/19 17:47:57  acg
4913481Sgiacomo.travaglini@arm.com//  Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
5013481Sgiacomo.travaglini@arm.com//
5113481Sgiacomo.travaglini@arm.com// Revision 1.2  2007/11/04 21:27:00  acg
5213481Sgiacomo.travaglini@arm.com//  Andy Goodrich: changes to make sure the proper value is returned from
5313481Sgiacomo.travaglini@arm.com//  concat_get_data().
5413481Sgiacomo.travaglini@arm.com//
5513481Sgiacomo.travaglini@arm.com// Revision 1.1.1.1  2006/12/15 20:20:05  acg
5613481Sgiacomo.travaglini@arm.com// SystemC 2.3
5713481Sgiacomo.travaglini@arm.com//
5813481Sgiacomo.travaglini@arm.com// Revision 1.3  2006/01/13 18:49:32  acg
5913481Sgiacomo.travaglini@arm.com// Added $Log command so that CVS check in comments are reproduced in the
6013481Sgiacomo.travaglini@arm.com// source.
6113481Sgiacomo.travaglini@arm.com//
6213481Sgiacomo.travaglini@arm.com
6313481Sgiacomo.travaglini@arm.com#include <sstream>
6413481Sgiacomo.travaglini@arm.com
6513481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/bit/sc_bv_base.hh"
6613481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/bit/sc_lv_base.hh"
6713481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/fx/sc_ufix.hh"
6813481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/fx/scfx_other_defs.hh"
6913481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/int/sc_signed.hh"
7013481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/int/sc_uint_base.hh"
7113481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/int/sc_unsigned.hh"
7213481Sgiacomo.travaglini@arm.com#include "systemc/ext/dt/misc/sc_concatref.hh"
7313481Sgiacomo.travaglini@arm.com
7413481Sgiacomo.travaglini@arm.com// explicit template instantiations
7513481Sgiacomo.travaglini@arm.comnamespace sc_core
7613481Sgiacomo.travaglini@arm.com{
7713481Sgiacomo.travaglini@arm.com
7813481Sgiacomo.travaglini@arm.comtemplate class sc_vpool<sc_dt::sc_uint_bitref>;
7913481Sgiacomo.travaglini@arm.comtemplate class sc_vpool<sc_dt::sc_uint_subref>;
8013481Sgiacomo.travaglini@arm.com
8113481Sgiacomo.travaglini@arm.com} // namespace sc_core
8213481Sgiacomo.travaglini@arm.com
8313481Sgiacomo.travaglini@arm.comnamespace sc_dt
8413481Sgiacomo.travaglini@arm.com{
8513481Sgiacomo.travaglini@arm.com
8613481Sgiacomo.travaglini@arm.com// to avoid code bloat in sc_uint_concat<T1,T2>
8713481Sgiacomo.travaglini@arm.com
8813481Sgiacomo.travaglini@arm.comvoid
8913481Sgiacomo.travaglini@arm.comsc_uint_concref_invalid_length(int length)
9013481Sgiacomo.travaglini@arm.com{
9113481Sgiacomo.travaglini@arm.com    std::stringstream msg;
9213481Sgiacomo.travaglini@arm.com    msg << "sc_uint_concref<T1,T2> initialization: length = " << length <<
9313481Sgiacomo.travaglini@arm.com           "violates 1 <= length <= " << SC_INTWIDTH;
9413481Sgiacomo.travaglini@arm.com    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
9513481Sgiacomo.travaglini@arm.com    sc_core::sc_abort(); // can't recover from here
9613481Sgiacomo.travaglini@arm.com}
9713481Sgiacomo.travaglini@arm.com
9813481Sgiacomo.travaglini@arm.com
9913481Sgiacomo.travaglini@arm.com
10013481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
10113481Sgiacomo.travaglini@arm.com//  CLASS : sc_uint_bitref
10213481Sgiacomo.travaglini@arm.com//
10313481Sgiacomo.travaglini@arm.com//  Proxy class for sc_uint bit selection (r-value and l-value).
10413481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
10513481Sgiacomo.travaglini@arm.com
10613481Sgiacomo.travaglini@arm.comsc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
10713481Sgiacomo.travaglini@arm.com
10813481Sgiacomo.travaglini@arm.com// concatenation methods:
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.com// #### OPTIMIZE
11113481Sgiacomo.travaglini@arm.comvoid
11213481Sgiacomo.travaglini@arm.comsc_uint_bitref::concat_set(int64 src, int low_i)
11313481Sgiacomo.travaglini@arm.com{
11413481Sgiacomo.travaglini@arm.com    sc_uint_base aa(1);
11513481Sgiacomo.travaglini@arm.com    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
11613481Sgiacomo.travaglini@arm.com}
11713481Sgiacomo.travaglini@arm.com
11813481Sgiacomo.travaglini@arm.comvoid
11913481Sgiacomo.travaglini@arm.comsc_uint_bitref::concat_set(const sc_signed &src, int low_i)
12013481Sgiacomo.travaglini@arm.com{
12113481Sgiacomo.travaglini@arm.com    sc_uint_base aa(1);
12213481Sgiacomo.travaglini@arm.com    if (low_i < src.length())
12313481Sgiacomo.travaglini@arm.com        *this = aa = 1 & (src >> low_i);
12413481Sgiacomo.travaglini@arm.com    else
12513481Sgiacomo.travaglini@arm.com        *this = aa = (src < 0) ? (int_type)-1 : 0;
12613481Sgiacomo.travaglini@arm.com}
12713481Sgiacomo.travaglini@arm.com
12813481Sgiacomo.travaglini@arm.comvoid
12913481Sgiacomo.travaglini@arm.comsc_uint_bitref::concat_set(const sc_unsigned &src, int low_i)
13013481Sgiacomo.travaglini@arm.com{
13113481Sgiacomo.travaglini@arm.com    sc_uint_base aa(1);
13213481Sgiacomo.travaglini@arm.com    if (low_i < src.length())
13313481Sgiacomo.travaglini@arm.com        *this = aa = 1 & (src >> low_i);
13413481Sgiacomo.travaglini@arm.com    else
13513481Sgiacomo.travaglini@arm.com        *this = aa = 0;
13613481Sgiacomo.travaglini@arm.com}
13713481Sgiacomo.travaglini@arm.com
13813481Sgiacomo.travaglini@arm.comvoid
13913481Sgiacomo.travaglini@arm.comsc_uint_bitref::concat_set(uint64 src, int low_i)
14013481Sgiacomo.travaglini@arm.com{
14113481Sgiacomo.travaglini@arm.com    sc_uint_base aa(1);
14213481Sgiacomo.travaglini@arm.com    *this = aa = (low_i < 64) ? src >> low_i : 0;
14313481Sgiacomo.travaglini@arm.com}
14413481Sgiacomo.travaglini@arm.com
14513481Sgiacomo.travaglini@arm.com
14613481Sgiacomo.travaglini@arm.com// other methods
14713481Sgiacomo.travaglini@arm.comvoid
14813481Sgiacomo.travaglini@arm.comsc_uint_bitref::scan(::std::istream &is)
14913481Sgiacomo.travaglini@arm.com{
15013481Sgiacomo.travaglini@arm.com    bool b;
15113481Sgiacomo.travaglini@arm.com    is >> b;
15213481Sgiacomo.travaglini@arm.com    *this = b;
15313481Sgiacomo.travaglini@arm.com}
15413481Sgiacomo.travaglini@arm.com
15513481Sgiacomo.travaglini@arm.com
15613481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
15713481Sgiacomo.travaglini@arm.com//  CLASS : sc_uint_subref_r
15813481Sgiacomo.travaglini@arm.com//
15913481Sgiacomo.travaglini@arm.com//  Proxy class for sc_uint part selection (l-value).
16013481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
16113481Sgiacomo.travaglini@arm.com
16213481Sgiacomo.travaglini@arm.combool
16313481Sgiacomo.travaglini@arm.comsc_uint_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
16413481Sgiacomo.travaglini@arm.com{
16513481Sgiacomo.travaglini@arm.com    int dst_i; // Word in dst_p now processing.
16613481Sgiacomo.travaglini@arm.com    int end_i; // Highest order word in dst_p to process.
16713481Sgiacomo.travaglini@arm.com    int left_shift; // Left shift for val.
16813481Sgiacomo.travaglini@arm.com    uint_type mask; // Mask for bits to extract or keep.
16913481Sgiacomo.travaglini@arm.com
17013481Sgiacomo.travaglini@arm.com    dst_i = low_i / BITS_PER_DIGIT;
17113481Sgiacomo.travaglini@arm.com    left_shift = low_i % BITS_PER_DIGIT;
17213481Sgiacomo.travaglini@arm.com    end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT;
17313481Sgiacomo.travaglini@arm.com
17413481Sgiacomo.travaglini@arm.com    mask = ~(~UINT_ZERO << left_shift);
17513481Sgiacomo.travaglini@arm.com    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
17613481Sgiacomo.travaglini@arm.com
17713481Sgiacomo.travaglini@arm.com    dst_i++;
17813481Sgiacomo.travaglini@arm.com    for (; dst_i <= end_i; dst_i++)
17913481Sgiacomo.travaglini@arm.com        dst_p[dst_i] = 0;
18013481Sgiacomo.travaglini@arm.com
18113481Sgiacomo.travaglini@arm.com    return false;
18213481Sgiacomo.travaglini@arm.com}
18313481Sgiacomo.travaglini@arm.com
18413481Sgiacomo.travaglini@arm.combool
18513481Sgiacomo.travaglini@arm.comsc_uint_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
18613481Sgiacomo.travaglini@arm.com{
18713481Sgiacomo.travaglini@arm.com    int dst_i; // Word in dst_p now processing.
18813481Sgiacomo.travaglini@arm.com    int end_i; // Highest order word in dst_p to process.
18913481Sgiacomo.travaglini@arm.com    int high_i; // Index of high order bit in dst_p to set.
19013481Sgiacomo.travaglini@arm.com    int left_shift; // Left shift for val.
19113481Sgiacomo.travaglini@arm.com    uint_type mask; // Mask for bits to extract or keep.
19213481Sgiacomo.travaglini@arm.com    bool result; // True if inserting non-zero value.
19313481Sgiacomo.travaglini@arm.com    uint_type val; // Selection value extracted from m_obj_p.
19413481Sgiacomo.travaglini@arm.com
19513481Sgiacomo.travaglini@arm.com    dst_i = low_i / BITS_PER_DIGIT;
19613481Sgiacomo.travaglini@arm.com    left_shift = low_i % BITS_PER_DIGIT;
19713481Sgiacomo.travaglini@arm.com    high_i = low_i + (m_left-m_right);
19813481Sgiacomo.travaglini@arm.com    end_i = high_i / BITS_PER_DIGIT;
19913481Sgiacomo.travaglini@arm.com    mask = ~mask_int[m_left][m_right];
20013481Sgiacomo.travaglini@arm.com    val = (m_obj_p->m_val & mask) >> m_right;
20113481Sgiacomo.travaglini@arm.com    result = val != 0;
20213481Sgiacomo.travaglini@arm.com
20313481Sgiacomo.travaglini@arm.com    // PROCESS THE FIRST WORD:
20413481Sgiacomo.travaglini@arm.com    mask = ~(~UINT_ZERO << left_shift);
20513481Sgiacomo.travaglini@arm.com    dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
20613481Sgiacomo.travaglini@arm.com        ((val << left_shift) & DIGIT_MASK));
20713481Sgiacomo.travaglini@arm.com
20813481Sgiacomo.travaglini@arm.com    switch (end_i - dst_i) {
20913481Sgiacomo.travaglini@arm.com      // BITS ARE ACROSS TWO WORDS:
21013481Sgiacomo.travaglini@arm.com      case 1:
21113481Sgiacomo.travaglini@arm.com        dst_i++;
21213481Sgiacomo.travaglini@arm.com        val >>= (BITS_PER_DIGIT-left_shift);
21313481Sgiacomo.travaglini@arm.com        dst_p[dst_i] = (sc_digit)val;
21413481Sgiacomo.travaglini@arm.com        break;
21513481Sgiacomo.travaglini@arm.com
21613481Sgiacomo.travaglini@arm.com      // BITS ARE ACROSS THREE WORDS:
21713481Sgiacomo.travaglini@arm.com      case 2:
21813481Sgiacomo.travaglini@arm.com        dst_i++;
21913481Sgiacomo.travaglini@arm.com        val >>= (BITS_PER_DIGIT-left_shift);
22013481Sgiacomo.travaglini@arm.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
22113481Sgiacomo.travaglini@arm.com        val >>= BITS_PER_DIGIT;
22213481Sgiacomo.travaglini@arm.com        dst_p[dst_i] = (sc_digit)val;
22313481Sgiacomo.travaglini@arm.com        break;
22413481Sgiacomo.travaglini@arm.com
22513481Sgiacomo.travaglini@arm.com      // BITS ARE ACROSS THREE WORDS:
22613481Sgiacomo.travaglini@arm.com      case 3:
22713481Sgiacomo.travaglini@arm.com        dst_i++;
22813481Sgiacomo.travaglini@arm.com        val >>= (BITS_PER_DIGIT-left_shift);
22913481Sgiacomo.travaglini@arm.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23013481Sgiacomo.travaglini@arm.com        val >>= BITS_PER_DIGIT;
23113481Sgiacomo.travaglini@arm.com        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
23213481Sgiacomo.travaglini@arm.com        val >>= BITS_PER_DIGIT;
23313481Sgiacomo.travaglini@arm.com        dst_p[dst_i] = (sc_digit)val;
23413481Sgiacomo.travaglini@arm.com        break;
23513481Sgiacomo.travaglini@arm.com    }
23613481Sgiacomo.travaglini@arm.com    return result;
23713481Sgiacomo.travaglini@arm.com}
23813481Sgiacomo.travaglini@arm.com
23913481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
24013481Sgiacomo.travaglini@arm.com//  CLASS : sc_uint_subref
24113481Sgiacomo.travaglini@arm.com//
24213481Sgiacomo.travaglini@arm.com//  Proxy class for sc_uint part selection (r-value and l-value).
24313481Sgiacomo.travaglini@arm.com// ----------------------------------------------------------------------------
24413481Sgiacomo.travaglini@arm.com
24513481Sgiacomo.travaglini@arm.comsc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
24613481Sgiacomo.travaglini@arm.com
24713481Sgiacomo.travaglini@arm.com// assignment operators
24813481Sgiacomo.travaglini@arm.com
24913481Sgiacomo.travaglini@arm.comsc_uint_subref &
25013481Sgiacomo.travaglini@arm.comsc_uint_subref::operator = (uint_type v)
25113481Sgiacomo.travaglini@arm.com{
25213481Sgiacomo.travaglini@arm.com    uint_type val = m_obj_p->m_val;
25313481Sgiacomo.travaglini@arm.com    uint_type mask = mask_int[m_left][m_right];
25413481Sgiacomo.travaglini@arm.com    val &= mask;
25513481Sgiacomo.travaglini@arm.com    val |= (v << m_right) & ~mask;
25613481Sgiacomo.travaglini@arm.com    m_obj_p->m_val = val;
25713481Sgiacomo.travaglini@arm.com    m_obj_p->extend_sign();
25813481Sgiacomo.travaglini@arm.com    return *this;
25913481Sgiacomo.travaglini@arm.com}
26013481Sgiacomo.travaglini@arm.com
26113481Sgiacomo.travaglini@arm.comsc_uint_subref &
26213481Sgiacomo.travaglini@arm.comsc_uint_subref::operator = (const sc_signed &a)
26313481Sgiacomo.travaglini@arm.com{
26413481Sgiacomo.travaglini@arm.com    sc_uint_base aa(length());
26513481Sgiacomo.travaglini@arm.com    return (*this = aa = a);
26613481Sgiacomo.travaglini@arm.com}
26713481Sgiacomo.travaglini@arm.com
26813481Sgiacomo.travaglini@arm.comsc_uint_subref &
26913481Sgiacomo.travaglini@arm.comsc_uint_subref::operator = (const sc_unsigned &a)
27013481Sgiacomo.travaglini@arm.com{
27113481Sgiacomo.travaglini@arm.com    sc_uint_base aa(length());
27213481Sgiacomo.travaglini@arm.com    return (*this = aa = a);
27313481Sgiacomo.travaglini@arm.com}
27413481Sgiacomo.travaglini@arm.com
27513481Sgiacomo.travaglini@arm.comsc_uint_subref &
27613481Sgiacomo.travaglini@arm.comsc_uint_subref::operator = (const sc_bv_base &a)
27713481Sgiacomo.travaglini@arm.com{
27813481Sgiacomo.travaglini@arm.com    sc_uint_base aa(length());
27913481Sgiacomo.travaglini@arm.com    return (*this = aa = a);
28013481Sgiacomo.travaglini@arm.com}
281
282sc_uint_subref &
283sc_uint_subref::operator = (const sc_lv_base &a)
284{
285    sc_uint_base aa(length());
286    return (*this = aa = a);
287}
288
289// concatenation methods:
290
291// #### OPTIMIZE
292void
293sc_uint_subref::concat_set(int64 src, int low_i)
294{
295    sc_uint_base aa(length());
296    *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
297}
298
299void
300sc_uint_subref::concat_set(const sc_signed &src, int low_i)
301{
302    sc_uint_base aa(length());
303    if (low_i < src.length())
304        *this = aa = src >> low_i;
305    else
306        *this = aa = (src < 0) ? (int_type)-1 : 0;
307}
308
309void
310sc_uint_subref::concat_set(const sc_unsigned &src, int low_i)
311{
312    sc_uint_base aa(length());
313    if (low_i < src.length())
314        *this = aa = src >> low_i;
315    else
316        *this = aa = 0;
317}
318
319void
320sc_uint_subref::concat_set(uint64 src, int low_i)
321{
322    sc_uint_base aa(length());
323    *this = aa = (low_i < 64) ? src >> low_i : 0;
324}
325
326// other methods
327void
328sc_uint_subref::scan(::std::istream &is)
329{
330    std::string s;
331    is >> s;
332    *this = s.c_str();
333}
334
335
336// ----------------------------------------------------------------------------
337//  CLASS : sc_uint_base
338//
339//  Base class for sc_uint.
340// ----------------------------------------------------------------------------
341
342// support methods
343
344void
345sc_uint_base::invalid_length() const
346{
347    std::stringstream msg;
348    msg << "sc_uint[_base] initialization: length = " << m_len <<
349           " violates 1 <= length <= " << SC_INTWIDTH;
350    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
351    sc_core::sc_abort(); // can't recover from here}
352}
353
354void
355sc_uint_base::invalid_index(int i) const
356{
357    std::stringstream msg;
358    msg << "sc_uint[_base] bit selection: index = " << i <<
359           " violates 0 <= index <= " << (m_len - 1);
360    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
361    sc_core::sc_abort(); // can't recover from here
362}
363
364void
365sc_uint_base::invalid_range(int l, int r) const
366{
367    std::stringstream msg;
368    msg << "sc_uint[_base] part selection: " <<
369           "left = " << l << ", right = " << r << " violates " <<
370           (m_len - 1) << " >= left >= right >= 0";
371    SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
372    sc_core::sc_abort(); // can't recover from here
373}
374
375
376void
377sc_uint_base::check_value() const
378{
379    uint_type limit = (~UINT_ZERO >> m_ulen);
380    if (m_val > limit) {
381        std::stringstream msg;
382        msg << "sc_uint[_base]: value does not fit into a length of " << m_len;
383        SC_REPORT_WARNING(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str());
384    }
385}
386
387
388// constructors
389sc_uint_base::sc_uint_base(const sc_bv_base &v) :
390    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
391{
392    check_length();
393    *this = v;
394}
395sc_uint_base::sc_uint_base(const sc_lv_base &v) :
396    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
397{
398    check_length();
399    *this = v;
400}
401sc_uint_base::sc_uint_base(const sc_int_subref_r &v) :
402    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
403{
404    check_length();
405    *this = v.to_uint64();
406}
407sc_uint_base::sc_uint_base(const sc_signed_subref_r &v) :
408    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
409{
410    check_length();
411    *this = v.to_uint64();
412}
413sc_uint_base::sc_uint_base(const sc_unsigned_subref_r &v) :
414    m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
415{
416    check_length();
417    *this = v.to_uint64();
418}
419
420sc_uint_base::sc_uint_base(const sc_signed &a) :
421    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
422{
423    check_length();
424    *this = a.to_uint64();
425}
426
427sc_uint_base::sc_uint_base(const sc_unsigned &a) :
428    m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
429{
430    check_length();
431    *this = a.to_uint64();
432}
433
434// assignment operators
435
436sc_uint_base &
437sc_uint_base::operator = (const sc_signed &a)
438{
439    int minlen = sc_min(m_len, a.length());
440    int i = 0;
441    for (; i < minlen; ++i) {
442        set(i, a.test(i));
443    }
444    bool sgn = a.sign();
445    for (; i < m_len; ++i) {
446        // sign extension
447        set(i, sgn);
448    }
449    extend_sign();
450    return *this;
451}
452
453sc_uint_base &
454sc_uint_base::operator = (const sc_unsigned &a)
455{
456    int minlen = sc_min(m_len, a.length());
457    int i = 0;
458    for (; i < minlen; ++i) {
459        set(i, a.test(i));
460    }
461    for (; i < m_len; ++i) {
462        // zero extension
463        set(i, 0);
464    }
465    extend_sign();
466    return *this;
467}
468
469
470sc_uint_base &
471sc_uint_base::operator = (const sc_bv_base &a)
472{
473    int minlen = sc_min(m_len, a.length());
474    int i = 0;
475    for (; i < minlen; ++i) {
476        set(i, a.get_bit(i));
477    }
478    for (; i < m_len; ++i) {
479        // zero extension
480        set(i, 0);
481    }
482    extend_sign();
483    return *this;
484}
485
486sc_uint_base &
487sc_uint_base::operator = (const sc_lv_base &a)
488{
489    int minlen = sc_min(m_len, a.length());
490    int i = 0;
491    for (; i < minlen; ++i) {
492        set(i, sc_logic(a.get_bit(i)).to_bool());
493    }
494    for (; i < m_len; ++i) {
495        // zero extension
496        set(i, 0);
497    }
498    extend_sign();
499    return *this;
500}
501
502sc_uint_base &
503sc_uint_base::operator = (const char *a)
504{
505    if (a == 0) {
506        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
507                        "character string is zero");
508    } else if (*a == 0) {
509        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_,
510                        "character string is empty");
511    } else try {
512        int len = m_len;
513        sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
514        return this->operator = (aa);
515    } catch(const sc_core::sc_report &) {
516        std::stringstream msg;
517        msg << "character string '" << a << "' is not valid";
518        SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg.str().c_str());
519    }
520    return *this;
521}
522
523
524// explicit conversion to character string
525const std::string
526sc_uint_base::to_string(sc_numrep numrep) const
527{
528    int len = m_len;
529    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
530    return aa.to_string(numrep);
531}
532
533const std::string
534sc_uint_base::to_string(sc_numrep numrep, bool w_prefix) const
535{
536    int len = m_len;
537    sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
538    return aa.to_string(numrep, w_prefix);
539}
540
541
542// reduce methods
543bool
544sc_uint_base::and_reduce() const
545{
546    return (m_val == (~UINT_ZERO >> m_ulen));
547}
548
549bool
550sc_uint_base::or_reduce() const
551{
552    return (m_val != uint_type(0));
553}
554
555bool
556sc_uint_base::xor_reduce() const
557{
558    uint_type mask = ~UINT_ZERO;
559    uint_type val = m_val;
560    int n = SC_INTWIDTH;
561    do {
562        n >>= 1;
563        mask >>= n;
564        val = ((val & (mask << n)) >> n) ^ (val & mask);
565    } while (n != 1);
566    return (val != uint_type(0));
567}
568
569
570bool
571sc_uint_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
572{
573    int dst_i; // Word in dst_p now processing.
574    int end_i; // Highest order word in dst_p to process.
575    int left_shift; // Left shift for val.
576    uint_type mask; // Mask for bits to extract or keep.
577
578    dst_i = low_i / BITS_PER_DIGIT;
579    left_shift = low_i % BITS_PER_DIGIT;
580    end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
581
582    // PROCESS THE FIRST WORD:
583    mask = ~(~UINT_ZERO << left_shift);
584    dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
585
586    dst_i++;
587    for (; dst_i <= end_i; dst_i++)
588        dst_p[dst_i] = 0;
589    return false;
590}
591
592//-----------------------------------------------------------------------------
593//"sc_uint_base::concat_get_data"
594//
595// This method transfers the value of this object instance to the supplied
596// array of sc_unsigned digits starting with the bit specified by low_i within
597// the array of digits.
598//
599// Notes:
600//   (1) we don't worry about masking the high order data we transfer since
601//       concat_get_data() is called from low order bit to high order bit. So
602//       the bits above where we place ours will be filled in by someone else.
603//
604//   dst_p -> array of sc_unsigned digits to be filled in.
605//   low_i =  first bit within dst_p to be set.
606//-----------------------------------------------------------------------------
607bool
608sc_uint_base::concat_get_data(sc_digit *dst_p, int low_i) const
609{
610    int dst_i; // Word in dst_p now processing.
611    int end_i; // Highest order word in dst_p to process.
612    int high_i; // Index of high order bit in dst_p to set.
613    int left_shift; // Left shift for val.
614    uint_type mask; // Mask for bits to extract or keep.
615    bool result; // True if inserting non-zero value.
616    uint_type val; // Value for this object.
617
618    dst_i = low_i / BITS_PER_DIGIT;
619    left_shift = low_i % BITS_PER_DIGIT;
620    high_i = low_i + (m_len - 1);
621    end_i = high_i / BITS_PER_DIGIT;
622    val = m_val;
623    result = val != 0;
624
625    // MASK OFF DATA TO BE TRANSFERRED BASE ON WIDTH:
626    if (m_len < 64) {
627        mask = ~(~UINT_ZERO << m_len);
628        val &=  mask;
629    }
630
631    // PROCESS THE FIRST WORD:
632    mask = ~(~UINT_ZERO << left_shift);
633    dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
634        ((val << left_shift) & DIGIT_MASK));
635
636    switch (end_i - dst_i) {
637      // BITS ARE ACROSS TWO WORDS:
638      case 1:
639        dst_i++;
640        val >>= (BITS_PER_DIGIT - left_shift);
641        dst_p[dst_i] = (sc_digit)val;
642        break;
643
644      // BITS ARE ACROSS THREE WORDS:
645      case 2:
646        dst_i++;
647        val >>= (BITS_PER_DIGIT - left_shift);
648        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
649        val >>= BITS_PER_DIGIT;
650        dst_p[dst_i] = (sc_digit)val;
651        break;
652
653      // BITS ARE ACROSS FOUR WORDS:
654      case 3:
655        dst_i++;
656        val >>= (BITS_PER_DIGIT - left_shift);
657        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
658        val >>= BITS_PER_DIGIT;
659        dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
660        val >>= BITS_PER_DIGIT;
661        dst_p[dst_i] = (sc_digit)val;
662        break;
663    }
664    return result;
665}
666
667// #### OPTIMIZE
668void
669sc_uint_base::concat_set(int64 src, int low_i)
670{
671    *this = (low_i < 64) ? src >> low_i : src >> 63;
672}
673
674void
675sc_uint_base::concat_set(const sc_signed &src, int low_i)
676{
677    if (low_i < src.length())
678        *this = src >> low_i;
679    else
680        *this = (src < 0) ? (int_type)-1 : 0;
681}
682
683void
684sc_uint_base::concat_set(const sc_unsigned &src, int low_i)
685{
686    if (low_i < src.length())
687        *this = src >> low_i;
688    else
689        *this = 0;
690}
691
692void
693sc_uint_base::concat_set(uint64 src, int low_i)
694{
695    *this = (low_i < 64) ? src >> low_i : 0;
696}
697
698
699// other methods
700void
701sc_uint_base::scan(::std::istream &is)
702{
703    std::string s;
704    is >> s;
705    *this = s.c_str();
706}
707
708} // namespace sc_dt
709