sc_uint_base.cc revision 13325
13536Sgblack@eecs.umich.edu/***************************************************************************** 23536Sgblack@eecs.umich.edu 33536Sgblack@eecs.umich.edu Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 43536Sgblack@eecs.umich.edu more contributor license agreements. See the NOTICE file distributed 53536Sgblack@eecs.umich.edu with this work for additional information regarding copyright ownership. 63536Sgblack@eecs.umich.edu Accellera licenses this file to you under the Apache License, Version 2.0 73536Sgblack@eecs.umich.edu (the "License"); you may not use this file except in compliance with the 83536Sgblack@eecs.umich.edu License. You may obtain a copy of the License at 93536Sgblack@eecs.umich.edu 103536Sgblack@eecs.umich.edu http://www.apache.org/licenses/LICENSE-2.0 113536Sgblack@eecs.umich.edu 123536Sgblack@eecs.umich.edu Unless required by applicable law or agreed to in writing, software 133536Sgblack@eecs.umich.edu distributed under the License is distributed on an "AS IS" BASIS, 143536Sgblack@eecs.umich.edu WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 153536Sgblack@eecs.umich.edu implied. See the License for the specific language governing 163536Sgblack@eecs.umich.edu permissions and limitations under the License. 173536Sgblack@eecs.umich.edu 183536Sgblack@eecs.umich.edu *****************************************************************************/ 193536Sgblack@eecs.umich.edu 203536Sgblack@eecs.umich.edu/***************************************************************************** 213536Sgblack@eecs.umich.edu 223536Sgblack@eecs.umich.edu sc_uint_base.cpp -- contains interface definitions between sc_uint and 233536Sgblack@eecs.umich.edu sc_signed, sc_unsigned, and definitions for sc_uint_subref. 243536Sgblack@eecs.umich.edu 253536Sgblack@eecs.umich.edu Original Author: Ali Dasdan, Synopsys, Inc. 263536Sgblack@eecs.umich.edu 273536Sgblack@eecs.umich.edu *****************************************************************************/ 283536Sgblack@eecs.umich.edu 293536Sgblack@eecs.umich.edu/***************************************************************************** 303536Sgblack@eecs.umich.edu 313536Sgblack@eecs.umich.edu MODIFICATION LOG - modifiers, enter your name, affiliation, date and 328332Snate@binkert.org changes you are making here. 338332Snate@binkert.org 343536Sgblack@eecs.umich.edu Name, Affiliation, Date: 353536Sgblack@eecs.umich.edu Description of Modification: 363536Sgblack@eecs.umich.edu 373536Sgblack@eecs.umich.edu *****************************************************************************/ 383536Sgblack@eecs.umich.edu 393536Sgblack@eecs.umich.edu 403536Sgblack@eecs.umich.edu// $Log: sc_uint_base.cpp,v $ 415543Ssaidi@eecs.umich.edu// Revision 1.5 2011/02/18 20:19:15 acg 425543Ssaidi@eecs.umich.edu// Andy Goodrich: updating Copyright notice. 433536Sgblack@eecs.umich.edu// 443536Sgblack@eecs.umich.edu// Revision 1.4 2010/02/04 22:23:29 acg 453536Sgblack@eecs.umich.edu// Andy Goodrich: fixed bug in concatenation reads for part selections, 463536Sgblack@eecs.umich.edu// the mask being used was 32 bits and should have been 64 bits. 473536Sgblack@eecs.umich.edu// 483536Sgblack@eecs.umich.edu// Revision 1.3 2008/06/19 17:47:57 acg 493536Sgblack@eecs.umich.edu// Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES. 503536Sgblack@eecs.umich.edu// 513536Sgblack@eecs.umich.edu// Revision 1.2 2007/11/04 21:27:00 acg 523536Sgblack@eecs.umich.edu// Andy Goodrich: changes to make sure the proper value is returned from 533536Sgblack@eecs.umich.edu// concat_get_data(). 545543Ssaidi@eecs.umich.edu// 555543Ssaidi@eecs.umich.edu// Revision 1.1.1.1 2006/12/15 20:20:05 acg 563536Sgblack@eecs.umich.edu// SystemC 2.3 573536Sgblack@eecs.umich.edu// 583536Sgblack@eecs.umich.edu// Revision 1.3 2006/01/13 18:49:32 acg 593536Sgblack@eecs.umich.edu// Added $Log command so that CVS check in comments are reproduced in the 603536Sgblack@eecs.umich.edu// source. 613536Sgblack@eecs.umich.edu// 623536Sgblack@eecs.umich.edu 633536Sgblack@eecs.umich.edu#include <sstream> 643536Sgblack@eecs.umich.edu 653536Sgblack@eecs.umich.edu#include "systemc/ext/dt/bit/sc_bv_base.hh" 663536Sgblack@eecs.umich.edu#include "systemc/ext/dt/bit/sc_lv_base.hh" 673536Sgblack@eecs.umich.edu#include "systemc/ext/dt/fx/sc_ufix.hh" 683536Sgblack@eecs.umich.edu#include "systemc/ext/dt/fx/scfx_other_defs.hh" 693536Sgblack@eecs.umich.edu#include "systemc/ext/dt/int/sc_signed.hh" 703536Sgblack@eecs.umich.edu#include "systemc/ext/dt/int/sc_uint_base.hh" 713536Sgblack@eecs.umich.edu#include "systemc/ext/dt/int/sc_unsigned.hh" 725543Ssaidi@eecs.umich.edu#include "systemc/ext/dt/misc/sc_concatref.hh" 733536Sgblack@eecs.umich.edu 743536Sgblack@eecs.umich.edu// explicit template instantiations 753536Sgblack@eecs.umich.edunamespace sc_core 763536Sgblack@eecs.umich.edu{ 773536Sgblack@eecs.umich.edu 783536Sgblack@eecs.umich.edutemplate class sc_vpool<sc_dt::sc_uint_bitref>; 793536Sgblack@eecs.umich.edutemplate class sc_vpool<sc_dt::sc_uint_subref>; 803536Sgblack@eecs.umich.edu 813536Sgblack@eecs.umich.edu} // namespace sc_core 823536Sgblack@eecs.umich.edu 833536Sgblack@eecs.umich.edunamespace sc_dt 843536Sgblack@eecs.umich.edu{ 853536Sgblack@eecs.umich.edu 863536Sgblack@eecs.umich.edu// to avoid code bloat in sc_uint_concat<T1,T2> 873536Sgblack@eecs.umich.edu 883536Sgblack@eecs.umich.eduvoid 893536Sgblack@eecs.umich.edusc_uint_concref_invalid_length(int length) 903536Sgblack@eecs.umich.edu{ 913536Sgblack@eecs.umich.edu std::stringstream msg; 925543Ssaidi@eecs.umich.edu msg << "sc_uint_concref<T1,T2> initialization: length = " << length << 935543Ssaidi@eecs.umich.edu "violates 1 <= length <= " << SC_INTWIDTH; 943536Sgblack@eecs.umich.edu SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, msg.str().c_str()); 953536Sgblack@eecs.umich.edu sc_core::sc_abort(); // can't recover from here 963536Sgblack@eecs.umich.edu} 973536Sgblack@eecs.umich.edu 983536Sgblack@eecs.umich.edu 993536Sgblack@eecs.umich.edu 1003536Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1013536Sgblack@eecs.umich.edu// CLASS : sc_uint_bitref 1023536Sgblack@eecs.umich.edu// 1033536Sgblack@eecs.umich.edu// Proxy class for sc_uint bit selection (r-value and l-value). 1043536Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1053536Sgblack@eecs.umich.edu 1063536Sgblack@eecs.umich.edusc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9); 1073536Sgblack@eecs.umich.edu 1083536Sgblack@eecs.umich.edu// concatenation methods: 1093536Sgblack@eecs.umich.edu 1103536Sgblack@eecs.umich.edu// #### OPTIMIZE 1113536Sgblack@eecs.umich.eduvoid 1123536Sgblack@eecs.umich.edusc_uint_bitref::concat_set(int64 src, int low_i) 1133536Sgblack@eecs.umich.edu{ 1143536Sgblack@eecs.umich.edu sc_uint_base aa(1); 1153536Sgblack@eecs.umich.edu *this = aa = (low_i < 64) ? src >> low_i : src >> 63; 1163536Sgblack@eecs.umich.edu} 1173536Sgblack@eecs.umich.edu 1183536Sgblack@eecs.umich.eduvoid 1193536Sgblack@eecs.umich.edusc_uint_bitref::concat_set(const sc_signed &src, int low_i) 1208229Snate@binkert.org{ 1213536Sgblack@eecs.umich.edu sc_uint_base aa(1); 1223536Sgblack@eecs.umich.edu if (low_i < src.length()) 1233536Sgblack@eecs.umich.edu *this = aa = 1 & (src >> low_i); 1248229Snate@binkert.org else 1253536Sgblack@eecs.umich.edu *this = aa = (src < 0) ? (int_type)-1 : 0; 1263536Sgblack@eecs.umich.edu} 1273536Sgblack@eecs.umich.edu 1283536Sgblack@eecs.umich.eduvoid 1293536Sgblack@eecs.umich.edusc_uint_bitref::concat_set(const sc_unsigned &src, int low_i) 1303536Sgblack@eecs.umich.edu{ 1318229Snate@binkert.org sc_uint_base aa(1); 1323536Sgblack@eecs.umich.edu if (low_i < src.length()) 1338232Snate@binkert.org *this = aa = 1 & (src >> low_i); 1345107Sgblack@eecs.umich.edu else 1353536Sgblack@eecs.umich.edu *this = aa = 0; 1363536Sgblack@eecs.umich.edu} 1377678Sgblack@eecs.umich.edu 1388767Sgblack@eecs.umich.eduvoid 1395107Sgblack@eecs.umich.edusc_uint_bitref::concat_set(uint64 src, int low_i) 1403536Sgblack@eecs.umich.edu{ 1413536Sgblack@eecs.umich.edu sc_uint_base aa(1); 1423536Sgblack@eecs.umich.edu *this = aa = (low_i < 64) ? src >> low_i : 0; 1435567Snate@binkert.org} 1443536Sgblack@eecs.umich.edu 1453550Sgblack@eecs.umich.edu 1464060Ssaidi@eecs.umich.edu// other methods 1473536Sgblack@eecs.umich.eduvoid 1483536Sgblack@eecs.umich.edusc_uint_bitref::scan(::std::istream &is) 1493536Sgblack@eecs.umich.edu{ 1503536Sgblack@eecs.umich.edu bool b; 1513536Sgblack@eecs.umich.edu is >> b; 1525543Ssaidi@eecs.umich.edu *this = b; 1533536Sgblack@eecs.umich.edu} 1543536Sgblack@eecs.umich.edu 1553536Sgblack@eecs.umich.edu 1563536Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1573571Sgblack@eecs.umich.edu// CLASS : sc_uint_subref_r 1587741Sgblack@eecs.umich.edu// 1597741Sgblack@eecs.umich.edu// Proxy class for sc_uint part selection (l-value). 1608767Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 1618767Sgblack@eecs.umich.edu 1628767Sgblack@eecs.umich.edubool 1638767Sgblack@eecs.umich.edusc_uint_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const 1648767Sgblack@eecs.umich.edu{ 1658767Sgblack@eecs.umich.edu int dst_i; // Word in dst_p now processing. 1668767Sgblack@eecs.umich.edu int end_i; // Highest order word in dst_p to process. 1678767Sgblack@eecs.umich.edu int left_shift; // Left shift for val. 1688767Sgblack@eecs.umich.edu uint_type mask; // Mask for bits to extract or keep. 1698767Sgblack@eecs.umich.edu 1708767Sgblack@eecs.umich.edu dst_i = low_i / BITS_PER_DIGIT; 1718767Sgblack@eecs.umich.edu left_shift = low_i % BITS_PER_DIGIT; 1723536Sgblack@eecs.umich.edu end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT; 1733536Sgblack@eecs.umich.edu 1743536Sgblack@eecs.umich.edu mask = ~(~UINT_ZERO << left_shift); 1753536Sgblack@eecs.umich.edu dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask)); 1763536Sgblack@eecs.umich.edu 1775543Ssaidi@eecs.umich.edu dst_i++; 1785543Ssaidi@eecs.umich.edu for (; dst_i <= end_i; dst_i++) 1793536Sgblack@eecs.umich.edu dst_p[dst_i] = 0; 1803536Sgblack@eecs.umich.edu 1813536Sgblack@eecs.umich.edu return false; 1823536Sgblack@eecs.umich.edu} 1833536Sgblack@eecs.umich.edu 1847720Sgblack@eecs.umich.edubool 1857720Sgblack@eecs.umich.edusc_uint_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const 1864172Ssaidi@eecs.umich.edu{ 1874070Ssaidi@eecs.umich.edu int dst_i; // Word in dst_p now processing. 1884070Ssaidi@eecs.umich.edu int end_i; // Highest order word in dst_p to process. 1894070Ssaidi@eecs.umich.edu int high_i; // Index of high order bit in dst_p to set. 1907720Sgblack@eecs.umich.edu int left_shift; // Left shift for val. 1917720Sgblack@eecs.umich.edu uint_type mask; // Mask for bits to extract or keep. 1927741Sgblack@eecs.umich.edu bool result; // True if inserting non-zero value. 1934070Ssaidi@eecs.umich.edu uint_type val; // Selection value extracted from m_obj_p. 1944060Ssaidi@eecs.umich.edu 1954070Ssaidi@eecs.umich.edu dst_i = low_i / BITS_PER_DIGIT; 1964172Ssaidi@eecs.umich.edu left_shift = low_i % BITS_PER_DIGIT; 1974172Ssaidi@eecs.umich.edu high_i = low_i + (m_left-m_right); 1984070Ssaidi@eecs.umich.edu end_i = high_i / BITS_PER_DIGIT; 1994070Ssaidi@eecs.umich.edu mask = ~mask_int[m_left][m_right]; 2007720Sgblack@eecs.umich.edu val = (m_obj_p->m_val & mask) >> m_right; 2017720Sgblack@eecs.umich.edu result = val != 0; 2027741Sgblack@eecs.umich.edu 2034070Ssaidi@eecs.umich.edu // PROCESS THE FIRST WORD: 2044060Ssaidi@eecs.umich.edu mask = ~(~UINT_ZERO << left_shift); 2054172Ssaidi@eecs.umich.edu dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) | 2064172Ssaidi@eecs.umich.edu ((val << left_shift) & DIGIT_MASK)); 2074070Ssaidi@eecs.umich.edu 2084070Ssaidi@eecs.umich.edu switch (end_i - dst_i) { 2094172Ssaidi@eecs.umich.edu // BITS ARE ACROSS TWO WORDS: 2104172Ssaidi@eecs.umich.edu case 1: 2114172Ssaidi@eecs.umich.edu dst_i++; 2124070Ssaidi@eecs.umich.edu val >>= (BITS_PER_DIGIT-left_shift); 2134070Ssaidi@eecs.umich.edu dst_p[dst_i] = (sc_digit)val; 2144060Ssaidi@eecs.umich.edu break; 2154060Ssaidi@eecs.umich.edu 2164060Ssaidi@eecs.umich.edu // BITS ARE ACROSS THREE WORDS: 2177741Sgblack@eecs.umich.edu case 2: 2187741Sgblack@eecs.umich.edu dst_i++; 2197741Sgblack@eecs.umich.edu val >>= (BITS_PER_DIGIT-left_shift); 2203536Sgblack@eecs.umich.edu dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); 2213536Sgblack@eecs.umich.edu val >>= BITS_PER_DIGIT; 2223536Sgblack@eecs.umich.edu dst_p[dst_i] = (sc_digit)val; 2233536Sgblack@eecs.umich.edu break; 2243536Sgblack@eecs.umich.edu 2255543Ssaidi@eecs.umich.edu // BITS ARE ACROSS THREE WORDS: 2265543Ssaidi@eecs.umich.edu case 3: 2273536Sgblack@eecs.umich.edu dst_i++; 2283536Sgblack@eecs.umich.edu val >>= (BITS_PER_DIGIT-left_shift); 2293536Sgblack@eecs.umich.edu dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); 2303536Sgblack@eecs.umich.edu val >>= BITS_PER_DIGIT; 2317720Sgblack@eecs.umich.edu dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK); 2327720Sgblack@eecs.umich.edu val >>= BITS_PER_DIGIT; 2337720Sgblack@eecs.umich.edu dst_p[dst_i] = (sc_digit)val; 2347720Sgblack@eecs.umich.edu break; 2357720Sgblack@eecs.umich.edu } 2367720Sgblack@eecs.umich.edu return result; 2377720Sgblack@eecs.umich.edu} 2387741Sgblack@eecs.umich.edu 2393550Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 2407741Sgblack@eecs.umich.edu// CLASS : sc_uint_subref 2413536Sgblack@eecs.umich.edu// 2423536Sgblack@eecs.umich.edu// Proxy class for sc_uint part selection (r-value and l-value). 2433536Sgblack@eecs.umich.edu// ---------------------------------------------------------------------------- 2443536Sgblack@eecs.umich.edu 2453536Sgblack@eecs.umich.edusc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9); 2464060Ssaidi@eecs.umich.edu 2474060Ssaidi@eecs.umich.edu// assignment operators 2483536Sgblack@eecs.umich.edu 2493536Sgblack@eecs.umich.edusc_uint_subref & 2503536Sgblack@eecs.umich.edusc_uint_subref::operator = (uint_type v) 2513536Sgblack@eecs.umich.edu{ 2523536Sgblack@eecs.umich.edu uint_type val = m_obj_p->m_val; 2537720Sgblack@eecs.umich.edu uint_type mask = mask_int[m_left][m_right]; 2544060Ssaidi@eecs.umich.edu val &= mask; 2553536Sgblack@eecs.umich.edu val |= (v << m_right) & ~mask; 256 m_obj_p->m_val = val; 257 m_obj_p->extend_sign(); 258 return *this; 259} 260 261sc_uint_subref & 262sc_uint_subref::operator = (const sc_signed &a) 263{ 264 sc_uint_base aa(length()); 265 return (*this = aa = a); 266} 267 268sc_uint_subref & 269sc_uint_subref::operator = (const sc_unsigned &a) 270{ 271 sc_uint_base aa(length()); 272 return (*this = aa = a); 273} 274 275sc_uint_subref & 276sc_uint_subref::operator = (const sc_bv_base &a) 277{ 278 sc_uint_base aa(length()); 279 return (*this = aa = a); 280} 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