sc_int_base.cc revision 13325
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