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_proxy.h -- Proxy base class for vector data types. 23 24 This class is created for several purposes: 25 1) hiding operators from the global namespace that would be 26 otherwise found by Koenig lookup 27 2) avoiding repeating the same operations in every class 28 including proxies that could also be achieved by common 29 base class, but this method allows 30 3) improve performance by using non-virtual functions 31 32 Original Author: Gene Bushuyev, Synopsys, Inc. 33 34 *****************************************************************************/ 35 36 /***************************************************************************** 37 38 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 39 changes you are making here. 40 41 Name, Affiliation, Date: 42 Description of Modification: 43 44 *****************************************************************************/ 45 46 // $Log: sc_proxy.h,v $ 47 // Revision 1.3 2010/12/07 20:09:07 acg 48 // Andy Goodrich: Fix for returning enough data 49 // 50 // Revision 1.2 2009/02/28 00:26:14 acg 51 // Andy Goodrich: bug fixes. 52 // 53 // Revision 1.1.1.1 2006/12/15 20:31:36 acg 54 // SystemC 2.2 55 // 56 // Revision 1.3 2006/01/13 18:53:53 acg 57 // Andy Goodrich: added $Log command so that CVS comments are reproduced in 58 // the source. 59 // 60 61 #ifndef SC_PROXY_H 62 #define SC_PROXY_H 63 64 65 #include "sysc/kernel/sc_cmnhdr.h" 66 #include "sysc/datatypes/int/sc_signed.h" 67 #include "sysc/datatypes/int/sc_unsigned.h" 68 #include "sysc/datatypes/int/sc_int_base.h" 69 #include "sysc/datatypes/int/sc_uint_base.h" 70 #include "sysc/datatypes/bit/sc_bit.h" 71 #include "sysc/datatypes/bit/sc_bit_ids.h" 72 #include "sysc/datatypes/bit/sc_logic.h" 73 #include "sysc/kernel/sc_macros.h" 74 75 76 namespace sc_dt 77 { 78 79 // classes defined in this module 80 template <class X> class sc_proxy; 81 82 // forward class declarations 83 class sc_bv_base; 84 class sc_lv_base; 85 template <class X> class sc_bitref_r; 86 template <class X> class sc_bitref; 87 template <class X> class sc_subref_r; 88 template <class X> class sc_subref; 89 template <class X, class Y> class sc_concref_r; 90 template <class X, class Y> class sc_concref; 91 92 93 const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit ); 94 95 const sc_digit SC_DIGIT_ZERO = (sc_digit)0; 96 const sc_digit SC_DIGIT_ONE = (sc_digit)1; 97 const sc_digit SC_DIGIT_TWO = (sc_digit)2; 98 99 SC_API void sc_proxy_out_of_bounds(const char* msg = NULL, int64 val = 0); 100 101 // assignment functions; forward declarations 102 103 template <class X, class Y> 104 inline 105 void 106 assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ); 107 108 // Vector types that are not derived from sc_proxy must have a length() 109 // function and an operator []. 110 111 template <class X, class T> 112 inline 113 void 114 assign_v_( sc_proxy<X>& px, const T& a ); 115 116 117 // other functions; forward declarations 118 119 SC_API const std::string convert_to_bin( const char* s ); 120 SC_API const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool ); 121 122 // ---------------------------------------------------------------------------- 123 // CLASS TEMPLATE : sc_proxy_traits 124 // 125 // Template traits helper to select the correct bit/value/vector_types for 126 // sc_proxy-based vector classes. 127 // 128 // All types derived from/based on a bit-vector contain typedef to a plain bool, 129 // all others point to the sc_logic_value_t/sc_logic/sc_lv_base types. 130 // ---------------------------------------------------------------------------- 131 132 template<typename X> struct sc_proxy_traits; 133 134 template<> struct sc_proxy_traits<sc_bv_base> 135 { 136 typedef sc_proxy_traits<sc_bv_base> traits_type; 137 typedef bool value_type; 138 typedef sc_logic bit_type; // sc_logic needed for mixed expressions 139 typedef sc_bv_base vector_type; 140 }; 141 142 template<> struct sc_proxy_traits<sc_lv_base> 143 { 144 typedef sc_proxy_traits<sc_lv_base> traits_type; 145 typedef sc_logic_value_t value_type; 146 typedef sc_logic bit_type; 147 typedef sc_lv_base vector_type; 148 }; 149 150 151 template<typename X> struct sc_proxy_traits<sc_bitref_r<X> > 152 : sc_proxy_traits<X> {}; 153 154 template<typename X> struct sc_proxy_traits<sc_bitref<X> > 155 : sc_proxy_traits<X> {}; 156 157 158 template<typename X> struct sc_proxy_traits<sc_subref_r<X> > 159 : sc_proxy_traits<X> {}; 160 161 template<typename X> struct sc_proxy_traits<sc_subref<X> > 162 : sc_proxy_traits<X> {}; 163 164 165 template<typename X> struct sc_proxy_traits<sc_proxy<X> > 166 : sc_proxy_traits<X> {}; 167 168 169 template< typename X, typename Y > struct sc_mixed_proxy_traits_helper 170 : sc_proxy_traits<sc_lv_base> {}; // logic vector by default 171 172 template<typename X> struct sc_mixed_proxy_traits_helper<X,X> 173 : X {}; 174 175 176 template<typename X, typename Y> struct sc_proxy_traits< sc_concref_r<X,Y> > 177 : sc_mixed_proxy_traits_helper< typename X::traits_type 178 , typename Y::traits_type > 179 {}; 180 181 template<typename X, typename Y> struct sc_proxy_traits<sc_concref<X,Y> > 182 : sc_mixed_proxy_traits_helper< typename X::traits_type 183 , typename Y::traits_type > 184 {}; 185 186 187 // ---------------------------------------------------------------------------- 188 // CLASS TEMPLATE : sc_proxy 189 // 190 // Base class template for bit/logic vector classes. 191 // (Barton/Nackmann implementation) 192 // ---------------------------------------------------------------------------- 193 194 template <class X> 195 class sc_proxy // #### : public sc_value_base 196 { 197 public: 198 typedef typename sc_proxy_traits<X>::traits_type traits_type; 199 typedef typename traits_type::bit_type bit_type; 200 typedef typename traits_type::value_type value_type; 201 202 // virtual destructor 203 204 virtual ~sc_proxy() {} 205 206 207 // casts 208 209 X& back_cast() 210 { return static_cast<X&>( *this ); } 211 212 const X& back_cast() const 213 { return static_cast<const X&>( *this ); } 214 215 216 // assignment operators 217 218 template <class Y> 219 X& assign_( const sc_proxy<Y>& a ) 220 { assign_p_( *this, a ); return back_cast(); } 221 222 X& assign_( const char* a ); 223 X& assign_( const bool* a ); 224 X& assign_( const sc_logic* a ); 225 226 X& assign_( const sc_unsigned& a ) 227 { assign_v_( *this, a ); return back_cast(); } 228 229 X& assign_( const sc_signed& a ) 230 { assign_v_( *this, a ); return back_cast(); } 231 232 X& assign_( const sc_uint_base& a ) 233 { return assign_( (uint64) a ); } 234 235 X& assign_( const sc_int_base& a ) 236 { return assign_( (int64) a ); } 237 238 X& assign_( unsigned int a ); 239 X& assign_( int a ); 240 241 X& assign_( unsigned long a ); 242 243 X& assign_( long a ); 244 245 X& assign_( uint64 a ); 246 X& assign_( int64 a ); 247 248 249 // bitwise operators and functions 250 251 // bitwise complement 252 253 X& b_not(); 254 255 const sc_lv_base operator ~ () const; 256 257 258 // bitwise and 259 260 X& operator &= ( const char* b ); 261 X& operator &= ( const bool* b ); 262 X& operator &= ( const sc_logic* b ); 263 X& operator &= ( const sc_unsigned& b ); 264 X& operator &= ( const sc_signed& b ); 265 266 X& operator &= ( const sc_uint_base& b ) 267 { return operator &= ( (uint64) b ); } 268 269 X& operator &= ( const sc_int_base& b ) 270 { return operator &= ( (int64) b ); } 271 272 X& operator &= ( unsigned long b ); 273 X& operator &= ( long b ); 274 275 X& operator &= ( unsigned int b ) 276 { return operator &= ( (unsigned long) b ); } 277 278 X& operator &= ( int b ) 279 { return operator &= ( (long) b ); } 280 281 X& operator &= ( uint64 b ); 282 X& operator &= ( int64 b ); 283 284 285 const sc_lv_base operator & ( const char* b ) const; 286 const sc_lv_base operator & ( const bool* b ) const; 287 const sc_lv_base operator & ( const sc_logic* b ) const; 288 const sc_lv_base operator & ( const sc_unsigned& b ) const; 289 const sc_lv_base operator & ( const sc_signed& b ) const; 290 const sc_lv_base operator & ( const sc_uint_base& b ) const; 291 const sc_lv_base operator & ( const sc_int_base& b ) const; 292 const sc_lv_base operator & ( unsigned long b ) const; 293 const sc_lv_base operator & ( long b ) const; 294 const sc_lv_base operator & ( unsigned int b ) const; 295 const sc_lv_base operator & ( int b ) const; 296 const sc_lv_base operator & ( uint64 b ) const; 297 const sc_lv_base operator & ( int64 b ) const; 298 299 300 // bitwise or 301 302 X& operator |= ( const char* b ); 303 X& operator |= ( const bool* b ); 304 X& operator |= ( const sc_logic* b ); 305 X& operator |= ( const sc_unsigned& b ); 306 X& operator |= ( const sc_signed& b ); 307 308 X& operator |= ( const sc_uint_base& b ) 309 { return operator |= ( (uint64) b ); } 310 311 X& operator |= ( const sc_int_base& b ) 312 { return operator |= ( (int64) b ); } 313 314 X& operator |= ( unsigned long b ); 315 X& operator |= ( long b ); 316 317 X& operator |= ( unsigned int b ) 318 { return operator |= ( (unsigned long) b ); } 319 320 X& operator |= ( int b ) 321 { return operator |= ( (long) b ); } 322 323 X& operator |= ( uint64 b ); 324 X& operator |= ( int64 b ); 325 326 327 const sc_lv_base operator | ( const char* b ) const; 328 const sc_lv_base operator | ( const bool* b ) const; 329 const sc_lv_base operator | ( const sc_logic* b ) const; 330 const sc_lv_base operator | ( const sc_unsigned& b ) const; 331 const sc_lv_base operator | ( const sc_signed& b ) const; 332 const sc_lv_base operator | ( const sc_uint_base& b ) const; 333 const sc_lv_base operator | ( const sc_int_base& b ) const; 334 const sc_lv_base operator | ( unsigned long b ) const; 335 const sc_lv_base operator | ( long b ) const; 336 const sc_lv_base operator | ( unsigned int b ) const; 337 const sc_lv_base operator | ( int b ) const; 338 const sc_lv_base operator | ( uint64 b ) const; 339 const sc_lv_base operator | ( int64 b ) const; 340 341 342 // bitwise xor 343 344 X& operator ^= ( const char* b ); 345 X& operator ^= ( const bool* b ); 346 X& operator ^= ( const sc_logic* b ); 347 X& operator ^= ( const sc_unsigned& b ); 348 X& operator ^= ( const sc_signed& b ); 349 350 X& operator ^= ( const sc_uint_base& b ) 351 { return operator ^= ( (uint64) b ); } 352 353 X& operator ^= ( const sc_int_base& b ) 354 { return operator ^= ( (int64) b ); } 355 356 X& operator ^= ( unsigned long b ); 357 X& operator ^= ( long b ); 358 359 X& operator ^= ( unsigned int b ) 360 { return operator ^= ( (unsigned long) b ); } 361 362 X& operator ^= ( int b ) 363 { return operator ^= ( (long) b ); } 364 365 X& operator ^= ( uint64 b ); 366 X& operator ^= ( int64 b ); 367 368 369 const sc_lv_base operator ^ ( const char* b ) const; 370 const sc_lv_base operator ^ ( const bool* b ) const; 371 const sc_lv_base operator ^ ( const sc_logic* b ) const; 372 const sc_lv_base operator ^ ( const sc_unsigned& b ) const; 373 const sc_lv_base operator ^ ( const sc_signed& b ) const; 374 const sc_lv_base operator ^ ( const sc_uint_base& b ) const; 375 const sc_lv_base operator ^ ( const sc_int_base& b ) const; 376 const sc_lv_base operator ^ ( unsigned long b ) const; 377 const sc_lv_base operator ^ ( long b ) const; 378 const sc_lv_base operator ^ ( unsigned int b ) const; 379 const sc_lv_base operator ^ ( int b ) const; 380 const sc_lv_base operator ^ ( uint64 b ) const; 381 const sc_lv_base operator ^ ( int64 b ) const; 382 383 384 // bitwise left shift 385 386 X& operator <<= ( int n ); 387 388 const sc_lv_base operator << ( int n ) const; 389 390 391 // bitwise right shift 392 393 X& operator >>= ( int n ); 394 395 const sc_lv_base operator >> ( int n ) const; 396 397 398 // bitwise left rotate 399 400 X& lrotate( int n ); 401 402 403 // bitwise right rotate 404 405 X& rrotate( int n ); 406 407 408 // bitwise reverse 409 410 X& reverse(); 411 412 413 // bit selection 414 415 sc_bitref<X> operator [] ( int i ) 416 { return sc_bitref<X>( back_cast(), i ); } 417 418 sc_bitref_r<X> operator [] ( int i ) const 419 { return sc_bitref_r<X>( back_cast(), i ); } 420 421 sc_bitref<X> bit( int i ) 422 { return sc_bitref<X>( back_cast(), i ); } 423 424 sc_bitref_r<X> bit( int i ) const 425 { return sc_bitref_r<X>( back_cast(), i ); } 426 427 428 // part selection 429 430 sc_subref<X> operator () ( int hi, int lo ) 431 { return sc_subref<X>( back_cast(), hi, lo ); } 432 433 sc_subref_r<X> operator () ( int hi, int lo ) const 434 { return sc_subref_r<X>( back_cast(), hi, lo ); } 435 436 sc_subref<X> range( int hi, int lo ) 437 { return sc_subref<X>( back_cast(), hi, lo ); } 438 439 sc_subref_r<X> range( int hi, int lo ) const 440 { return sc_subref_r<X>( back_cast(), hi, lo ); } 441 442 443 // reduce functions 444 445 value_type and_reduce() const; 446 447 value_type nand_reduce() const 448 { return sc_logic::not_table[and_reduce()]; } 449 450 value_type or_reduce() const; 451 452 value_type nor_reduce() const 453 { return sc_logic::not_table[or_reduce()]; } 454 455 value_type xor_reduce() const; 456 457 value_type xnor_reduce() const 458 { return sc_logic::not_table[xor_reduce()]; } 459 460 461 // relational operators 462 463 bool operator == ( const char* b ) const; 464 bool operator == ( const bool* b ) const; 465 bool operator == ( const sc_logic* b ) const; 466 bool operator == ( const sc_unsigned& b ) const; 467 bool operator == ( const sc_signed& b ) const; 468 bool operator == ( const sc_uint_base& b ) const; 469 bool operator == ( const sc_int_base& b ) const; 470 bool operator == ( unsigned long b ) const; 471 bool operator == ( long b ) const; 472 bool operator == ( unsigned int b ) const; 473 bool operator == ( int b ) const; 474 bool operator == ( uint64 b ) const; 475 bool operator == ( int64 b ) const; 476 477 478 // explicit conversions to character string 479 480 const std::string to_string() const; 481 const std::string to_string( sc_numrep ) const; 482 const std::string to_string( sc_numrep, bool ) const; 483 484 485 // explicit conversions 486 487 inline int64 to_int64() const 488 { return to_anything_signed(); } 489 inline uint64 to_uint64() const; 490 int to_int() const 491 { return (int)to_anything_signed(); } 492 493 unsigned int to_uint() const 494 { return (unsigned int)to_anything_unsigned(); } 495 496 long to_long() const 497 { return (long)to_anything_signed(); } 498 499 unsigned long to_ulong() const 500 { return (unsigned long)to_anything_unsigned(); } 501 502 #ifdef SC_DT_DEPRECATED 503 504 int to_signed() const 505 { return to_int(); } 506 507 sc_digit to_unsigned() const 508 { return to_uint(); } 509 510 #endif 511 512 513 // other methods 514 515 void print( ::std::ostream& os = ::std::cout ) const 516 { 517 // the test below will force printing in binary if decimal is 518 // specified. 519 if ( sc_io_base(os, SC_DEC) == SC_DEC ) 520 os << to_string(); 521 else 522 os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os)); 523 } 524 525 void scan( ::std::istream& is = ::std::cin ); 526 527 protected: 528 529 void check_bounds( int n ) const; // check if bit n accessible 530 void check_wbounds( int n ) const; // check if word n accessible 531 532 sc_digit to_anything_unsigned() const; 533 int64 to_anything_signed() const; 534 }; 535 536 537 // ---------------------------------------------------------------------------- 538 539 // bitwise operators and functions 540 541 // bitwise and 542 543 template <class X, class Y> 544 inline 545 X& 546 operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); 547 548 549 template <class X, class Y> 550 inline 551 const sc_lv_base 552 operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); 553 554 555 #define DECL_BITWISE_AND_OP_T(tp) \ 556 template <class X> \ 557 inline \ 558 const sc_lv_base \ 559 operator & ( tp b, const sc_proxy<X>& px ); 560 561 DECL_BITWISE_AND_OP_T(const char*) 562 DECL_BITWISE_AND_OP_T(const bool*) 563 DECL_BITWISE_AND_OP_T(const sc_logic*) 564 DECL_BITWISE_AND_OP_T(const sc_unsigned&) 565 DECL_BITWISE_AND_OP_T(const sc_signed&) 566 DECL_BITWISE_AND_OP_T(const sc_uint_base&) 567 DECL_BITWISE_AND_OP_T(const sc_int_base&) 568 DECL_BITWISE_AND_OP_T(unsigned long) 569 DECL_BITWISE_AND_OP_T(long) 570 DECL_BITWISE_AND_OP_T(unsigned int) 571 DECL_BITWISE_AND_OP_T(int) 572 DECL_BITWISE_AND_OP_T(uint64) 573 DECL_BITWISE_AND_OP_T(int64) 574 575 #undef DECL_BITWISE_AND_OP_T 576 577 578 // bitwise or 579 580 template <class X, class Y> 581 inline 582 X& 583 operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); 584 585 586 template <class X, class Y> 587 inline 588 const sc_lv_base 589 operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); 590 591 592 #define DECL_BITWISE_OR_OP_T(tp) \ 593 template <class X> \ 594 inline \ 595 const sc_lv_base \ 596 operator | ( tp a, const sc_proxy<X>& px ); 597 598 DECL_BITWISE_OR_OP_T(const char*) 599 DECL_BITWISE_OR_OP_T(const bool*) 600 DECL_BITWISE_OR_OP_T(const sc_logic*) 601 DECL_BITWISE_OR_OP_T(const sc_unsigned&) 602 DECL_BITWISE_OR_OP_T(const sc_signed&) 603 DECL_BITWISE_OR_OP_T(const sc_uint_base&) 604 DECL_BITWISE_OR_OP_T(const sc_int_base&) 605 DECL_BITWISE_OR_OP_T(unsigned long) 606 DECL_BITWISE_OR_OP_T(long) 607 DECL_BITWISE_OR_OP_T(unsigned int) 608 DECL_BITWISE_OR_OP_T(int) 609 DECL_BITWISE_OR_OP_T(uint64) 610 DECL_BITWISE_OR_OP_T(int64) 611 612 #undef DECL_BITWISE_OR_OP_T 613 614 615 // bitwise xor 616 617 template <class X, class Y> 618 inline 619 X& 620 operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py ); 621 622 623 template <class X, class Y> 624 inline 625 const sc_lv_base 626 operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); 627 628 629 #define DECL_BITWISE_XOR_OP_T(tp) \ 630 template <class X> \ 631 inline \ 632 const sc_lv_base \ 633 operator ^ ( tp a, const sc_proxy<X>& px ); 634 635 DECL_BITWISE_XOR_OP_T(const char*) 636 DECL_BITWISE_XOR_OP_T(const bool*) 637 DECL_BITWISE_XOR_OP_T(const sc_logic*) 638 DECL_BITWISE_XOR_OP_T(const sc_unsigned&) 639 DECL_BITWISE_XOR_OP_T(const sc_signed&) 640 DECL_BITWISE_XOR_OP_T(const sc_uint_base&) 641 DECL_BITWISE_XOR_OP_T(const sc_int_base&) 642 DECL_BITWISE_XOR_OP_T(unsigned long) 643 DECL_BITWISE_XOR_OP_T(long) 644 DECL_BITWISE_XOR_OP_T(unsigned int) 645 DECL_BITWISE_XOR_OP_T(int) 646 DECL_BITWISE_XOR_OP_T(uint64) 647 DECL_BITWISE_XOR_OP_T(int64) 648 649 #undef DECL_BITWISE_XOR_OP_T 650 651 652 // relational operators 653 654 template <class X, class Y> 655 inline 656 bool 657 operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); 658 659 template <class X, class Y> 660 inline 661 bool 662 operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ); 663 664 665 #define DECL_REL_OP_T(tp) \ 666 template <class X> \ 667 inline \ 668 bool \ 669 operator == ( tp b, const sc_proxy<X>& px ); \ 670 \ 671 template <class X> \ 672 inline \ 673 bool \ 674 operator != ( const sc_proxy<X>& px, tp b ); \ 675 \ 676 template <class X> \ 677 inline \ 678 bool \ 679 operator != ( tp b, const sc_proxy<X>& px ); 680 681 DECL_REL_OP_T(const char*) 682 DECL_REL_OP_T(const bool*) 683 DECL_REL_OP_T(const sc_logic*) 684 DECL_REL_OP_T(const sc_unsigned&) 685 DECL_REL_OP_T(const sc_signed&) 686 DECL_REL_OP_T(const sc_uint_base&) 687 DECL_REL_OP_T(const sc_int_base&) 688 DECL_REL_OP_T(unsigned long) 689 DECL_REL_OP_T(long) 690 DECL_REL_OP_T(unsigned int) 691 DECL_REL_OP_T(int) 692 DECL_REL_OP_T(uint64) 693 DECL_REL_OP_T(int64) 694 695 #undef DECL_REL_OP_T 696 697 698 // l-value concatenation 699 700 // Due to the fact that temporary objects cannot be passed to non-const 701 // references, we have to enumerate, use call by value, and use dynamic 702 // memory allocation (and deallocation). 703 704 705 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 706 707 template <class X> 708 inline 709 void 710 get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw ) 711 { 712 x_dw = x.get_word( wi ); 713 x_cw = x.get_cword( wi ); 714 } 715 716 template <class X> 717 inline 718 void 719 set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw ) 720 { 721 x.set_word( wi, x_dw ); 722 x.set_cword( wi, x_cw ); 723 } 724 725 template <class X> 726 inline 727 void 728 extend_sign_w_( X& x, int wi, bool sign ) 729 { 730 int sz = x.size(); 731 unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO); 732 for( int i = wi; i < sz; ++ i ) { 733 set_words_( x, i, sgn, SC_DIGIT_ZERO ); 734 } 735 } 736 737 738 // assignment functions 739 740 template <class X, class Y> 741 inline 742 void 743 assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py ) 744 { 745 if( (void*) &px != (void*) &py ) { 746 X& x = px.back_cast(); 747 const Y& y = py.back_cast(); 748 int sz = x.size(); 749 int min_sz = sc_min( sz, y.size() ); 750 int i = 0; 751 for( ; i < min_sz; ++ i ) { 752 set_words_( x, i, y.get_word( i ), y.get_cword( i ) ); 753 } 754 // extend with zeros 755 extend_sign_w_( x, i, false ); 756 x.clean_tail(); 757 } 758 } 759 760 // Vector types that are not derived from sc_proxy, sc_int_base, 761 // sc_uint_base, sc_signed, or sc_unsigned, must have a length() 762 // function and an operator []. The vector argument type must support 763 // accessing bits that are beyond the msb. The vector argument type 764 // decides what to do there (e.g. sign extension or zero padding). 765 766 template <class X, class T> 767 inline 768 void 769 assign_v_( sc_proxy<X>& px, const T& a ) 770 { 771 X& x = px.back_cast(); 772 int i; 773 int len_x = x.length(); 774 int len_a = a.length(); 775 if ( len_a > len_x ) len_a = len_x; 776 for( i = 0 ; i < len_a; ++ i ) { 777 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); 778 } 779 for( ; i < len_x; ++ i ) { 780 x.set_bit( i, sc_logic_value_t( false ) ); 781 } 782 } 783 784 template <class X> 785 inline 786 void 787 assign_v_( sc_proxy<X>& px, const sc_int_base& a ) 788 { 789 X& x = px.back_cast(); 790 int i; 791 bool sign = a < 0; 792 int len_x = x.length(); 793 int len_a = a.length(); 794 if ( len_a > len_x ) len_a = len_x; 795 for( i = 0 ; i < len_a; ++ i ) { 796 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); 797 } 798 for( ; i < len_x; ++ i ) { 799 x.set_bit( i, sc_logic_value_t( sign ) ); 800 } 801 } 802 803 template <class X> 804 inline 805 void 806 assign_v_( sc_proxy<X>& px, const sc_signed& a ) 807 { 808 X& x = px.back_cast(); 809 int i; 810 bool sign = a < 0; 811 int len_x = x.length(); 812 int len_a = a.length(); 813 if ( len_a > len_x ) len_a = len_x; 814 for( i = 0 ; i < len_a; ++ i ) { 815 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); 816 } 817 for( ; i < len_x; ++ i ) { 818 x.set_bit( i, sc_logic_value_t( sign ) ); 819 } 820 } 821 822 template <class X> 823 inline 824 void 825 assign_v_( sc_proxy<X>& px, const sc_uint_base& a ) 826 { 827 X& x = px.back_cast(); 828 int i; 829 int len_x = x.length(); 830 int len_a = a.length(); 831 if ( len_a > len_x ) len_a = len_x; 832 for( i = 0 ; i < len_a; ++ i ) { 833 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); 834 } 835 for( ; i < len_x; ++ i ) { 836 x.set_bit( i, sc_logic_value_t( false ) ); 837 } 838 } 839 840 template <class X> 841 inline 842 void 843 assign_v_( sc_proxy<X>& px, const sc_unsigned& a ) 844 { 845 X& x = px.back_cast(); 846 int i; 847 int len_x = x.length(); 848 int len_a = a.length(); 849 if ( len_a > len_x ) len_a = len_x; 850 for( i = 0 ; i < len_a; ++ i ) { 851 x.set_bit( i, sc_logic_value_t( (bool) a[i] ) ); 852 } 853 for( ; i < len_x; ++ i ) { 854 x.set_bit( i, sc_logic_value_t( false ) ); 855 } 856 } 857 858 859 // assignment operators 860 861 template <class X> 862 inline 863 X& 864 sc_proxy<X>::assign_( const char* a ) 865 { 866 X& x = back_cast(); 867 std::string s = convert_to_bin( a ); 868 int len = x.length(); 869 int s_len = s.length() - 1; 870 int min_len = sc_min( len, s_len ); 871 int i = 0; 872 for( ; i < min_len; ++ i ) { 873 char c = s[s_len - i - 1]; 874 x.set_bit( i, sc_logic::char_to_logic[(int)c] ); 875 } 876 // if formatted, fill the rest with sign(s), otherwise fill with zeros 877 sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' ) 878 : sc_logic_value_t( 0 )); 879 for( ; i < len; ++ i ) { 880 x.set_bit( i, fill ); 881 } 882 return x; 883 } 884 885 template <class X> 886 inline 887 X& 888 sc_proxy<X>::assign_( const bool* a ) 889 { 890 // the length of 'a' must be larger than or equal to the length of 'this' 891 X& x = back_cast(); 892 int len = x.length(); 893 for( int i = 0; i < len; ++ i ) { 894 x.set_bit( i, sc_logic_value_t( a[i] ) ); 895 } 896 return x; 897 } 898 899 template <class X> 900 inline 901 X& 902 sc_proxy<X>::assign_( const sc_logic* a ) 903 { 904 // the length of 'a' must be larger than or equal to the length of 'this' 905 X& x = back_cast(); 906 int len = x.length(); 907 for( int i = 0; i < len; ++ i ) { 908 x.set_bit( i, a[i].value() ); 909 } 910 return x; 911 } 912 913 template <class X> 914 inline 915 X& 916 sc_proxy<X>::assign_( unsigned int a ) 917 { 918 X& x = back_cast(); 919 set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); 920 // extend with zeros 921 extend_sign_w_( x, 1, false ); 922 x.clean_tail(); 923 return x; 924 } 925 926 template <class X> 927 inline 928 X& 929 sc_proxy<X>::assign_( int a ) 930 { 931 X& x = back_cast(); 932 set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); 933 // extend with sign(a) 934 extend_sign_w_( x, 1, (a < 0) ); 935 x.clean_tail(); 936 return x; 937 } 938 939 #if defined(SC_LONG_64) 940 template <class X> 941 inline 942 X& 943 sc_proxy<X>::assign_( unsigned long a ) 944 { 945 X& x = back_cast(); 946 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); 947 if( x.size() > 1 ) { 948 set_words_( x, 1, 949 ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 950 SC_DIGIT_ZERO ); 951 // extend with zeros 952 extend_sign_w_( x, 2, false ); 953 } 954 x.clean_tail(); 955 return x; 956 } 957 958 template <class X> 959 inline 960 X& 961 sc_proxy<X>::assign_( long a ) 962 { 963 X& x = back_cast(); 964 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); 965 if( x.size() > 1 ) { 966 set_words_( x, 1, 967 ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 968 SC_DIGIT_ZERO ); 969 // extend with sign(a) 970 extend_sign_w_( x, 2, (a < 0) ); 971 } 972 x.clean_tail(); 973 return x; 974 } 975 976 #else 977 template <class X> 978 inline 979 X& 980 sc_proxy<X>::assign_( unsigned long a ) 981 { 982 X& x = back_cast(); 983 set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO ); 984 // extend with zeros 985 extend_sign_w_( x, 1, false ); 986 x.clean_tail(); 987 return x; 988 } 989 990 template <class X> 991 inline 992 X& 993 sc_proxy<X>::assign_( long a ) 994 { 995 X& x = back_cast(); 996 set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO ); 997 // extend with sign(a) 998 extend_sign_w_( x, 1, (a < 0) ); 999 x.clean_tail(); 1000 return x; 1001 } 1002 #endif 1003 template <class X> 1004 inline 1005 X& 1006 sc_proxy<X>::assign_( uint64 a ) 1007 { 1008 X& x = back_cast(); 1009 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); 1010 if( x.size() > 1 ) { 1011 set_words_( x, 1, 1012 ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 1013 SC_DIGIT_ZERO ); 1014 // extend with zeros 1015 extend_sign_w_( x, 2, false ); 1016 } 1017 x.clean_tail(); 1018 return x; 1019 } 1020 1021 template <class X> 1022 inline 1023 X& 1024 sc_proxy<X>::assign_( int64 a ) 1025 { 1026 X& x = back_cast(); 1027 set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO ); 1028 if( x.size() > 1 ) { 1029 set_words_( x, 1, 1030 ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), 1031 SC_DIGIT_ZERO ); 1032 // extend with sign(a) 1033 extend_sign_w_( x, 2, (a < 0) ); 1034 } 1035 x.clean_tail(); 1036 return x; 1037 } 1038 1039 1040 // bitwise operators and functions 1041 1042 // bitwise complement 1043 1044 template <class X> 1045 inline 1046 X& 1047 sc_proxy<X>::b_not() 1048 { 1049 X& x = back_cast(); 1050 int sz = x.size(); 1051 for( int i = 0; i < sz; ++ i ) { 1052 sc_digit x_dw, x_cw; 1053 get_words_( x, i, x_dw, x_cw ); 1054 x.set_word( i, x_cw | ~x_dw ); 1055 } 1056 x.clean_tail(); 1057 return x; 1058 } 1059 1060 1061 // bitwise and 1062 1063 template <class X, class Y> 1064 inline 1065 X& 1066 b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) 1067 { 1068 X& x = px.back_cast(); 1069 const Y& y = py.back_cast(); 1070 sc_assert( x.length() == y.length() ); 1071 int sz = x.size(); 1072 for( int i = 0; i < sz; ++ i ) { 1073 sc_digit x_dw, x_cw, y_dw, y_cw; 1074 get_words_( x, i, x_dw, x_cw ); 1075 get_words_( y, i, y_dw, y_cw ); 1076 sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw); 1077 sc_digit dw = cw | (x_dw & y_dw); 1078 set_words_( x, i, dw, cw ); 1079 } 1080 // tail cleaning not needed 1081 return x; 1082 } 1083 1084 1085 // bitwise or 1086 1087 template <class X, class Y> 1088 inline 1089 X& 1090 b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py ) 1091 { 1092 X& x = px.back_cast(); 1093 const Y& y = py.back_cast(); 1094 sc_assert( x.length() == y.length() ); 1095 int sz = x.size(); 1096 for( int i = 0; i < sz; ++ i ) { 1097 sc_digit x_dw, x_cw, y_dw, y_cw; 1098 get_words_( x, i, x_dw, x_cw ); 1099 get_words_( y, i, y_dw, y_cw ); 1100 sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw); 1101 sc_digit dw = cw | x_dw | y_dw; 1102 set_words_( x, i, dw, cw ); 1103 } 1104 // tail cleaning not needed 1105 return x; 1106 } 1107 1108 1109 // bitwise xor 1110 1111 template <class X, class Y> 1112 inline 1113 X& 1114 b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b ) 1115 { 1116 X& x = a.back_cast(); 1117 const Y& y = b.back_cast(); 1118 sc_assert( x.length() == y.length() ); 1119 int sz = x.size(); 1120 for( int i = 0; i < sz; ++ i ) { 1121 sc_digit x_dw, x_cw, y_dw, y_cw; 1122 get_words_( x, i, x_dw, x_cw ); 1123 get_words_( y, i, y_dw, y_cw ); 1124 sc_digit cw = x_cw | y_cw; 1125 sc_digit dw = cw | (x_dw ^ y_dw); 1126 set_words_( x, i, dw, cw ); 1127 } 1128 // tail cleaning not needed 1129 return x; 1130 } 1131 1132 1133 // bitwise left shift 1134 1135 template <class X> 1136 inline 1137 X& 1138 sc_proxy<X>::operator <<= ( int n ) 1139 { 1140 X& x = back_cast(); 1141 if( n < 0 ) { 1142 sc_proxy_out_of_bounds( "left shift operation is only allowed with " 1143 "positive shift values, shift value = ", n ); 1144 return x; 1145 } 1146 if( n >= x.length() ) { 1147 extend_sign_w_( x, 0, false ); 1148 // no tail cleaning needed 1149 return x; 1150 } 1151 int sz = x.size(); 1152 int wn = n / SC_DIGIT_SIZE; 1153 int bn = n % SC_DIGIT_SIZE; 1154 if( wn != 0 ) { 1155 // shift words 1156 int i = sz - 1; 1157 for( ; i >= wn; -- i ) { 1158 set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) ); 1159 } 1160 for( ; i >= 0; -- i ) { 1161 set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); 1162 } 1163 } 1164 if( bn != 0 ) { 1165 // shift bits 1166 for( int i = sz - 1; i >= 1; -- i ) { 1167 sc_digit x_dw, x_cw; 1168 get_words_( x, i, x_dw, x_cw ); 1169 x_dw <<= bn; 1170 x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn); 1171 x_cw <<= bn; 1172 x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn); 1173 set_words_( x, i, x_dw, x_cw ); 1174 } 1175 sc_digit x_dw, x_cw; 1176 get_words_( x, 0, x_dw, x_cw ); 1177 x_dw <<= bn; 1178 x_cw <<= bn; 1179 set_words_( x, 0, x_dw, x_cw ); 1180 } 1181 x.clean_tail(); 1182 return x; 1183 } 1184 1185 1186 // bitwise right shift 1187 1188 1189 template <class X> 1190 inline 1191 X& 1192 sc_proxy<X>::operator >>= ( int n ) 1193 { 1194 X& x = back_cast(); 1195 if( n < 0 ) { 1196 sc_proxy_out_of_bounds( "right shift operation is only allowed with " 1197 "positive shift values, shift value = ", n ); 1198 return x; 1199 } 1200 if( n >= x.length() ) { 1201 extend_sign_w_( x, 0, false ); 1202 // no tail cleaning needed 1203 return x; 1204 } 1205 int sz = x.size(); 1206 int wn = n / SC_DIGIT_SIZE; 1207 int bn = n % SC_DIGIT_SIZE; 1208 if( wn != 0 ) { 1209 // shift words 1210 int i = 0; 1211 for( ; i < (sz - wn); ++ i ) { 1212 set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) ); 1213 } 1214 for( ; i < sz; ++ i ) { 1215 set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO ); 1216 } 1217 } 1218 if( bn != 0 ) { 1219 // shift bits 1220 for( int i = 0; i < (sz - 1); ++ i ) { 1221 sc_digit x_dw, x_cw; 1222 get_words_( x, i, x_dw, x_cw ); 1223 x_dw >>= bn; 1224 x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn); 1225 x_cw >>= bn; 1226 x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn); 1227 set_words_( x, i, x_dw, x_cw ); 1228 } 1229 sc_digit x_dw, x_cw; 1230 get_words_( x, sz - 1, x_dw, x_cw ); 1231 x_dw >>= bn; 1232 x_cw >>= bn; 1233 set_words_( x, sz - 1, x_dw, x_cw ); 1234 } 1235 x.clean_tail(); 1236 return x; 1237 } 1238 1239 1240 // bitwise left rotate 1241 1242 template <class X> 1243 inline 1244 const sc_lv_base 1245 lrotate( const sc_proxy<X>& x, int n ); 1246 1247 1248 // bitwise right rotate 1249 1250 template <class X> 1251 inline 1252 const sc_lv_base 1253 rrotate( const sc_proxy<X>& x, int n ); 1254 1255 1256 // bitwise reverse 1257 1258 template <class X> 1259 inline 1260 X& 1261 sc_proxy<X>::reverse() 1262 { 1263 X& x = back_cast(); 1264 int len = x.length(); 1265 int half_len = len / 2; 1266 for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) { 1267 value_type t = x.get_bit( i ); 1268 x.set_bit( i, x.get_bit( j ) ); 1269 x.set_bit( j, t ); 1270 } 1271 return x; 1272 } 1273 1274 template <class X> 1275 inline 1276 const sc_lv_base 1277 reverse( const sc_proxy<X>& a ); 1278 1279 1280 // reduce functions 1281 1282 template <class X> 1283 inline 1284 typename sc_proxy<X>::value_type 1285 sc_proxy<X>::and_reduce() const 1286 { 1287 const X& x = back_cast(); 1288 value_type result = value_type( 1 ); 1289 int len = x.length(); 1290 for( int i = 0; i < len; ++ i ) { 1291 result = sc_logic::and_table[result][x.get_bit( i )]; 1292 } 1293 return result; 1294 } 1295 1296 template <class X> 1297 inline 1298 typename sc_proxy<X>::value_type 1299 sc_proxy<X>::or_reduce() const 1300 { 1301 const X& x = back_cast(); 1302 value_type result = value_type( 0 ); 1303 int len = x.length(); 1304 for( int i = 0; i < len; ++ i ) { 1305 result = sc_logic::or_table[result][x.get_bit( i )]; 1306 } 1307 return result; 1308 } 1309 1310 template <class X> 1311 inline 1312 typename sc_proxy<X>::value_type 1313 sc_proxy<X>::xor_reduce() const 1314 { 1315 const X& x = back_cast(); 1316 value_type result = value_type( 0 ); 1317 int len = x.length(); 1318 for( int i = 0; i < len; ++ i ) { 1319 result = sc_logic::xor_table[result][x.get_bit( i )]; 1320 } 1321 return result; 1322 } 1323 1324 1325 // relational operators 1326 1327 template <class X, class Y> 1328 inline 1329 bool 1330 operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py ) 1331 { 1332 return !( px == py ); 1333 } 1334 1335 1336 #define DEFN_REL_OP_T(tp) \ 1337 template <class X> \ 1338 inline \ 1339 bool \ 1340 operator == ( tp b, const sc_proxy<X>& px ) \ 1341 { \ 1342 return ( px == b ); \ 1343 } \ 1344 \ 1345 template <class X> \ 1346 inline \ 1347 bool \ 1348 operator != ( const sc_proxy<X>& px, tp b ) \ 1349 { \ 1350 return !( px == b ); \ 1351 } \ 1352 \ 1353 template <class X> \ 1354 inline \ 1355 bool \ 1356 operator != ( tp b, const sc_proxy<X>& px ) \ 1357 { \ 1358 return !( px == b ); \ 1359 } 1360 1361 DEFN_REL_OP_T(const char*) 1362 DEFN_REL_OP_T(const bool*) 1363 DEFN_REL_OP_T(const sc_logic*) 1364 DEFN_REL_OP_T(const sc_unsigned&) 1365 DEFN_REL_OP_T(const sc_signed&) 1366 DEFN_REL_OP_T(const sc_uint_base&) 1367 DEFN_REL_OP_T(const sc_int_base&) 1368 DEFN_REL_OP_T(unsigned long) 1369 DEFN_REL_OP_T(long) 1370 DEFN_REL_OP_T(unsigned int) 1371 DEFN_REL_OP_T(int) 1372 DEFN_REL_OP_T(uint64) 1373 DEFN_REL_OP_T(int64) 1374 1375 #undef DEFN_REL_OP_T 1376 1377 1378 // explicit conversions to character string 1379 1380 template <class X> 1381 inline 1382 const std::string 1383 sc_proxy<X>::to_string() const 1384 { 1385 const X& x = back_cast(); 1386 int len = x.length(); 1387 std::string s; // ( len + 1 ); 1388 for( int i = 0; i < len; ++ i ) { 1389 s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )]; 1390 } 1391 return s; 1392 } 1393 1394 template <class X> 1395 inline 1396 const std::string 1397 sc_proxy<X>::to_string( sc_numrep numrep ) const 1398 { 1399 return convert_to_fmt( to_string(), numrep, true ); 1400 } 1401 1402 template <class X> 1403 inline 1404 const std::string 1405 sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const 1406 { 1407 return convert_to_fmt( to_string(), numrep, w_prefix ); 1408 } 1409 1410 1411 // other methods 1412 1413 template <class X> 1414 inline 1415 void 1416 sc_proxy<X>::scan( ::std::istream& is ) 1417 { 1418 std::string s; 1419 is >> s; 1420 back_cast() = s.c_str(); 1421 } 1422 1423 1424 template <class X> 1425 inline 1426 void 1427 sc_proxy<X>::check_bounds( int n ) const // check if bit n accessible 1428 { 1429 if( n < 0 || n >= back_cast().length() ) { 1430 sc_proxy_out_of_bounds(NULL, n); 1431 sc_core::sc_abort(); // can't recover from here 1432 } 1433 } 1434 1435 template <class X> 1436 inline 1437 void 1438 sc_proxy<X>::check_wbounds( int n ) const // check if word n accessible 1439 { 1440 if( n < 0 || n >= back_cast().size() ) { 1441 sc_proxy_out_of_bounds(NULL, n); 1442 sc_core::sc_abort(); // can't recover from here 1443 } 1444 } 1445 1446 1447 template <class X> 1448 inline 1449 sc_digit 1450 sc_proxy<X>::to_anything_unsigned() const 1451 { 1452 // only 0 word is returned 1453 // can't convert logic values other than 0 and 1 1454 const X& x = back_cast(); 1455 int len = x.length(); 1456 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { 1457 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); 1458 } 1459 sc_digit w = x.get_word( 0 ); 1460 if( len >= SC_DIGIT_SIZE ) { 1461 return w; 1462 } 1463 return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); 1464 } 1465 1466 template <class X> 1467 inline 1468 uint64 1469 sc_proxy<X>::to_uint64() const 1470 { 1471 // words 1 and 0 returned. 1472 // can't convert logic values other than 0 and 1 1473 const X& x = back_cast(); 1474 int len = x.length(); 1475 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) { 1476 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); 1477 } 1478 uint64 w = x.get_word( 0 ); 1479 if( len > SC_DIGIT_SIZE ) 1480 { 1481 if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) { 1482 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); 1483 } 1484 uint64 w1 = x.get_word( 1 ); 1485 w = w | (w1 << SC_DIGIT_SIZE); 1486 return w; 1487 } 1488 else if( len == SC_DIGIT_SIZE ) 1489 { 1490 return w; 1491 } 1492 else 1493 { 1494 return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) ); 1495 } 1496 } 1497 1498 template <class X> 1499 inline 1500 int64 1501 sc_proxy<X>::to_anything_signed() const 1502 { 1503 const X& x = back_cast(); 1504 int len = x.length(); 1505 int64 w = 0; 1506 1507 if( len > SC_DIGIT_SIZE ) 1508 { 1509 if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) 1510 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); 1511 w = x.get_word(1); 1512 } 1513 if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) 1514 SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 ); 1515 w = (w << SC_DIGIT_SIZE) | x.get_word( 0 ); 1516 if( len >= 64 ) { 1517 return w; 1518 } 1519 1520 uint64 zero = 0; 1521 value_type sgn = x.get_bit( len - 1 ); 1522 if( sgn == 0 ) { 1523 return (int64)( w & (~zero >> (64 - len)) ); 1524 } else { 1525 return (int64)( w | (~zero << len) ); 1526 } 1527 } 1528 1529 1530 // ---------------------------------------------------------------------------- 1531 1532 // functional notation for the reduce methods 1533 1534 template <class X> 1535 inline 1536 typename sc_proxy<X>::value_type 1537 and_reduce( const sc_proxy<X>& a ) 1538 { 1539 return a.and_reduce(); 1540 } 1541 1542 template <class X> 1543 inline 1544 typename sc_proxy<X>::value_type 1545 nand_reduce( const sc_proxy<X>& a ) 1546 { 1547 return a.nand_reduce(); 1548 } 1549 1550 template <class X> 1551 inline 1552 typename sc_proxy<X>::value_type 1553 or_reduce( const sc_proxy<X>& a ) 1554 { 1555 return a.or_reduce(); 1556 } 1557 1558 template <class X> 1559 inline 1560 typename sc_proxy<X>::value_type 1561 nor_reduce( const sc_proxy<X>& a ) 1562 { 1563 return a.nor_reduce(); 1564 } 1565 1566 template <class X> 1567 inline 1568 typename sc_proxy<X>::value_type 1569 xor_reduce( const sc_proxy<X>& a ) 1570 { 1571 return a.xor_reduce(); 1572 } 1573 1574 template <class X> 1575 inline 1576 typename sc_proxy<X>::value_type 1577 xnor_reduce( const sc_proxy<X>& a ) 1578 { 1579 return a.xnor_reduce(); 1580 } 1581 1582 1583 // ---------------------------------------------------------------------------- 1584 1585 template <class X> 1586 inline 1587 ::std::ostream& 1588 operator << ( ::std::ostream& os, const sc_proxy<X>& a ) 1589 { 1590 a.print( os ); 1591 return os; 1592 } 1593 1594 template <class X> 1595 inline 1596 ::std::istream& 1597 operator >> ( ::std::istream& is, sc_proxy<X>& a ) 1598 { 1599 a.scan( is ); 1600 return is; 1601 } 1602 1603 } // namespace sc_dt 1604 1605 1606 #endif 1607