1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 sc_uint_base.h -- An unsigned integer whose length is less than 64 bits. 23 24 Unlike arbitrary precision, arithmetic and bitwise operations 25 are performed using the native types (hence capped at 64 bits). 26 The sc_uint integer is useful when the user does not need 27 arbitrary precision and the performance is superior to 28 sc_bigint/sc_biguint. 29 30 Original Author: Amit Rao, Synopsys, Inc. 31 32 *****************************************************************************/ 33 34/***************************************************************************** 35 36 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 37 changes you are making here. 38 39 Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. 40 Description of Modification: - Resolved ambiguity with sc_(un)signed. 41 - Merged the code for 64- and 32-bit versions 42 via the constants in sc_nbdefs.h. 43 - Eliminated redundant file inclusions. 44 45 Name, Affiliation, Date: 46 Description of Modification: 47 48 *****************************************************************************/ 49 50// $Log: sc_uint_base.h,v $ 51// Revision 1.3 2011/08/24 22:05:46 acg 52// Torsten Maehne: initialization changes to remove warnings. 53// 54// Revision 1.2 2011/02/18 20:19:15 acg 55// Andy Goodrich: updating Copyright notice. 56// 57// Revision 1.1.1.1 2006/12/15 20:20:05 acg 58// SystemC 2.3 59// 60// Revision 1.4 2006/05/08 17:50:02 acg 61// Andy Goodrich: Added David Long's declarations for friend operators, 62// functions, and methods, to keep the Microsoft compiler happy. 63// 64// Revision 1.3 2006/01/13 18:49:32 acg 65// Added $Log command so that CVS check in comments are reproduced in the 66// source. 67// 68 69#ifndef __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ 70#define __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ 71 72#include <iostream> 73 74#include "../fx/scfx_ieee.hh" 75#include "../misc/sc_value_base.hh" 76#include "../sc_temporary.hh" 77#include "sc_length_param.hh" 78#include "sc_nbdefs.hh" 79 80namespace sc_dt 81{ 82 83class sc_concatref; 84 85// classes defined in this module 86class sc_uint_bitref_r; 87class sc_uint_bitref; 88class sc_uint_subref_r; 89class sc_uint_subref; 90class sc_uint_base; 91 92// forward class declarations 93class sc_bv_base; 94class sc_lv_base; 95class sc_int_subref_r; 96class sc_signed_subref_r; 97class sc_unsigned_subref_r; 98class sc_signed; 99class sc_unsigned; 100class sc_fxval; 101class sc_fxval_fast; 102class sc_fxnum; 103class sc_fxnum_fast; 104 105} // namespace sc_dt 106 107// extern template instantiations 108namespace sc_core 109{ 110 111extern template class sc_vpool<sc_dt::sc_uint_bitref>; 112extern template class sc_vpool<sc_dt::sc_uint_subref>; 113 114} // namespace sc_core 115 116namespace sc_dt 117{ 118 119extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; 120 121// friend operator declarations 122inline bool operator == (const sc_uint_base &a, const sc_uint_base &b); 123inline bool operator != (const sc_uint_base &a, const sc_uint_base &b); 124inline bool operator < (const sc_uint_base &a, const sc_uint_base &b); 125inline bool operator <= (const sc_uint_base &a, const sc_uint_base &b); 126inline bool operator > (const sc_uint_base &a, const sc_uint_base &b); 127inline bool operator >= (const sc_uint_base &a, const sc_uint_base &b); 128 129 130// ---------------------------------------------------------------------------- 131// CLASS : sc_uint_bitref_r 132// 133// Proxy class for sc_uint bit selection (r-value only). 134// ---------------------------------------------------------------------------- 135 136class sc_uint_bitref_r : public sc_value_base 137{ 138 friend class sc_uint_base; 139 friend class sc_uint_signal; 140 141 // constructors 142 public: 143 sc_uint_bitref_r(const sc_uint_bitref_r &init) : 144 sc_value_base(init), m_index(init.m_index), m_obj_p(init.m_obj_p) 145 {} 146 147 protected: 148 sc_uint_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {} 149 150 // initializer for sc_core::sc_vpool: 151 void 152 initialize(const sc_uint_base* obj_p, int index_) 153 { 154 m_obj_p = (sc_uint_base *)obj_p; 155 m_index = index_; 156 } 157 158 public: 159 // destructor 160 virtual ~sc_uint_bitref_r() {} 161 162 // concatenation support 163 virtual int 164 concat_length(bool *xz_present_p) const 165 { 166 if (xz_present_p) 167 *xz_present_p = false; 168 return 1; 169 } 170 virtual bool 171 concat_get_ctrl(sc_digit *dst_p, int low_i) const 172 { 173 int bit_mask = 1 << (low_i % BITS_PER_DIGIT); 174 int word_i = low_i / BITS_PER_DIGIT; 175 176 dst_p[word_i] &= ~bit_mask; 177 return false; 178 } 179 virtual bool 180 concat_get_data(sc_digit *dst_p, int low_i) const 181 { 182 int bit_mask = 1 << (low_i % BITS_PER_DIGIT); 183 bool result; // True is non-zero. 184 int word_i = low_i / BITS_PER_DIGIT; 185 186 if (operator uint64()) { 187 dst_p[word_i] |= bit_mask; 188 result = true; 189 } else { 190 dst_p[word_i] &= ~bit_mask; 191 result = false; 192 } 193 return result; 194 } 195 virtual uint64 concat_get_uint64() const { return operator uint64(); } 196 197 // capacity 198 int length() const { return 1; } 199 200 // implicit conversion to uint64 201 operator uint64 () const; 202 bool operator ! () const; 203 bool operator ~ () const; 204 205 // explicit conversions 206 uint64 value() const { return operator uint64 (); } 207 bool to_bool() const { return operator uint64 (); } 208 209 // other methods 210 void print(::std::ostream &os=::std::cout) const { os << to_bool(); } 211 212 protected: 213 int m_index; 214 sc_uint_base *m_obj_p; 215 216 private: 217 // Disabled 218 sc_uint_bitref_r &operator = (const sc_uint_bitref_r &); 219}; 220 221inline ::std::ostream &operator << ( 222 ::std::ostream &, const sc_uint_bitref_r &); 223 224 225// ---------------------------------------------------------------------------- 226// CLASS : sc_uint_bitref 227// 228// Proxy class for sc_uint bit selection (r-value and l-value). 229// ---------------------------------------------------------------------------- 230 231class sc_uint_bitref : public sc_uint_bitref_r 232{ 233 friend class sc_uint_base; 234 friend class sc_core::sc_vpool<sc_uint_bitref>; 235 236 // constructors 237 protected: 238 sc_uint_bitref() : sc_uint_bitref_r() {} 239 240 public: 241 sc_uint_bitref(const sc_uint_bitref &init) : sc_uint_bitref_r(init) {} 242 243 public: 244 // assignment operators 245 sc_uint_bitref &operator = (const sc_uint_bitref_r &b); 246 sc_uint_bitref &operator = (const sc_uint_bitref &b); 247 sc_uint_bitref &operator = (bool b); 248 249 sc_uint_bitref &operator &= (bool b); 250 sc_uint_bitref &operator |= (bool b); 251 sc_uint_bitref &operator ^= (bool b); 252 253 // concatenation methods 254 virtual void concat_set(int64 src, int low_i); 255 virtual void concat_set(const sc_signed &src, int low_i); 256 virtual void concat_set(const sc_unsigned &src, int low_i); 257 virtual void concat_set(uint64 src, int low_i); 258 259 // other methods 260 void scan(::std::istream &is=::std::cin); 261 262 protected: 263 static sc_core::sc_vpool<sc_uint_bitref> m_pool; 264}; 265 266inline ::std::istream &operator >> (::std::istream &, sc_uint_bitref &); 267 268 269// ---------------------------------------------------------------------------- 270// CLASS : sc_uint_subref_r 271// 272// Proxy class for sc_uint part selection (r-value only). 273// ---------------------------------------------------------------------------- 274 275class sc_uint_subref_r : public sc_value_base 276{ 277 friend class sc_uint_base; 278 friend class sc_uint_subref; 279 280 // constructors 281 public: 282 sc_uint_subref_r( const sc_uint_subref_r& init ) : 283 sc_value_base(init), m_left(init.m_left), m_obj_p(init.m_obj_p), 284 m_right(init.m_right) 285 {} 286 287 protected: 288 sc_uint_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {} 289 290 // initializer for sc_core::sc_vpool: 291 void 292 initialize(const sc_uint_base *obj_p, int left_i, int right_i) 293 { 294 m_obj_p = (sc_uint_base *)obj_p; 295 m_left = left_i; 296 m_right = right_i; 297 } 298 299 public: 300 // destructor 301 virtual ~sc_uint_subref_r() {} 302 303 // capacity 304 int length() const { return (m_left - m_right + 1); } 305 306 // concatenation support 307 virtual int 308 concat_length(bool *xz_present_p) const 309 { 310 if (xz_present_p) 311 *xz_present_p = false; 312 return length(); 313 } 314 virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; 315 virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; 316 virtual uint64 317 concat_get_uint64() const 318 { 319 return (uint64)operator uint_type(); 320 } 321 322 // reduce methods 323 bool and_reduce() const; 324 bool nand_reduce() const { return !and_reduce(); } 325 bool or_reduce() const; 326 bool nor_reduce() const { return !or_reduce(); } 327 bool xor_reduce() const; 328 bool xnor_reduce() const { return !xor_reduce(); } 329 330 // implicit conversion to uint_type 331 operator uint_type() const; 332 333 // explicit conversions 334 uint_type value() const { return operator uint_type(); } 335 336 int to_int() const; 337 unsigned int to_uint() const; 338 long to_long() const; 339 unsigned long to_ulong() const; 340 int64 to_int64() const; 341 uint64 to_uint64() const; 342 double to_double() const; 343 344 // explicit conversion to character string 345 const std::string to_string(sc_numrep numrep=SC_DEC) const; 346 const std::string to_string(sc_numrep numrep, bool w_prefix) const; 347 348 // other methods 349 void 350 print(::std::ostream &os=::std::cout) const 351 { 352 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); 353 } 354 355 protected: 356 int m_left; 357 sc_uint_base *m_obj_p; 358 int m_right; 359 360 private: 361 // Disabled 362 sc_uint_subref_r &operator = (const sc_uint_subref_r &); 363}; 364 365inline ::std::ostream &operator << ( 366 ::std::ostream &, const sc_uint_subref_r &); 367 368 369// ---------------------------------------------------------------------------- 370// CLASS : sc_uint_subref 371// 372// Proxy class for sc_uint part selection (r-value and l-value). 373// ---------------------------------------------------------------------------- 374 375class sc_uint_subref : public sc_uint_subref_r 376{ 377 friend class sc_uint_base; 378 friend class sc_core::sc_vpool<sc_uint_subref>; 379 380 // constructors 381 protected: 382 sc_uint_subref() : sc_uint_subref_r() {} 383 384 public: 385 sc_uint_subref(const sc_uint_subref &init) : sc_uint_subref_r(init) {} 386 387 public: 388 // assignment operators 389 sc_uint_subref &operator = (uint_type v); 390 sc_uint_subref &operator = (const sc_uint_base &a); 391 sc_uint_subref & 392 operator = (const sc_uint_subref_r &a) 393 { 394 return operator = (a.operator uint_type()); 395 } 396 sc_uint_subref & 397 operator = (const sc_uint_subref &a) 398 { 399 return operator = (a.operator uint_type()); 400 } 401 template<class T> 402 sc_uint_subref & 403 operator = (const sc_generic_base<T> &a) 404 { 405 return operator = (a->to_uint64()); 406 } 407 sc_uint_subref &operator = (const char *a); 408 sc_uint_subref & 409 operator = (unsigned long a) 410 { 411 return operator = ((uint_type)a); 412 } 413 sc_uint_subref & 414 operator = (long a) 415 { 416 return operator = ((uint_type)a); 417 } 418 sc_uint_subref & 419 operator = (unsigned int a) 420 { 421 return operator = ((uint_type)a); 422 } 423 sc_uint_subref & 424 operator = (int a) 425 { 426 return operator = ((uint_type)a); 427 } 428 sc_uint_subref & 429 operator = (int64 a) 430 { 431 return operator = ((uint_type)a); 432 } 433 sc_uint_subref & 434 operator = (double a) 435 { 436 return operator = ((uint_type)a); 437 } 438 sc_uint_subref &operator = (const sc_signed &); 439 sc_uint_subref &operator = (const sc_unsigned &); 440 sc_uint_subref &operator = (const sc_bv_base &); 441 sc_uint_subref &operator = (const sc_lv_base &); 442 443 // concatenation methods 444 virtual void concat_set(int64 src, int low_i); 445 virtual void concat_set(const sc_signed &src, int low_i); 446 virtual void concat_set(const sc_unsigned &src, int low_i); 447 virtual void concat_set(uint64 src, int low_i); 448 449 // other methods 450 void scan(::std::istream &is=::std::cin); 451 452 protected: 453 static sc_core::sc_vpool<sc_uint_subref> m_pool; 454}; 455 456inline ::std::istream &operator >> (::std::istream &, sc_uint_subref &); 457 458 459// ---------------------------------------------------------------------------- 460// CLASS : sc_uint_base 461// 462// Base class for sc_uint. 463// ---------------------------------------------------------------------------- 464 465class sc_uint_base : public sc_value_base 466{ 467 friend class sc_uint_bitref_r; 468 friend class sc_uint_bitref; 469 friend class sc_uint_subref_r; 470 friend class sc_uint_subref; 471 472 // support methods 473 void invalid_length() const; 474 void invalid_index(int i) const; 475 void invalid_range(int l, int r) const; 476 477 void 478 check_length() const 479 { 480 if (m_len <= 0 || m_len > SC_INTWIDTH) { 481 invalid_length(); 482 } 483 } 484 485 void 486 check_index(int i) const 487 { 488 if (i < 0 || i >= m_len) { 489 invalid_index( i ); 490 } 491 } 492 493 void 494 check_range(int l, int r) const 495 { 496 if (r < 0 || l >= m_len || l < r) { 497 invalid_range( l, r ); 498 } 499 } 500 501 void check_value() const; 502 503 void 504 extend_sign() 505 { 506#ifdef DEBUG_SYSTEMC 507 check_value(); 508#endif 509 m_val &= (~UINT_ZERO >> m_ulen); 510 } 511 512 public: 513 // constructors 514 explicit sc_uint_base(int w=sc_length_param().len()) : 515 m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len) 516 { 517 check_length(); 518 } 519 520 sc_uint_base(uint_type v, int w) : 521 m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len) 522 { 523 check_length(); 524 extend_sign(); 525 } 526 527 sc_uint_base(const sc_uint_base &a) : 528 sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) 529 {} 530 531 explicit sc_uint_base(const sc_uint_subref_r &a) : 532 m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len) 533 { 534 extend_sign(); 535 } 536 537 template<class T> 538 explicit sc_uint_base(const sc_generic_base<T> &a) : 539 m_val(a->to_uint64()), m_len(a->length()), 540 m_ulen(SC_INTWIDTH - m_len) 541 { 542 check_length(); 543 extend_sign(); 544 } 545 546 explicit sc_uint_base(const sc_bv_base &v); 547 explicit sc_uint_base(const sc_lv_base &v); 548 explicit sc_uint_base(const sc_int_subref_r &v); 549 explicit sc_uint_base(const sc_signed_subref_r &v); 550 explicit sc_uint_base(const sc_unsigned_subref_r &v); 551 explicit sc_uint_base(const sc_signed &a); 552 explicit sc_uint_base(const sc_unsigned &a); 553 554 // destructor 555 virtual ~sc_uint_base() {} 556 557 // assignment operators 558 sc_uint_base & 559 operator = (uint_type v) 560 { 561 m_val = v; 562 extend_sign(); 563 return *this; 564 } 565 sc_uint_base & 566 operator = (const sc_uint_base &a) 567 { 568 m_val = a.m_val; 569 extend_sign(); 570 return *this; 571 } 572 sc_uint_base & 573 operator = (const sc_uint_subref_r &a) 574 { 575 m_val = a; 576 extend_sign(); 577 return *this; 578 } 579 template<class T> 580 sc_uint_base & 581 operator = (const sc_generic_base<T> &a) 582 { 583 m_val = a->to_uint64(); 584 extend_sign(); 585 return *this; 586 } 587 sc_uint_base &operator = (const sc_signed &a); 588 sc_uint_base &operator = (const sc_unsigned &a); 589 sc_uint_base &operator = (const sc_fxval &a); 590 sc_uint_base &operator = (const sc_fxval_fast &a); 591 sc_uint_base &operator = (const sc_fxnum &a); 592 sc_uint_base &operator = (const sc_fxnum_fast &a); 593 sc_uint_base &operator = (const sc_bv_base &a); 594 sc_uint_base &operator = (const sc_lv_base &a); 595 sc_uint_base &operator = (const char *a); 596 sc_uint_base & 597 operator = (unsigned long a) 598 { 599 m_val = a; 600 extend_sign(); 601 return *this; 602 } 603 sc_uint_base & 604 operator = (long a) 605 { 606 m_val = a; 607 extend_sign(); 608 return *this; 609 } 610 sc_uint_base & 611 operator = (unsigned int a) 612 { 613 m_val = a; 614 extend_sign(); 615 return *this; 616 } 617 sc_uint_base & 618 operator = (int a) 619 { 620 m_val = a; 621 extend_sign(); 622 return *this; 623 } 624 sc_uint_base & 625 operator = (int64 a) 626 { 627 m_val = a; 628 extend_sign(); 629 return *this; 630 } 631 sc_uint_base & 632 operator = (double a) 633 { 634 m_val = (uint_type)a; 635 extend_sign(); 636 return *this; 637 } 638 639 // arithmetic assignment operators 640 sc_uint_base & 641 operator += (uint_type v) 642 { 643 m_val += v; 644 extend_sign(); 645 return *this; 646 } 647 sc_uint_base & 648 operator -= (uint_type v) 649 { 650 m_val -= v; 651 extend_sign(); 652 return *this; 653 } 654 sc_uint_base & 655 operator *= (uint_type v) 656 { 657 m_val *= v; 658 extend_sign(); 659 return *this; 660 } 661 sc_uint_base & 662 operator /= (uint_type v) 663 { 664 m_val /= v; 665 extend_sign(); 666 return *this; 667 } 668 sc_uint_base & 669 operator %= (uint_type v) 670 { 671 m_val %= v; 672 extend_sign(); 673 return *this; 674 } 675 676 // bitwise assignment operators 677 sc_uint_base & 678 operator &= (uint_type v) 679 { 680 m_val &= v; 681 extend_sign(); 682 return *this; 683 } 684 sc_uint_base & 685 operator |= (uint_type v) 686 { 687 m_val |= v; 688 extend_sign(); 689 return *this; 690 } 691 sc_uint_base & 692 operator ^= (uint_type v) 693 { 694 m_val ^= v; 695 extend_sign(); 696 return *this; 697 } 698 sc_uint_base & 699 operator <<= (uint_type v) 700 { 701 m_val <<= v; 702 extend_sign(); 703 return *this; 704 } 705 sc_uint_base & 706 operator >>= (uint_type v) 707 { 708 m_val >>= v; 709 /* no sign extension needed */ 710 return *this; 711 } 712 713 // prefix and postfix increment and decrement operators 714 sc_uint_base & 715 operator ++ () // prefix 716 { 717 ++m_val; 718 extend_sign(); 719 return *this; 720 } 721 const sc_uint_base 722 operator ++ (int) // postfix 723 { 724 sc_uint_base tmp(*this); 725 ++m_val; 726 extend_sign(); 727 return tmp; 728 } 729 730 sc_uint_base & 731 operator -- () // prefix 732 { 733 --m_val; 734 extend_sign(); 735 return *this; 736 } 737 const sc_uint_base 738 operator -- (int) // postfix 739 { 740 sc_uint_base tmp(*this); 741 --m_val; 742 extend_sign(); 743 return tmp; 744 } 745 746 // relational operators 747 friend bool 748 operator == (const sc_uint_base &a, const sc_uint_base &b) 749 { 750 return a.m_val == b.m_val; 751 } 752 friend bool 753 operator != (const sc_uint_base &a, const sc_uint_base &b) 754 { 755 return a.m_val != b.m_val; 756 } 757 friend bool 758 operator < (const sc_uint_base &a, const sc_uint_base &b) 759 { 760 return a.m_val < b.m_val; 761 } 762 friend bool 763 operator <= (const sc_uint_base &a, const sc_uint_base &b) 764 { 765 return a.m_val <= b.m_val; 766 } 767 friend bool 768 operator > (const sc_uint_base &a, const sc_uint_base &b) 769 { 770 return a.m_val > b.m_val; 771 } 772 friend bool 773 operator >= (const sc_uint_base &a, const sc_uint_base &b) 774 { 775 return a.m_val >= b.m_val; 776 } 777 778 // bit selection 779 sc_uint_bitref &operator [] (int i); 780 const sc_uint_bitref_r &operator [] (int i) const; 781 782 sc_uint_bitref &bit(int i); 783 const sc_uint_bitref_r &bit(int i) const; 784 785 // part selection 786 sc_uint_subref &operator () (int left, int right); 787 const sc_uint_subref_r &operator () (int left, int right) const; 788 789 sc_uint_subref &range(int left, int right); 790 const sc_uint_subref_r &range(int left, int right) const; 791 792 // bit access, without bounds checking or sign extension 793 bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); } 794 795 void set(int i) { m_val |= (UINT_ONE << i); } 796 void 797 set(int i, bool v) 798 { 799 v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); 800 } 801 802 // capacity 803 int length() const { return m_len; } 804 805 // concatenation support 806 virtual int 807 concat_length(bool *xz_present_p) const 808 { 809 if (xz_present_p) 810 *xz_present_p = false; 811 return length(); 812 } 813 virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; 814 virtual bool concat_get_data( sc_digit *dst_p, int low_i) const; 815 virtual uint64 concat_get_uint64() const { return m_val; } 816 virtual void concat_set(int64 src, int low_i); 817 virtual void concat_set(const sc_signed &src, int low_i); 818 virtual void concat_set(const sc_unsigned &src, int low_i); 819 virtual void concat_set(uint64 src, int low_i); 820 821 // reduce methods 822 bool and_reduce() const; 823 bool nand_reduce() const { return !and_reduce(); } 824 bool or_reduce() const; 825 bool nor_reduce() const { return !or_reduce(); } 826 bool xor_reduce() const; 827 bool xnor_reduce() const { return !xor_reduce(); } 828 829 // implicit conversion to uint_type 830 operator uint_type() const { return m_val; } 831 832 // explicit conversions 833 uint_type value() const { return operator uint_type(); } 834 835 int to_int() const { return (int) m_val; } 836 unsigned int to_uint() const { return (unsigned int)m_val; } 837 long to_long() const { return (long)m_val; } 838 unsigned long to_ulong() const { return (unsigned long)m_val; } 839 int64 to_int64() const { return (int64)m_val; } 840 uint64 to_uint64() const { return (uint64)m_val; } 841 double to_double() const { return uint64_to_double(m_val); } 842 843 long long_low() const { return (long)(m_val & UINT64_32ONES); } 844 long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); } 845 846 // explicit conversion to character string 847 const std::string to_string(sc_numrep numrep=SC_DEC) const; 848 const std::string to_string(sc_numrep numrep, bool w_prefix) const; 849 850 // other methods 851 void 852 print(::std::ostream &os=::std::cout) const 853 { 854 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); 855 } 856 857 void scan(::std::istream &is=::std::cin); 858 859 protected: 860 uint_type m_val; // value 861 int m_len; // length 862 int m_ulen; // unused length 863}; 864 865inline ::std::ostream &operator << (::std::ostream &, const sc_uint_base &); 866inline ::std::istream &operator >> (::std::istream &, sc_uint_base &); 867 868 869// ---------------------------------------------------------------------------- 870// CLASS : sc_uint_bitref_r 871// 872// Proxy class for sc_uint bit selection (r-value only). 873// ---------------------------------------------------------------------------- 874 875// implicit conversion to bool 876 877inline sc_uint_bitref_r::operator uint64 () const 878{ 879 return m_obj_p->test(m_index); 880} 881 882inline bool 883sc_uint_bitref_r::operator ! () const 884{ 885 return !m_obj_p->test(m_index); 886} 887 888inline bool 889sc_uint_bitref_r::operator ~ () const 890{ 891 return !m_obj_p->test(m_index); 892} 893 894inline ::std::ostream & 895operator << (::std::ostream &os, const sc_uint_bitref_r &a) 896{ 897 a.print(os); 898 return os; 899} 900 901 902// ---------------------------------------------------------------------------- 903// CLASS : sc_uint_bitref 904// 905// Proxy class for sc_uint bit selection (r-value and l-value). 906// ---------------------------------------------------------------------------- 907 908// assignment operators 909 910inline sc_uint_bitref & 911sc_uint_bitref::operator = (const sc_uint_bitref_r &b) 912{ 913 m_obj_p->set(m_index, b.to_bool()); 914 return *this; 915} 916 917inline sc_uint_bitref & 918sc_uint_bitref::operator = (const sc_uint_bitref &b) 919{ 920 m_obj_p->set(m_index, b.to_bool()); 921 return *this; 922} 923 924inline sc_uint_bitref & 925sc_uint_bitref::operator = (bool b) 926{ 927 m_obj_p->set(m_index, b); 928 return *this; 929} 930 931inline sc_uint_bitref & 932sc_uint_bitref::operator &= (bool b) 933{ 934 if (!b) { 935 m_obj_p->set(m_index, b); 936 } 937 return *this; 938} 939 940inline sc_uint_bitref & 941sc_uint_bitref::operator |= (bool b) 942{ 943 if (b) { 944 m_obj_p->set(m_index, b); 945 } 946 return *this; 947} 948 949inline sc_uint_bitref & 950sc_uint_bitref::operator ^= (bool b) 951{ 952 if (b) { 953 m_obj_p->m_val ^= (UINT_ONE << m_index); 954 } 955 return *this; 956} 957 958inline ::std::istream & 959operator >> (::std::istream &is, sc_uint_bitref &a) 960{ 961 a.scan(is); 962 return is; 963} 964 965 966// ---------------------------------------------------------------------------- 967// CLASS : sc_uint_subref_r 968// 969// Proxy class for sc_uint part selection (r-value only). 970// ---------------------------------------------------------------------------- 971 972// implicit conversion to uint_type 973 974inline sc_uint_subref_r::operator uint_type() const 975{ 976 uint_type val = m_obj_p->m_val; 977 int uleft = SC_INTWIDTH - (m_left + 1); 978 return ((val & (~UINT_ZERO >> uleft)) >> m_right); 979} 980 981 982// reduce methods 983inline bool 984sc_uint_subref_r::and_reduce() const 985{ 986 sc_uint_base a(*this); 987 return a.and_reduce(); 988} 989inline bool 990sc_uint_subref_r::or_reduce() const 991{ 992 sc_uint_base a(*this); 993 return a.or_reduce(); 994} 995inline bool 996sc_uint_subref_r::xor_reduce() const 997{ 998 sc_uint_base a(*this); 999 return a.xor_reduce(); 1000} 1001 1002// explicit conversions 1003inline int 1004sc_uint_subref_r::to_int() const 1005{ 1006 sc_uint_base a(*this); 1007 return a.to_int(); 1008} 1009inline unsigned int 1010sc_uint_subref_r::to_uint() const 1011{ 1012 sc_uint_base a(*this); 1013 return a.to_uint(); 1014} 1015inline long 1016sc_uint_subref_r::to_long() const 1017{ 1018 sc_uint_base a(*this); 1019 return a.to_long(); 1020} 1021inline unsigned long 1022sc_uint_subref_r::to_ulong() const 1023{ 1024 sc_uint_base a(*this); 1025 return a.to_ulong(); 1026} 1027inline int64 1028sc_uint_subref_r::to_int64() const 1029{ 1030 sc_uint_base a(*this); 1031 return a.to_int64(); 1032} 1033inline uint64 1034sc_uint_subref_r::to_uint64() const 1035{ 1036 sc_uint_base a(*this); 1037 return a.to_uint64(); 1038} 1039inline double 1040sc_uint_subref_r::to_double() const 1041{ 1042 sc_uint_base a(*this); 1043 return a.to_double(); 1044} 1045 1046// explicit conversion to character string 1047inline const std::string 1048sc_uint_subref_r::to_string(sc_numrep numrep) const 1049{ 1050 sc_uint_base a(*this); 1051 return a.to_string(numrep); 1052} 1053 1054inline const std::string 1055sc_uint_subref_r::to_string(sc_numrep numrep, bool w_prefix) const 1056{ 1057 sc_uint_base a(*this); 1058 return a.to_string(numrep, w_prefix); 1059} 1060 1061// functional notation for the reduce methods 1062inline bool 1063and_reduce(const sc_uint_subref_r &a) 1064{ 1065 return a.and_reduce(); 1066} 1067inline bool 1068nand_reduce(const sc_uint_subref_r &a) 1069{ 1070 return a.nand_reduce(); 1071} 1072inline bool 1073or_reduce(const sc_uint_subref_r &a) 1074{ 1075 return a.or_reduce(); 1076} 1077inline bool 1078nor_reduce(const sc_uint_subref_r &a) 1079{ 1080 return a.nor_reduce(); 1081} 1082inline bool 1083xor_reduce(const sc_uint_subref_r &a) 1084{ 1085 return a.xor_reduce(); 1086} 1087inline bool 1088xnor_reduce(const sc_uint_subref_r &a) 1089{ 1090 return a.xnor_reduce(); 1091} 1092 1093inline ::std::ostream & 1094operator << (::std::ostream &os, const sc_uint_subref_r &a) 1095{ 1096 a.print(os); 1097 return os; 1098} 1099 1100 1101// ---------------------------------------------------------------------------- 1102// CLASS : sc_uint_subref 1103// 1104// Proxy class for sc_uint part selection (r-value and l-value). 1105// ---------------------------------------------------------------------------- 1106 1107// assignment operators 1108 1109inline sc_uint_subref & 1110sc_uint_subref::operator = (const sc_uint_base &a) 1111{ 1112 return operator = (a.operator uint_type()); 1113} 1114 1115inline sc_uint_subref & 1116sc_uint_subref::operator = (const char *a) 1117{ 1118 sc_uint_base aa(length()); 1119 return (*this = aa = a); 1120} 1121 1122inline ::std::istream & 1123operator >> (::std::istream &is, sc_uint_subref &a) 1124{ 1125 a.scan(is); 1126 return is; 1127} 1128 1129 1130// ---------------------------------------------------------------------------- 1131// CLASS : sc_uint_base 1132// 1133// Base class for sc_uint. 1134// ---------------------------------------------------------------------------- 1135 1136// bit selection 1137inline sc_uint_bitref & 1138sc_uint_base::operator [] (int i) 1139{ 1140 check_index(i); 1141 sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); 1142 result_p->initialize(this, i); 1143 return *result_p; 1144} 1145 1146inline const sc_uint_bitref_r & 1147sc_uint_base::operator [] (int i) const 1148{ 1149 check_index(i); 1150 sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); 1151 result_p->initialize(this, i); 1152 return *result_p; 1153} 1154 1155inline sc_uint_bitref & 1156sc_uint_base::bit(int i) 1157{ 1158 check_index(i); 1159 sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); 1160 result_p->initialize(this, i); 1161 return *result_p; 1162} 1163 1164inline const sc_uint_bitref_r & 1165sc_uint_base::bit(int i) const 1166{ 1167 check_index(i); 1168 sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); 1169 result_p->initialize(this, i); 1170 return *result_p; 1171} 1172 1173// part selection 1174inline sc_uint_subref & 1175sc_uint_base::operator () (int left, int right) 1176{ 1177 check_range(left, right); 1178 sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); 1179 result_p->initialize(this, left, right); 1180 return *result_p; 1181} 1182 1183inline const sc_uint_subref_r & 1184sc_uint_base::operator () (int left, int right) const 1185{ 1186 check_range(left, right); 1187 sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); 1188 result_p->initialize(this, left, right); 1189 return *result_p; 1190} 1191 1192inline sc_uint_subref & 1193sc_uint_base::range(int left, int right) 1194{ 1195 check_range(left, right); 1196 sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); 1197 result_p->initialize(this, left, right); 1198 return *result_p; 1199} 1200 1201inline const sc_uint_subref_r & 1202sc_uint_base::range(int left, int right) const 1203{ 1204 check_range(left, right); 1205 sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); 1206 result_p->initialize(this, left, right); 1207 return *result_p; 1208} 1209 1210// functional notation for the reduce methods 1211inline bool 1212and_reduce(const sc_uint_base &a) 1213{ 1214 return a.and_reduce(); 1215} 1216inline bool 1217nand_reduce(const sc_uint_base &a) 1218{ 1219 return a.nand_reduce(); 1220} 1221inline bool 1222or_reduce(const sc_uint_base &a) 1223{ 1224 return a.or_reduce(); 1225} 1226inline bool 1227nor_reduce(const sc_uint_base &a) 1228{ 1229 return a.nor_reduce(); 1230} 1231inline bool 1232xor_reduce(const sc_uint_base &a) 1233{ 1234 return a.xor_reduce(); 1235} 1236inline bool 1237xnor_reduce(const sc_uint_base &a) 1238{ 1239 return a.xnor_reduce(); 1240} 1241 1242inline ::std::ostream & 1243operator << (::std::ostream &os, const sc_uint_base &a) 1244{ 1245 a.print(os); 1246 return os; 1247} 1248 1249inline ::std::istream & 1250operator >> (::std::istream &is, sc_uint_base &a) 1251{ 1252 a.scan(is); 1253 return is; 1254} 1255 1256} // namespace sc_dt 1257 1258#endif // __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ 1259