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