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