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