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