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_concatref.h -- Concatenation support. 23 24 Original Author: Andy Goodrich, Forte Design, Inc. 25 26 *****************************************************************************/ 27 28/***************************************************************************** 29 30 MODIFICATION LOG - modifiers, enter your name, affiliation, date and 31 changes you are making here. 32 33 Name, Affiliation, Date: 34 Description of Modification: 35 36 Andy Goodrich, Forte Design Systems, 17 Nov 2002 37 Creation of sc_concatref class by merging the capabilities of 38 sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref, 39 and implementing the capabilities of sc_signed_concref, sc_signed_concref, 40 sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows 41 mixed mode concatenations on the left and right sides of an assignment. 42 43 *****************************************************************************/ 44 45// $Log: sc_concatref.h,v $ 46// Revision 1.6 2011/08/24 22:05:48 acg 47// Torsten Maehne: initialization changes to remove warnings. 48// 49// Revision 1.5 2009/11/17 19:58:15 acg 50// Andy Goodrich: fix of shift rhs possibilities to include "int". 51// 52// Revision 1.4 2009/02/28 00:26:29 acg 53// Andy Goodrich: bug fixes. 54// 55// Revision 1.3 2008/04/29 20:23:55 acg 56// Andy Goodrich: fixed the code that assigns the value of a string to 57// an sc_concatref instance. 58// 59// Revision 1.2 2008/02/14 20:57:26 acg 60// Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy. 61// 62// Revision 1.1.1.1 2006/12/15 20:20:05 acg 63// SystemC 2.3 64// 65// Revision 1.4 2006/10/23 19:36:59 acg 66// Andy Goodrich: changed casts for operations on concatenation values to 67// mirror those of sc_unsigned. For instance, an sc_unsigned minus a value 68// returns an sc_signed result, whereas an sc_concatref minus a value was 69// returning an sc_unsigned result. Now both sc_unsigned and sc_concatref 70// minus a value return an sc_signed result. 71// 72// Revision 1.3 2006/01/13 18:54:01 acg 73// Andy Goodrich: added $Log command so that CVS comments are reproduced in 74// the source. 75// 76 77#ifndef SC_CONCATREF_H 78#define SC_CONCATREF_H 79 80#include "sysc/kernel/sc_object.h" 81#include "sysc/datatypes/misc/sc_value_base.h" 82#include "sysc/utils/sc_temporary.h" 83#include "sysc/datatypes/bit/sc_bv.h" 84#include "sysc/datatypes/bit/sc_lv.h" 85#include "sysc/datatypes/int/sc_int_base.h" 86#include "sysc/datatypes/int/sc_uint_base.h" 87#include "sysc/datatypes/int/sc_signed.h" 88#include "sysc/datatypes/int/sc_unsigned.h" 89 90namespace sc_core { 91 extern sc_byte_heap sc_temp_heap; // Temporary storage. 92} // namespace sc_core 93 94namespace sc_dt 95{ 96 97// ---------------------------------------------------------------------------- 98// CLASS TEMPLATE : sc_concatref 99// 100// Proxy class for sized bit concatenation. 101// ---------------------------------------------------------------------------- 102 103class sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base 104{ 105public: 106 friend class sc_core::sc_vpool<sc_concatref>; 107 108 inline void initialize( 109 sc_value_base& left, sc_value_base& right ) 110 { 111 bool left_xz; // True if x's and/or z's found in left. 112 bool right_xz; // True if x's and/or z's found in right. 113 114 m_left_p = (sc_value_base*)&left; 115 m_right_p = (sc_value_base*)&right; 116 m_len_r = right.concat_length(&right_xz); 117 m_len = left.concat_length(&left_xz) + m_len_r; 118 m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none; 119 } 120 121 122 inline void initialize( 123 const sc_value_base& left, const sc_value_base& right ) 124 { 125 bool left_xz; // True if x's and/or z's found in left. 126 bool right_xz; // True if x's and/or z's found in right. 127 128 m_left_p = (sc_value_base*)&left; 129 m_right_p = (sc_value_base*)&right; 130 m_len_r = right.concat_length(&right_xz); 131 m_len = left.concat_length(&left_xz) + m_len_r; 132 m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none; 133 } 134 135 // destructor 136 137 virtual ~sc_concatref() 138 {} 139 140 141 // capacity 142 143 unsigned int length() const 144 { return m_len; } 145 146#ifdef SC_DT_DEPRECATED 147 int bitwidth() const 148 { return length(); } 149#endif 150 151 // concatenation 152 153 virtual int concat_length( bool* xz_present_p ) const 154 { 155 if ( xz_present_p ) 156 *xz_present_p = m_flags & cf_xz_present ? true : false; 157 return m_len; 158 } 159 160 virtual void concat_clear_data( bool to_ones ) 161 { 162 m_left_p->concat_clear_data(to_ones); 163 m_right_p->concat_clear_data(to_ones); 164 } 165 166 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const 167 { 168 bool rnz = m_right_p->concat_get_ctrl( dst_p, low_i ); 169 bool lnz = m_left_p->concat_get_ctrl( dst_p, low_i+m_len_r ); 170 return rnz || lnz; 171 } 172 173 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const 174 { 175 bool rnz = m_right_p->concat_get_data( dst_p, low_i ); 176 bool lnz = m_left_p->concat_get_data( dst_p, low_i+m_len_r ); 177 return rnz || lnz; 178 } 179 180 virtual uint64 concat_get_uint64() const 181 { 182 if ( m_len_r >= 64 ) 183 return m_right_p->concat_get_uint64(); 184 else 185 { 186 return (m_left_p->concat_get_uint64() << m_len_r) | 187 m_right_p->concat_get_uint64(); 188 } 189 } 190 191 virtual void concat_set( int64 src, int low_i ) 192 { 193 m_right_p->concat_set( src, low_i ); 194 m_left_p->concat_set( src, low_i+m_len_r); 195 } 196 197 virtual void concat_set( const sc_signed& src, int low_i ) 198 { 199 m_right_p->concat_set( src, low_i ); 200 m_left_p->concat_set( src, low_i+m_len_r); 201 } 202 203 virtual void concat_set( const sc_unsigned& src, int low_i ) 204 { 205 m_right_p->concat_set( src, low_i ); 206 m_left_p->concat_set( src, low_i+m_len_r); 207 } 208 209 virtual void concat_set( uint64 src, int low_i ) 210 { 211 m_right_p->concat_set( src, low_i ); 212 m_left_p->concat_set( src, low_i+m_len_r); 213 } 214 215 216 // explicit conversions 217 218 uint64 to_uint64() const 219 { 220 uint64 mask; 221 uint64 result; 222 223 result = m_right_p->concat_get_uint64(); 224 if ( m_len_r < 64 ) 225 { 226 mask = (uint64)~0; 227 result = (m_left_p->concat_get_uint64() << m_len_r) | 228 (result & ~(mask << m_len_r)); 229 } 230 if ( m_len < 64 ) 231 { 232 mask = (uint64)~0; 233 result = result & ~(mask << m_len); 234 } 235 return result; 236 } 237 238 const sc_unsigned& value() const 239 { 240 bool left_non_zero; 241 sc_unsigned* result_p = sc_unsigned::m_pool.allocate(); 242 bool right_non_zero; 243 244 result_p->nbits = result_p->num_bits(m_len); 245 result_p->ndigits = DIV_CEIL(result_p->nbits); 246 result_p->digit = (sc_digit*)sc_core::sc_temp_heap.allocate( 247 sizeof(sc_digit)*result_p->ndigits ); 248#if defined(_MSC_VER) 249 // workaround spurious initialisation issue on MS Visual C++ 250 memset( result_p->digit, 0, sizeof(sc_digit)*result_p->ndigits ); 251#else 252 result_p->digit[result_p->ndigits-1] = 0; 253#endif 254 right_non_zero = m_right_p->concat_get_data( result_p->digit, 0 ); 255 left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r); 256 if ( left_non_zero || right_non_zero ) 257 result_p->sgn = SC_POS; 258 else 259 result_p->sgn = SC_ZERO; 260 return *result_p; 261 } 262 263 int64 to_int64() const 264 { 265 return (int64)to_uint64(); 266 } 267 int to_int() const 268 { return (int)to_int64(); } 269 unsigned int to_uint() const 270 { return (unsigned int)to_uint64(); } 271 long to_long() const 272 { return (long)to_int64(); } 273 unsigned long to_ulong() const 274 { return (unsigned long)to_uint64(); } 275 double to_double() const 276 { return value().to_double(); } 277 278 void to_sc_signed( sc_signed& target ) const 279 { target = value(); } 280 281 void to_sc_unsigned( sc_unsigned& target ) const 282 { target = value(); } 283 284 // implicit conversions: 285 286 operator uint64 () const 287 { return to_uint64(); } 288 289 operator const sc_unsigned& () const 290 { return value(); } 291 292 // unary operators: 293 294 sc_unsigned operator + () const 295 { return value(); } 296 297 sc_signed operator - () const 298 { return -value(); } 299 300 sc_unsigned operator ~ () const 301 { return ~value(); } 302 303 // explicit conversion to character string 304 305 const std::string to_string( sc_numrep numrep = SC_DEC ) const 306 { return value().to_string(numrep); } 307 308 const std::string to_string( sc_numrep numrep, bool w_prefix ) const 309 { return value().to_string(numrep,w_prefix); } 310 311 312 313 // assignments 314 315 inline const sc_concatref& operator = ( int v ) 316 { 317 m_right_p->concat_set((int64)v, 0); 318 m_left_p->concat_set((int64)v, m_len_r); 319 return *this; 320 } 321 322 inline const sc_concatref& operator = ( long v ) 323 { 324 m_right_p->concat_set((int64)v, 0); 325 m_left_p->concat_set((int64)v, m_len_r); 326 return *this; 327 } 328 329 inline const sc_concatref& operator = ( int64 v ) 330 { 331 m_right_p->concat_set(v, 0); 332 m_left_p->concat_set(v, m_len_r); 333 return *this; 334 } 335 336 inline const sc_concatref& operator = ( unsigned int v ) 337 { 338 m_right_p->concat_set((uint64)v, 0); 339 m_left_p->concat_set((uint64)v, m_len_r); 340 return *this; 341 } 342 343 inline const sc_concatref& operator = ( unsigned long v ) 344 { 345 m_right_p->concat_set((uint64)v, 0); 346 m_left_p->concat_set((uint64)v, m_len_r); 347 return *this; 348 } 349 350 inline const sc_concatref& operator = ( uint64 v ) 351 { 352 m_right_p->concat_set(v, 0); 353 m_left_p->concat_set(v, m_len_r); 354 return *this; 355 } 356 357 const sc_concatref& operator = ( const sc_concatref& v ) 358 { 359 sc_unsigned temp(v.length()); 360 temp = v.value(); 361 m_right_p->concat_set(temp, 0); 362 m_left_p->concat_set(temp, m_len_r); 363 return *this; 364 } 365 366 const sc_concatref& operator = ( const sc_signed& v ) 367 { 368 m_right_p->concat_set(v, 0); 369 m_left_p->concat_set(v, m_len_r); 370 return *this; 371 } 372 373 const sc_concatref& operator = ( const sc_unsigned& v ) 374 { 375 m_right_p->concat_set(v, 0); 376 m_left_p->concat_set(v, m_len_r); 377 return *this; 378 } 379 380 const sc_concatref& operator = ( const char* v_p ) 381 { 382 sc_unsigned v(m_len); 383 v = v_p; 384 m_right_p->concat_set(v, 0); 385 m_left_p->concat_set(v, m_len_r); 386 return *this; 387 } 388 389 const sc_concatref& operator = ( const sc_bv_base& v ) 390 { 391 sc_unsigned temp(v.length()); 392 temp = v; 393 m_right_p->concat_set(temp, 0); 394 m_left_p->concat_set(temp, m_len_r); 395 return *this; 396 } 397 398 const sc_concatref& operator = ( const sc_lv_base& v ) 399 { 400 sc_unsigned data(v.length()); 401 data = v; 402 m_right_p->concat_set(data, 0); 403 m_left_p->concat_set(data, m_len_r); 404 return *this; 405 } 406 407 408 // reduce methods 409 410 bool and_reduce() const 411 { return value().and_reduce(); } 412 413 bool nand_reduce() const 414 { return value().nand_reduce(); } 415 416 bool or_reduce() const 417 { return value().or_reduce(); } 418 419 bool nor_reduce() const 420 { return value().nor_reduce(); } 421 422 bool xor_reduce() const 423 { return value().xor_reduce(); } 424 425 bool xnor_reduce() const 426 { return value().xnor_reduce(); } 427 428 // other methods 429 430 void print( ::std::ostream& os = ::std::cout ) const 431 { os << this->value(); } 432 433 void scan( ::std::istream& is ) 434 { 435 std::string s; 436 is >> s; 437 *this = s.c_str(); 438 } 439 440public: 441 static sc_core::sc_vpool<sc_concatref> m_pool; // Pool of temporary objects. 442 443public: 444 enum concat_flags { 445 cf_none = 0, // Normal value. 446 cf_xz_present = 1 // X and/or Z values present. 447 }; 448 449protected: 450 sc_value_base* m_left_p; // Left hand operand of concatenation. 451 sc_value_base* m_right_p; // Right hand operand of concatenation. 452 int m_len; // Length of concatenation. 453 int m_len_r; // Length of m_rightt_p. 454 concat_flags m_flags; // Value is read only. 455 456private: 457 sc_concatref(const sc_concatref&); 458 sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags() 459 {} 460}; 461 462 463// functional notation for the reduce methods 464 465inline 466bool 467and_reduce( const sc_concatref& a ) 468{ 469 return a.and_reduce(); 470} 471 472inline 473bool 474nand_reduce( const sc_concatref& a ) 475{ 476 return a.nand_reduce(); 477} 478 479inline 480bool 481or_reduce( const sc_concatref& a ) 482{ 483 return a.or_reduce(); 484} 485 486inline 487bool 488nor_reduce( const sc_concatref& a ) 489{ 490 return a.nor_reduce(); 491} 492 493inline 494bool 495xor_reduce( const sc_concatref& a ) 496{ 497 return a.xor_reduce(); 498} 499 500inline 501bool 502xnor_reduce( const sc_concatref& a ) 503{ 504 return a.xnor_reduce(); 505} 506 507 508// SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES: 509// 510// Because sc_concatref has implicit casts to both uint64 and sc_unsigned 511// it is necessary to disambiguate the use of the shift operators. We do 512// this in favor of sc_unsigned so that precision is not lost. To get an 513// integer-based result use a cast to uint64 before performing the shift. 514 515inline const sc_unsigned operator << (const sc_concatref& target, uint64 shift) 516{ 517 return target.value() << (int)shift; 518} 519 520inline const sc_unsigned operator << (const sc_concatref& target, int64 shift) 521{ 522 return target.value() << (int)shift; 523} 524 525inline const sc_unsigned operator << ( 526 const sc_concatref& target, unsigned long shift ) 527{ 528 return target.value() << (int)shift; 529} 530 531inline const sc_unsigned operator << ( 532 const sc_concatref& target, int shift ) 533{ 534 return target.value() << shift; 535} 536 537inline const sc_unsigned operator << ( 538 const sc_concatref& target, unsigned int shift ) 539{ 540 return target.value() << (int)shift; 541} 542 543inline const sc_unsigned operator << ( const sc_concatref& target, long shift ) 544{ 545 return target.value() << (int)shift; 546} 547 548inline const sc_unsigned operator >> (const sc_concatref& target, uint64 shift) 549{ 550 return target.value() >> (int)shift; 551} 552 553inline const sc_unsigned operator >> (const sc_concatref& target, int64 shift) 554{ 555 return target.value() >> (int)shift; 556} 557 558inline const sc_unsigned operator >> ( 559 const sc_concatref& target, unsigned long shift ) 560{ 561 return target.value() >> (int)shift; 562} 563 564inline const sc_unsigned operator >> ( 565 const sc_concatref& target, int shift ) 566{ 567 return target.value() >> shift; 568} 569 570inline const sc_unsigned operator >> ( 571 const sc_concatref& target, unsigned int shift ) 572{ 573 return target.value() >> (int)shift; 574} 575 576inline const sc_unsigned operator >> ( const sc_concatref& target, long shift ) 577{ 578 return target.value() >> (int)shift; 579} 580 581 582// STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES: 583 584inline 585::std::ostream& 586operator << ( ::std::ostream& os, const sc_concatref& v ) 587{ 588 return os << v.value(); 589} 590 591inline 592::std::istream& 593operator >> ( ::std::istream& is, sc_concatref& a ) 594{ 595 sc_unsigned temp(a.concat_length(0)); 596 temp.scan( is ); 597 a = temp; 598 return is; 599} 600 601 602// ---------------------------------------------------------------------------- 603// CLASS TEMPLATE : sc_concat_bool 604// 605// Proxy class for read-only boolean values in concatenations. 606// ---------------------------------------------------------------------------- 607 608class sc_concat_bool : public sc_value_base 609{ 610 protected: 611 static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool. 612 bool m_value; // Value for this obj. 613 614 public: 615 616 // constructor: 617 618 sc_concat_bool() 619 : sc_value_base(), m_value() 620 {} 621 622 // destructor: 623 624 virtual ~sc_concat_bool() 625 { } 626 627 // allocation of temporary object: 628 629 static inline sc_concat_bool* allocate( bool v ) 630 { 631 sc_concat_bool* result_p = m_pool.allocate(); 632 result_p->m_value = v; 633 return result_p; 634 } 635 636 // concatenation: 637 638 virtual int concat_length( bool* xz_present_p ) const 639 { 640 if ( xz_present_p ) *xz_present_p = false; 641 return 1; 642 } 643 644 virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const 645 { 646 int bit = 1 << (low_i % BITS_PER_DIGIT); 647 int word_i = low_i / BITS_PER_DIGIT; 648 dst_p[word_i] &= ~bit; 649 return false; 650 } 651 652 virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const 653 { 654 int bit = 1 << (low_i % BITS_PER_DIGIT); 655 int word_i = low_i / BITS_PER_DIGIT; 656 if ( m_value ) 657 dst_p[word_i] |= bit; 658 else 659 dst_p[word_i] &= ~bit; 660 return m_value; 661 } 662 663 virtual uint64 concat_get_uint64() const 664 { 665 return m_value ? 1 : 0; 666 } 667}; 668 669 670// ---------------------------------------------------------------------------- 671// ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref 672// ---------------------------------------------------------------------------- 673 674#define SC_CONCAT_OP_TYPE(RESULT,OP,OTHER_TYPE) \ 675 inline RESULT operator OP ( const sc_concatref& a, OTHER_TYPE b ) \ 676 { \ 677 return a.value() OP b; \ 678 } \ 679 inline RESULT operator OP ( OTHER_TYPE a, const sc_concatref& b ) \ 680 { \ 681 return a OP b.value(); \ 682 } 683 684 685#define SC_CONCAT_OP(RESULT,OP) \ 686 inline RESULT operator OP ( const sc_concatref& a, const sc_concatref& b ) \ 687 { \ 688 return a.value() OP b.value(); \ 689 } \ 690 SC_CONCAT_OP_TYPE(const sc_signed,OP,int) \ 691 SC_CONCAT_OP_TYPE(const sc_signed,OP,long) \ 692 SC_CONCAT_OP_TYPE(const sc_signed,OP,int64) \ 693 SC_CONCAT_OP_TYPE(RESULT,OP,unsigned int) \ 694 SC_CONCAT_OP_TYPE(RESULT,OP,unsigned long) \ 695 SC_CONCAT_OP_TYPE(RESULT,OP,uint64) \ 696 SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_int_base&) \ 697 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_uint_base&) \ 698 SC_CONCAT_OP_TYPE(const sc_signed,OP,const sc_signed&) \ 699 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_unsigned&) \ 700 inline RESULT operator OP ( const sc_concatref& a, bool b ) \ 701 { \ 702 return a.value() OP (int)b; \ 703 } \ 704 inline RESULT operator OP ( bool a, const sc_concatref& b ) \ 705 { \ 706 return (int)a OP b.value(); \ 707 } 708 709#define SC_CONCAT_BOOL_OP(OP) \ 710 inline bool operator OP ( const sc_concatref& a, const sc_concatref& b ) \ 711 { \ 712 return a.value() OP b.value(); \ 713 } \ 714 SC_CONCAT_OP_TYPE(bool,OP,int) \ 715 SC_CONCAT_OP_TYPE(bool,OP,long) \ 716 SC_CONCAT_OP_TYPE(bool,OP,int64) \ 717 SC_CONCAT_OP_TYPE(bool,OP,unsigned int) \ 718 SC_CONCAT_OP_TYPE(bool,OP,unsigned long) \ 719 SC_CONCAT_OP_TYPE(bool,OP,uint64) \ 720 SC_CONCAT_OP_TYPE(bool,OP,const sc_int_base&) \ 721 SC_CONCAT_OP_TYPE(bool,OP,const sc_uint_base&) \ 722 SC_CONCAT_OP_TYPE(bool,OP,const sc_signed&) \ 723 SC_CONCAT_OP_TYPE(bool,OP,const sc_unsigned&) \ 724 inline bool operator OP ( const sc_concatref& a, bool b ) \ 725 { \ 726 return a.value() OP (int)b; \ 727 } \ 728 inline bool operator OP ( bool a, const sc_concatref& b ) \ 729 { \ 730 return (int)a OP b.value(); \ 731 } 732 733SC_CONCAT_OP(const sc_unsigned,+) 734SC_CONCAT_OP(const sc_signed,-) 735SC_CONCAT_OP(const sc_unsigned,*) 736SC_CONCAT_OP(const sc_unsigned,/) 737SC_CONCAT_OP(const sc_unsigned,%) 738SC_CONCAT_OP(const sc_unsigned,&) 739SC_CONCAT_OP(const sc_unsigned,|) 740SC_CONCAT_OP(const sc_unsigned,^) 741SC_CONCAT_BOOL_OP(==) 742SC_CONCAT_BOOL_OP(<=) 743SC_CONCAT_BOOL_OP(>=) 744SC_CONCAT_BOOL_OP(!=) 745SC_CONCAT_BOOL_OP(>) 746SC_CONCAT_BOOL_OP(<) 747 748#undef SC_CONCAT_OP 749#undef SC_CONCAT_OP_TYPE 750 751 752// ---------------------------------------------------------------------------- 753// CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES: 754// ---------------------------------------------------------------------------- 755 756inline sc_dt::sc_concatref& concat( 757 sc_dt::sc_value_base& a, sc_dt::sc_value_base& b) 758{ 759 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 760 761 result_p = sc_dt::sc_concatref::m_pool.allocate(); 762 result_p->initialize( a, b ); 763 return *result_p; 764} 765 766inline 767const 768sc_dt::sc_concatref& concat( 769 const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b) 770{ 771 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 772 773 result_p = sc_dt::sc_concatref::m_pool.allocate(); 774 result_p->initialize( a, b ); 775 return *result_p; 776} 777 778inline 779const 780sc_dt::sc_concatref& concat(const sc_dt::sc_value_base& a, bool b) 781{ 782 const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value. 783 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 784 785 b_p = sc_dt::sc_concat_bool::allocate(b); 786 result_p = sc_dt::sc_concatref::m_pool.allocate(); 787 result_p->initialize( a, *b_p ); 788 return *result_p; 789} 790 791inline 792const 793sc_dt::sc_concatref& concat(bool a, const sc_dt::sc_value_base& b) 794{ 795 const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value. 796 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 797 798 a_p = sc_dt::sc_concat_bool::allocate(a); 799 result_p = sc_dt::sc_concatref::m_pool.allocate(); 800 result_p->initialize( *a_p, b ); 801 return *result_p; 802} 803 804inline sc_dt::sc_concatref& operator , ( 805 sc_dt::sc_value_base& a, sc_dt::sc_value_base& b) 806{ 807 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 808 809 result_p = sc_dt::sc_concatref::m_pool.allocate(); 810 result_p->initialize( a, b ); 811 return *result_p; 812} 813 814inline 815const 816sc_dt::sc_concatref& operator , ( 817 const sc_dt::sc_value_base& a, const sc_dt::sc_value_base& b) 818{ 819 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 820 821 result_p = sc_dt::sc_concatref::m_pool.allocate(); 822 result_p->initialize( a, b ); 823 return *result_p; 824} 825 826inline 827const 828sc_dt::sc_concatref& operator , (const sc_dt::sc_value_base& a, bool b) 829{ 830 const sc_dt::sc_concat_bool* b_p; // Proxy for boolean value. 831 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 832 833 b_p = sc_dt::sc_concat_bool::allocate(b); 834 result_p = sc_dt::sc_concatref::m_pool.allocate(); 835 result_p->initialize( a, *b_p ); 836 return *result_p; 837} 838 839inline 840const 841sc_dt::sc_concatref& operator , (bool a, const sc_dt::sc_value_base& b) 842{ 843 const sc_dt::sc_concat_bool* a_p; // Proxy for boolean value. 844 sc_dt::sc_concatref* result_p; // Proxy for the concatenation. 845 846 a_p = sc_dt::sc_concat_bool::allocate(a); 847 result_p = sc_dt::sc_concatref::m_pool.allocate(); 848 result_p->initialize( *a_p, b ); 849 return *result_p; 850} 851 852} // namespace sc_dt 853 854#endif // SC_CONCATREF_H 855 856