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_int_base.h -- A signed integer whose length is less than 64 bit. 23 24 Unlike arbitrary precision, arithmetic and bitwise operations 25 are performed using the native types (hence capped at 64 bits). 26 The sc_int 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_int_base.h,v $ 51// Revision 1.3 2011/08/24 22:05:45 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:01 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:31 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_INT_BASE_HH__ 70#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ 71 72#include <iostream> 73 74#include "../misc/sc_value_base.hh" 75#include "../sc_temporary.hh" 76#include "sc_length_param.hh" 77#include "sc_nbdefs.hh" 78#include "sc_uint_base.hh" 79 80namespace sc_dt 81{ 82 83class sc_concatref; 84 85// classes defined in this module 86class sc_int_bitref_r; 87class sc_int_bitref; 88class sc_int_subref_r; 89class sc_int_subref; 90class sc_int_base; 91class sc_signed_subref_r; 92class sc_unsigned_subref_r; 93 94// forward class declarations 95class sc_bv_base; 96class sc_lv_base; 97class sc_signed; 98class sc_unsigned; 99class sc_fxval; 100class sc_fxval_fast; 101class sc_fxnum; 102class sc_fxnum_fast; 103 104} // namespace sc_dt 105 106// extern template instantiations 107namespace sc_core 108{ 109 110extern template class sc_vpool<sc_dt::sc_int_bitref>; 111extern template class sc_vpool<sc_dt::sc_int_subref>; 112 113} // namespace sc_core 114 115namespace sc_dt 116{ 117 118extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; 119 120// friend operator declarations 121 122// relational operators 123 124inline bool operator == (const sc_int_base &a, const sc_int_base &b); 125inline bool operator != (const sc_int_base &a, const sc_int_base &b); 126inline bool operator < (const sc_int_base &a, const sc_int_base &b); 127inline bool operator <= (const sc_int_base &a, const sc_int_base &b); 128inline bool operator > (const sc_int_base &a, const sc_int_base &b); 129inline bool operator >= (const sc_int_base &a, const sc_int_base &b); 130 131 132// ---------------------------------------------------------------------------- 133// CLASS : sc_int_bitref_r 134// 135// Proxy class for sc_int bit selection (r-value only). 136// ---------------------------------------------------------------------------- 137 138class sc_int_bitref_r : public sc_value_base 139{ 140 friend class sc_int_base; 141 142 protected: 143 // constructor 144 sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {} 145 146 // initializer for sc_core::sc_vpool: 147 void initialize(const sc_int_base *obj_p, int index_) 148 { 149 m_obj_p = (sc_int_base *)obj_p; 150 m_index = index_; 151 } 152 153 public: 154 // copy constructor 155 sc_int_bitref_r(const sc_int_bitref_r &a) : 156 sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) 157 {} 158 159 // destructor 160 virtual ~sc_int_bitref_r() {} 161 162 // capacity 163 int length() const { return 1; } 164 165#ifdef SC_DT_DEPRECATED 166 int bitwidth() const { return length(); } 167#endif 168 169 // concatenation support 170 virtual int 171 concat_length(bool *xz_present_p) const 172 { 173 if (xz_present_p) 174 *xz_present_p = false; 175 return 1; 176 } 177 virtual bool 178 concat_get_ctrl(sc_digit *dst_p, int low_i) const 179 { 180 int bit_mask = 1 << (low_i % BITS_PER_DIGIT); 181 int word_i = low_i / BITS_PER_DIGIT; 182 183 dst_p[word_i] &= ~bit_mask; 184 return false; 185 } 186 virtual bool 187 concat_get_data(sc_digit *dst_p, int low_i) const 188 { 189 bool non_zero; 190 int bit_mask = 1 << (low_i % BITS_PER_DIGIT); 191 int word_i = low_i / BITS_PER_DIGIT; 192 193 if (operator uint64()) { 194 dst_p[word_i] |= bit_mask; 195 non_zero = true; 196 } else { 197 dst_p[word_i] &= ~bit_mask; 198 non_zero = false; 199 } 200 return non_zero; 201 } 202 virtual uint64 203 concat_get_uint64() const 204 { 205 return operator uint64(); 206 } 207 208 209 // implicit conversions 210 operator uint64 () const; 211 bool operator ! () const; 212 bool operator ~ () const; 213 214 215 // explicit conversions 216 uint64 value() const { return operator uint64(); } 217 218 bool to_bool() const { return operator uint64(); } 219 220 221 // other methods 222 void print(::std::ostream& os=::std::cout) const { os << to_bool(); } 223 224 protected: 225 int m_index; 226 sc_int_base *m_obj_p; 227 228 private: 229 // Disabled 230 sc_int_bitref_r &operator = (const sc_int_bitref_r &); 231}; 232 233 234inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &); 235 236 237// ---------------------------------------------------------------------------- 238// CLASS : sc_int_bitref 239// 240// Proxy class for sc_int bit selection (r-value and l-value). 241// ---------------------------------------------------------------------------- 242 243class sc_int_bitref : public sc_int_bitref_r 244{ 245 friend class sc_int_base; 246 friend class sc_core::sc_vpool<sc_int_bitref>; 247 248 // constructor 249 sc_int_bitref() : sc_int_bitref_r() {} 250 251 public: 252 // copy constructor 253 sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {} 254 255 // assignment operators 256 sc_int_bitref &operator = (const sc_int_bitref_r &b); 257 sc_int_bitref &operator = (const sc_int_bitref &b); 258 sc_int_bitref &operator = (bool b); 259 260 sc_int_bitref &operator &= (bool b); 261 sc_int_bitref &operator |= (bool b); 262 sc_int_bitref &operator ^= (bool b); 263 264 // concatenation methods 265 virtual void concat_set(int64 src, int low_i); 266 virtual void concat_set(const sc_signed &src, int low_i); 267 virtual void concat_set(const sc_unsigned &src, int low_i); 268 virtual void concat_set(uint64 src, int low_i); 269 270 // other methods 271 void scan(::std::istream &is=::std::cin); 272 273 public: 274 static sc_core::sc_vpool<sc_int_bitref> m_pool; 275}; 276 277 278 279inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &); 280 281 282// ---------------------------------------------------------------------------- 283// CLASS : sc_int_subref_r 284// 285// Proxy class for sc_int part selection (r-value only). 286// ---------------------------------------------------------------------------- 287 288class sc_int_subref_r : public sc_value_base 289{ 290 friend class sc_int_base; 291 friend class sc_int_signal; 292 friend class sc_int_subref; 293 294 protected: 295 // constructor 296 sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {} 297 298 // initializer for sc_core::sc_vpool: 299 void initialize( const sc_int_base *obj_p, int left_i, int right_i) 300 { 301 m_obj_p = (sc_int_base *)obj_p; 302 m_left = left_i; 303 m_right = right_i; 304 } 305 306 public: 307 // copy constructor 308 sc_int_subref_r(const sc_int_subref_r &a) : 309 sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p), 310 m_right(a.m_right) 311 {} 312 313 // destructor 314 virtual ~sc_int_subref_r() {} 315 316 // capacity 317 int length() const { return (m_left - m_right + 1); } 318 319 // concatenation support 320 virtual int 321 concat_length(bool *xz_present_p) const 322 { 323 if (xz_present_p) 324 *xz_present_p = false; 325 return length(); 326 } 327 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; 328 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; 329 virtual uint64 330 concat_get_uint64() const 331 { 332 int len = length(); 333 uint64 val = operator uint_type(); 334 if (len < 64) 335 return (uint64)(val & ~((uint_type)-1 << len)); 336 else 337 return (uint64)val; 338 } 339 340 // reduce methods 341 bool and_reduce() const; 342 bool nand_reduce() const { return !and_reduce(); } 343 bool or_reduce() const; 344 bool nor_reduce() const { return !or_reduce(); } 345 bool xor_reduce() const; 346 bool xnor_reduce() const { return !xor_reduce(); } 347 348 // implicit conversion to uint_type 349 operator uint_type () const; 350 351 // explicit conversions 352 uint_type value() const { return operator uint_type(); } 353 354 355 int to_int() const; 356 unsigned int to_uint() const; 357 long to_long() const; 358 unsigned long to_ulong() const; 359 int64 to_int64() const; 360 uint64 to_uint64() const; 361 double to_double() const; 362 363 // explicit conversion to character string 364 const std::string to_string(sc_numrep numrep=SC_DEC) const; 365 const std::string to_string(sc_numrep numrep, bool w_prefix) const; 366 367 // other methods 368 void 369 print(::std::ostream &os=::std::cout) const 370 { 371 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); 372 } 373 374 protected: 375 int m_left; 376 sc_int_base *m_obj_p; 377 int m_right; 378 379 private: 380 const sc_int_subref_r &operator = (const sc_int_subref_r &); 381}; 382 383inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &); 384 385 386// ---------------------------------------------------------------------------- 387// CLASS : sc_int_subref 388// 389// Proxy class for sc_int part selection (r-value and l-value). 390// ---------------------------------------------------------------------------- 391 392class sc_int_subref : public sc_int_subref_r 393{ 394 friend class sc_int_base; 395 friend class sc_core::sc_vpool<sc_int_subref>; 396 397 protected: 398 // constructor 399 sc_int_subref() : sc_int_subref_r() {} 400 401 public: 402 // copy constructor 403 sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {} 404 405 // assignment operators 406 sc_int_subref &operator = (int_type v); 407 sc_int_subref &operator = (const sc_int_base &a); 408 409 sc_int_subref & 410 operator = (const sc_int_subref_r &a) 411 { 412 return operator = (a.operator uint_type()); 413 } 414 415 sc_int_subref & 416 operator = (const sc_int_subref &a) 417 { 418 return operator = (a.operator uint_type()); 419 } 420 421 template< class T > 422 sc_int_subref & 423 operator = (const sc_generic_base<T> &a) 424 { 425 return operator = (a->to_int64()); 426 } 427 428 sc_int_subref &operator = (const char *a); 429 430 sc_int_subref & 431 operator = (unsigned long a) 432 { 433 return operator = ((int_type)a); 434 } 435 436 sc_int_subref & 437 operator = (long a) 438 { 439 return operator = ((int_type)a); 440 } 441 442 sc_int_subref & 443 operator = (unsigned int a) 444 { 445 return operator = ((int_type)a); 446 } 447 448 sc_int_subref & 449 operator = (int a) 450 { 451 return operator = ((int_type)a); 452 } 453 454 sc_int_subref & 455 operator = (uint64 a) 456 { 457 return operator = ((int_type)a); 458 } 459 460 sc_int_subref & 461 operator = (double a) 462 { 463 return operator = ((int_type)a); 464 } 465 466 sc_int_subref &operator = (const sc_signed &); 467 sc_int_subref &operator = (const sc_unsigned &); 468 sc_int_subref &operator = (const sc_bv_base &); 469 sc_int_subref &operator = (const sc_lv_base &); 470 471 // concatenation methods 472 virtual void concat_set(int64 src, int low_i); 473 virtual void concat_set(const sc_signed &src, int low_i); 474 virtual void concat_set(const sc_unsigned &src, int low_i); 475 virtual void concat_set(uint64 src, int low_i); 476 477 // other methods 478 void scan(::std::istream &is=::std::cin); 479 480 public: 481 static sc_core::sc_vpool<sc_int_subref> m_pool; 482}; 483 484 485inline ::std::istream &operator >> (::std::istream &, sc_int_subref &); 486 487 488// ---------------------------------------------------------------------------- 489// CLASS : sc_int_base 490// 491// Base class for sc_int. 492// ---------------------------------------------------------------------------- 493 494class sc_int_base : public sc_value_base 495{ 496 friend class sc_int_bitref_r; 497 friend class sc_int_bitref; 498 friend class sc_int_subref_r; 499 friend class sc_int_subref; 500 501 502 // support methods 503 void invalid_length() const; 504 void invalid_index(int i) const; 505 void invalid_range(int l, int r) const; 506 507 void 508 check_length() const 509 { 510 if (m_len <= 0 || m_len > SC_INTWIDTH) { 511 invalid_length(); 512 } 513 } 514 515 void 516 check_index(int i) const 517 { 518 if (i < 0 || i >= m_len) { 519 invalid_index(i); 520 } 521 } 522 523 void 524 check_range(int l, int r) const 525 { 526 if (r < 0 || l >= m_len || l < r) { 527 invalid_range(l, r); 528 } 529 } 530 531 void check_value() const; 532 533 void 534 extend_sign() 535 { 536#ifdef DEBUG_SYSTEMC 537 check_value(); 538#endif 539 m_val = (m_val << m_ulen >> m_ulen); 540 } 541 542public: 543 544 // constructors 545 explicit sc_int_base(int w=sc_length_param().len()) : 546 m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len) 547 { 548 check_length(); 549 } 550 551 sc_int_base(int_type v, int w) : 552 m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len) 553 { 554 check_length(); 555 extend_sign(); 556 } 557 558 sc_int_base(const sc_int_base &a) : 559 sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) 560 {} 561 562 explicit sc_int_base(const sc_int_subref_r &a) : 563 m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len) 564 { 565 extend_sign(); 566 } 567 568 template< class T > 569 explicit sc_int_base(const sc_generic_base<T> &a) : 570 m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len) 571 { 572 check_length(); 573 extend_sign(); 574 } 575 576 explicit sc_int_base(const sc_signed &a); 577 explicit sc_int_base(const sc_unsigned &a); 578 explicit sc_int_base(const sc_bv_base &v); 579 explicit sc_int_base(const sc_lv_base &v); 580 explicit sc_int_base(const sc_uint_subref_r &v); 581 explicit sc_int_base(const sc_signed_subref_r &v); 582 explicit sc_int_base(const sc_unsigned_subref_r &v); 583 584 585 // destructor 586 virtual ~sc_int_base() {} 587 588 // assignment operators 589 sc_int_base & 590 operator = (int_type v) 591 { 592 m_val = v; 593 extend_sign(); 594 return *this; 595 } 596 597 sc_int_base & 598 operator = (const sc_int_base &a) 599 { 600 m_val = a.m_val; 601 extend_sign(); 602 return *this; 603 } 604 605 sc_int_base & 606 operator = (const sc_int_subref_r &a) 607 { 608 m_val = a; 609 extend_sign(); 610 return *this; 611 } 612 613 template<class T> 614 sc_int_base & 615 operator = (const sc_generic_base<T> &a) 616 { 617 m_val = a->to_int64(); 618 extend_sign(); 619 return *this; 620 } 621 622 sc_int_base &operator = (const sc_signed &a); 623 sc_int_base &operator = (const sc_unsigned &a); 624 625 sc_int_base &operator = (const sc_fxval &a); 626 sc_int_base &operator = (const sc_fxval_fast &a); 627 sc_int_base &operator = (const sc_fxnum &a); 628 sc_int_base &operator = (const sc_fxnum_fast &a); 629 630 sc_int_base &operator = (const sc_bv_base &a); 631 sc_int_base &operator = (const sc_lv_base &a); 632 633 sc_int_base &operator = (const char *a); 634 635 sc_int_base & 636 operator = (unsigned long a) 637 { 638 m_val = a; 639 extend_sign(); 640 return *this; 641 } 642 643 sc_int_base & 644 operator = (long a) 645 { 646 m_val = a; 647 extend_sign(); 648 return *this; 649 } 650 651 sc_int_base & 652 operator = (unsigned int a) 653 { 654 m_val = a; 655 extend_sign(); 656 return *this; 657 } 658 659 sc_int_base & 660 operator = (int a) 661 { 662 m_val = a; 663 extend_sign(); 664 return *this; 665 } 666 667 sc_int_base & 668 operator = (uint64 a) 669 { 670 m_val = a; 671 extend_sign(); 672 return *this; 673 } 674 675 sc_int_base & 676 operator = (double a) 677 { 678 m_val = (int_type)a; 679 extend_sign(); 680 return *this; 681 } 682 683 // arithmetic assignment operators 684 sc_int_base & 685 operator += (int_type v) 686 { 687 m_val += v; 688 extend_sign(); 689 return *this; 690 } 691 692 sc_int_base & 693 operator -= (int_type v) 694 { 695 m_val -= v; 696 extend_sign(); 697 return *this; 698 } 699 700 sc_int_base & 701 operator *= (int_type v) 702 { 703 m_val *= v; 704 extend_sign(); 705 return *this; 706 } 707 708 sc_int_base & 709 operator /= (int_type v) 710 { 711 m_val /= v; 712 extend_sign(); 713 return *this; 714 } 715 716 sc_int_base & 717 operator %= (int_type v) 718 { 719 m_val %= v; 720 extend_sign(); 721 return *this; 722 } 723 724 725 // bitwise assignment operators 726 sc_int_base & 727 operator &= (int_type v) 728 { 729 m_val &= v; 730 extend_sign(); 731 return *this; 732 } 733 734 sc_int_base & 735 operator |= (int_type v) 736 { 737 m_val |= v; 738 extend_sign(); 739 return *this; 740 } 741 742 sc_int_base & 743 operator ^= (int_type v) 744 { 745 m_val ^= v; 746 extend_sign(); 747 return *this; 748 } 749 750 751 sc_int_base & 752 operator <<= (int_type v) 753 { 754 m_val <<= v; 755 extend_sign(); 756 return *this; 757 } 758 759 sc_int_base & 760 operator >>= (int_type v) 761 { 762 m_val >>= v; 763 /* no sign extension needed */ 764 return *this; 765 } 766 767 768 // prefix and postfix increment and decrement operators 769 sc_int_base & 770 operator ++ () // prefix 771 { 772 ++m_val; 773 extend_sign(); 774 return *this; 775 } 776 777 const sc_int_base 778 operator ++ (int) // postfix 779 { 780 sc_int_base tmp(*this); 781 ++m_val; 782 extend_sign(); 783 return tmp; 784 } 785 786 sc_int_base & 787 operator -- () // prefix 788 { 789 --m_val; 790 extend_sign(); 791 return *this; 792 } 793 794 const sc_int_base 795 operator -- ( int ) // postfix 796 { 797 sc_int_base tmp(*this); 798 --m_val; 799 extend_sign(); 800 return tmp; 801 } 802 803 804 // relational operators 805 friend bool 806 operator == (const sc_int_base &a, const sc_int_base &b) 807 { 808 return a.m_val == b.m_val; 809 } 810 811 friend bool 812 operator != (const sc_int_base &a, const sc_int_base &b) 813 { 814 return a.m_val != b.m_val; 815 } 816 817 friend bool 818 operator < (const sc_int_base &a, const sc_int_base &b) 819 { 820 return a.m_val < b.m_val; 821 } 822 823 friend bool 824 operator <= (const sc_int_base &a, const sc_int_base &b) 825 { 826 return a.m_val <= b.m_val; 827 } 828 829 friend bool 830 operator > (const sc_int_base &a, const sc_int_base &b) 831 { 832 return a.m_val > b.m_val; 833 } 834 835 friend bool 836 operator >= (const sc_int_base &a, const sc_int_base &b) 837 { 838 return a.m_val >= b.m_val; 839 } 840 841 842 // bit selection 843 sc_int_bitref &operator [] (int i); 844 const sc_int_bitref_r &operator [] (int i) const; 845 846 sc_int_bitref &bit(int i); 847 const sc_int_bitref_r &bit(int i) const; 848 849 850 // part selection 851 sc_int_subref &operator () (int left, int right); 852 const sc_int_subref_r &operator () (int left, int right) const; 853 854 sc_int_subref &range(int left, int right); 855 const sc_int_subref_r &range(int left, int right) const; 856 857 858 // bit access, without bounds checking or sign extension 859 bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); } 860 861 void set(int i) { m_val |= (UINT_ONE << i); } 862 863 void 864 set(int i, bool v) 865 { 866 v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); 867 } 868 869 // capacity 870 int length() const { return m_len; } 871 872 // concatenation support 873 virtual int 874 concat_length(bool* xz_present_p) const 875 { 876 if (xz_present_p) 877 *xz_present_p = false; 878 return length(); 879 } 880 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; 881 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; 882 virtual uint64 883 concat_get_uint64() const 884 { 885 if (m_len < 64) 886 return (uint64)(m_val & ~((uint_type) - 1 << m_len)); 887 else 888 return (uint64)m_val; 889 } 890 virtual void concat_set(int64 src, int low_i); 891 virtual void concat_set(const sc_signed &src, int low_i); 892 virtual void concat_set(const sc_unsigned &src, int low_i); 893 virtual void concat_set(uint64 src, int low_i); 894 895 896 // reduce methods 897 bool and_reduce() const; 898 bool nand_reduce() const { return !and_reduce(); } 899 bool or_reduce() const; 900 bool nor_reduce() const { return !or_reduce(); } 901 bool xor_reduce() const; 902 bool xnor_reduce() const { return !xor_reduce(); } 903 904 905 // implicit conversion to int_type 906 operator int_type() const { return m_val; } 907 908 909 // explicit conversions 910 int_type value() const { return operator int_type(); } 911 int to_int() const { return (int)m_val; } 912 unsigned int to_uint() const { return (unsigned int)m_val; } 913 long to_long() const { return (long)m_val; } 914 unsigned long to_ulong() const { return (unsigned long)m_val; } 915 int64 to_int64() const { return (int64)m_val; } 916 uint64 to_uint64() const { return (uint64)m_val; } 917 double to_double() const { return (double)m_val; } 918 long long_low() const { return (long)(m_val & UINT64_32ONES); } 919 long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); } 920 921 922 // explicit conversion to character string 923 const std::string to_string(sc_numrep numrep=SC_DEC) const; 924 const std::string to_string(sc_numrep numrep, bool w_prefix) const; 925 926 927 // other methods 928 void 929 print(::std::ostream &os=::std::cout) const 930 { 931 os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); 932 } 933 934 void scan(::std::istream &is=::std::cin); 935 936 protected: 937 int_type m_val; // value 938 int m_len; // length 939 int m_ulen; // unused length 940}; 941 942inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &); 943inline ::std::istream &operator >> (::std::istream &, sc_int_base &); 944 945 946// ---------------------------------------------------------------------------- 947// CLASS : sc_int_bitref_r 948// 949// Proxy class for sc_int bit selection (r-value only). 950// ---------------------------------------------------------------------------- 951 952// implicit conversion to uint64 953 954inline sc_int_bitref_r::operator uint64 () const 955{ 956 return m_obj_p->test(m_index); 957} 958 959inline bool 960sc_int_bitref_r::operator ! () const 961{ 962 return ! m_obj_p->test(m_index); 963} 964 965inline bool 966sc_int_bitref_r::operator ~ () const 967{ 968 return !m_obj_p->test(m_index); 969} 970 971 972inline ::std::ostream & 973operator << (::std::ostream &os, const sc_int_bitref_r &a) 974{ 975 a.print(os); 976 return os; 977} 978 979 980// ---------------------------------------------------------------------------- 981// CLASS : sc_int_bitref 982// 983// Proxy class for sc_int bit selection (r-value and l-value). 984// ---------------------------------------------------------------------------- 985 986// assignment operators 987 988inline sc_int_bitref & 989sc_int_bitref::operator = (const sc_int_bitref_r &b) 990{ 991 m_obj_p->set(m_index, (bool)b); 992 m_obj_p->extend_sign(); 993 return *this; 994} 995 996inline sc_int_bitref & 997sc_int_bitref::operator = (const sc_int_bitref &b) 998{ 999 m_obj_p->set(m_index, (bool)b); 1000 m_obj_p->extend_sign(); 1001 return *this; 1002} 1003 1004inline sc_int_bitref & 1005sc_int_bitref::operator = (bool b) 1006{ 1007 m_obj_p->set(m_index, b); 1008 m_obj_p->extend_sign(); 1009 return *this; 1010} 1011 1012 1013inline sc_int_bitref & 1014sc_int_bitref::operator &= (bool b) 1015{ 1016 if (!b) { 1017 m_obj_p->set(m_index, b); 1018 m_obj_p->extend_sign(); 1019 } 1020 return *this; 1021} 1022 1023inline sc_int_bitref & 1024sc_int_bitref::operator |= (bool b) 1025{ 1026 if (b) { 1027 m_obj_p->set(m_index, b); 1028 m_obj_p->extend_sign(); 1029 } 1030 return *this; 1031} 1032 1033inline sc_int_bitref & 1034sc_int_bitref::operator ^= (bool b) 1035{ 1036 if (b) { 1037 m_obj_p->m_val ^= (UINT_ONE << m_index); 1038 m_obj_p->extend_sign(); 1039 } 1040 return *this; 1041} 1042 1043 1044 1045inline ::std::istream & 1046operator >> (::std::istream &is, sc_int_bitref &a) 1047{ 1048 a.scan(is); 1049 return is; 1050} 1051 1052 1053// ---------------------------------------------------------------------------- 1054// CLASS : sc_int_subref_r 1055// 1056// Proxy class for sc_int part selection (r-value only). 1057// ---------------------------------------------------------------------------- 1058 1059// implicit conversion to int_type 1060 1061inline sc_int_subref_r::operator uint_type() const 1062{ 1063 uint_type /*int_type*/ val = m_obj_p->m_val; 1064 int uleft = SC_INTWIDTH - (m_left + 1); 1065 int uright = uleft + m_right; 1066 return (val << uleft >> uright); 1067} 1068 1069 1070// reduce methods 1071 1072inline bool 1073sc_int_subref_r::and_reduce() const 1074{ 1075 sc_int_base a(*this); 1076 return a.and_reduce(); 1077} 1078 1079inline bool 1080sc_int_subref_r::or_reduce() const 1081{ 1082 sc_int_base a(*this); 1083 return a.or_reduce(); 1084} 1085 1086inline bool 1087sc_int_subref_r::xor_reduce() const 1088{ 1089 sc_int_base a(*this); 1090 return a.xor_reduce(); 1091} 1092 1093 1094// explicit conversions 1095 1096inline int 1097sc_int_subref_r::to_int() const 1098{ 1099 int result = static_cast<int>(operator uint_type()); 1100 return result; 1101} 1102 1103inline unsigned int 1104sc_int_subref_r::to_uint() const 1105{ 1106 unsigned int result = static_cast<unsigned int>(operator uint_type()); 1107 return result; 1108} 1109 1110inline long 1111sc_int_subref_r::to_long() const 1112{ 1113 long result = static_cast<long>(operator uint_type()); 1114 return result; 1115} 1116 1117inline unsigned long 1118sc_int_subref_r::to_ulong() const 1119{ 1120 unsigned long result = static_cast<unsigned long>(operator uint_type()); 1121 return result; 1122} 1123 1124inline int64 1125sc_int_subref_r::to_int64() const 1126{ 1127 int64 result = operator uint_type(); 1128 return result; 1129} 1130 1131inline uint64 1132sc_int_subref_r::to_uint64() const 1133{ 1134 uint64 result = operator uint_type(); 1135 return result; 1136} 1137 1138inline double 1139sc_int_subref_r::to_double() const 1140{ 1141 double result = static_cast<double>(operator uint_type()); 1142 return result; 1143} 1144 1145 1146// explicit conversion to character string 1147 1148inline const std::string 1149sc_int_subref_r::to_string(sc_numrep numrep) const 1150{ 1151 sc_uint_base a(length()); 1152 a = operator uint_type(); 1153 return a.to_string(numrep); 1154} 1155 1156inline const std::string 1157sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const 1158{ 1159 sc_uint_base a(length()); 1160 a = operator uint_type(); 1161 return a.to_string(numrep, w_prefix); 1162} 1163 1164 1165// functional notation for the reduce methods 1166 1167inline bool 1168and_reduce(const sc_int_subref_r &a) 1169{ 1170 return a.and_reduce(); 1171} 1172 1173inline bool 1174nand_reduce(const sc_int_subref_r &a) 1175{ 1176 return a.nand_reduce(); 1177} 1178 1179inline bool 1180or_reduce(const sc_int_subref_r &a) 1181{ 1182 return a.or_reduce(); 1183} 1184 1185inline bool 1186nor_reduce(const sc_int_subref_r &a) 1187{ 1188 return a.nor_reduce(); 1189} 1190 1191inline bool 1192xor_reduce(const sc_int_subref_r &a) 1193{ 1194 return a.xor_reduce(); 1195} 1196 1197inline bool 1198xnor_reduce(const sc_int_subref_r &a) 1199{ 1200 return a.xnor_reduce(); 1201} 1202 1203 1204 1205inline ::std::ostream & 1206operator << (::std::ostream &os, const sc_int_subref_r &a) 1207{ 1208 a.print(os); 1209 return os; 1210} 1211 1212 1213// ---------------------------------------------------------------------------- 1214// CLASS : sc_int_subref 1215// 1216// Proxy class for sc_int part selection (r-value and l-value). 1217// ---------------------------------------------------------------------------- 1218 1219// assignment operators 1220 1221inline sc_int_subref & 1222sc_int_subref::operator = (const sc_int_base &a) 1223{ 1224 return operator = (a.operator int_type()); 1225} 1226 1227inline sc_int_subref & 1228sc_int_subref::operator = (const char *a) 1229{ 1230 sc_int_base aa(length()); 1231 return (*this = aa = a); 1232} 1233 1234 1235 1236inline ::std::istream & 1237operator >> (::std::istream &is, sc_int_subref &a) 1238{ 1239 a.scan(is); 1240 return is; 1241} 1242 1243 1244// ---------------------------------------------------------------------------- 1245// CLASS : sc_int_base 1246// 1247// Base class for sc_int. 1248// ---------------------------------------------------------------------------- 1249 1250// bit selection 1251 1252inline sc_int_bitref & 1253sc_int_base::operator [] (int i) 1254{ 1255 check_index(i); 1256 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); 1257 result_p->initialize(this, i); 1258 return *result_p; 1259} 1260 1261inline const sc_int_bitref_r & 1262sc_int_base::operator [] (int i) const 1263{ 1264 check_index(i); 1265 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); 1266 result_p->initialize(this, i); 1267 return *result_p; 1268} 1269 1270 1271inline sc_int_bitref & 1272sc_int_base::bit(int i) 1273{ 1274 check_index(i); 1275 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); 1276 result_p->initialize(this, i); 1277 return *result_p; 1278} 1279 1280inline const sc_int_bitref_r & 1281sc_int_base::bit(int i) const 1282{ 1283 check_index(i); 1284 sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); 1285 result_p->initialize(this, i); 1286 return *result_p; 1287} 1288 1289 1290// part selection 1291 1292inline sc_int_subref & 1293sc_int_base::operator () (int left, int right) 1294{ 1295 check_range(left, right); 1296 sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); 1297 result_p->initialize(this, left, right); 1298 return *result_p; 1299} 1300 1301inline const sc_int_subref_r & 1302sc_int_base::operator () (int left, int right) const 1303{ 1304 check_range(left, right); 1305 sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); 1306 result_p->initialize(this, left, right); 1307 return *result_p; 1308} 1309 1310 1311inline sc_int_subref & 1312sc_int_base::range(int left, int right) 1313{ 1314 check_range(left, right); 1315 sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); 1316 result_p->initialize(this, left, right); 1317 return *result_p; 1318} 1319 1320inline const sc_int_subref_r & 1321sc_int_base::range(int left, int right) const 1322{ 1323 check_range(left, right); 1324 sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); 1325 result_p->initialize(this, left, right); 1326 return *result_p; 1327} 1328 1329 1330// functional notation for the reduce methods 1331 1332inline bool 1333and_reduce(const sc_int_base &a) 1334{ 1335 return a.and_reduce(); 1336} 1337 1338inline bool 1339nand_reduce(const sc_int_base &a) 1340{ 1341 return a.nand_reduce(); 1342} 1343 1344inline bool 1345or_reduce(const sc_int_base &a) 1346{ 1347 return a.or_reduce(); 1348} 1349 1350inline bool 1351nor_reduce(const sc_int_base &a) 1352{ 1353 return a.nor_reduce(); 1354} 1355 1356inline bool 1357xor_reduce(const sc_int_base &a) 1358{ 1359 return a.xor_reduce(); 1360} 1361 1362inline bool 1363xnor_reduce(const sc_int_base &a) 1364{ 1365 return a.xnor_reduce(); 1366} 1367 1368 1369 1370inline ::std::ostream & 1371operator << (::std::ostream &os, const sc_int_base &a) 1372{ 1373 a.print(os); 1374 return os; 1375} 1376 1377inline ::std::istream & 1378operator >> (::std::istream &is, sc_int_base &a) 1379{ 1380 a.scan(is); 1381 return is; 1382} 1383 1384} // namespace sc_dt 1385 1386#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ 1387