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