00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef SC_CONCATREF_H
00044 #define SC_CONCATREF_H
00045
00046 #include "systemc/kernel/sc_object.h"
00047 #include "systemc/datatypes/misc/sc_value_base.h"
00048 #include "systemc/utils/sc_temporary.h"
00049 #include "systemc/datatypes/bit/sc_bv.h"
00050 #include "systemc/datatypes/bit/sc_lv.h"
00051 #include "systemc/datatypes/int/sc_int_base.h"
00052 #include "systemc/datatypes/int/sc_uint_base.h"
00053 #include "systemc/datatypes/int/sc_signed.h"
00054 #include "systemc/datatypes/int/sc_unsigned.h"
00055
00056
00057
00058
00059 #define CONCONST
00060
00061 extern sc_byte_heap sc_temp_heap;
00062
00063 namespace sc_dt
00064 {
00065
00066
00067
00068
00069
00070
00071
00072 class sc_concatref : public sc_value_base
00073 {
00074 public:
00075
00076
00077
00078 sc_concatref( )
00079 { }
00080
00081 inline void initialize(
00082 sc_value_base& left, sc_value_base& right )
00083 {
00084 bool left_xz;
00085 bool right_xz;
00086
00087 m_left_p = (sc_value_base*)&left;
00088 m_right_p = (sc_value_base*)&right;
00089 m_len_r = right.concat_length(&right_xz);
00090 m_len = left.concat_length(&left_xz) + m_len_r;
00091 m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none;
00092 }
00093
00094
00095 inline void initialize(
00096 const sc_value_base& left, const sc_value_base& right )
00097 {
00098 bool left_xz;
00099 bool right_xz;
00100
00101 m_left_p = (sc_value_base*)&left;
00102 m_right_p = (sc_value_base*)&right;
00103 m_len_r = right.concat_length(&right_xz);
00104 m_len = left.concat_length(&left_xz) + m_len_r;
00105 m_flags = ( left_xz || right_xz ) ? cf_xz_present : cf_none;
00106 }
00107
00108
00109
00110 virtual ~sc_concatref()
00111 {}
00112
00113
00114
00115
00116 int length() const
00117 { return m_len; }
00118
00119 #ifdef SC_DT_DEPRECATED
00120 int bitwidth() const
00121 { return length(); }
00122 #endif
00123
00124
00125
00126 virtual int concat_length( bool* xz_present_p ) const
00127 {
00128 if ( xz_present_p )
00129 *xz_present_p = m_flags & cf_xz_present ? true : false;
00130 return m_len;
00131 }
00132
00133 virtual void concat_clear_data( bool to_ones )
00134 {
00135 m_left_p->concat_clear_data(to_ones);
00136 m_right_p->concat_clear_data(to_ones);
00137 }
00138
00139 virtual bool concat_get_ctrl( unsigned long* dst_p, int low_i ) const
00140 {
00141 bool rnz = m_right_p->concat_get_ctrl( dst_p, low_i );
00142 bool lnz = m_left_p->concat_get_ctrl( dst_p, low_i+m_len_r );
00143 return rnz || lnz;
00144 }
00145
00146 virtual bool concat_get_data( unsigned long* dst_p, int low_i ) const
00147 {
00148 bool rnz = m_right_p->concat_get_data( dst_p, low_i );
00149 bool lnz = m_left_p->concat_get_data( dst_p, low_i+m_len_r );
00150 return rnz || lnz;
00151 }
00152
00153 virtual uint64 concat_get_uint64() const
00154 {
00155 if ( m_len_r >= 64 )
00156 return m_right_p->concat_get_uint64();
00157 else
00158 {
00159 return (m_left_p->concat_get_uint64() << m_len_r) |
00160 m_right_p->concat_get_uint64();
00161 }
00162 }
00163
00164 virtual void concat_set( int64 src, int low_i )
00165 {
00166 m_right_p->concat_set( src, low_i );
00167 m_left_p->concat_set( src, low_i+m_len_r);
00168 }
00169
00170 virtual void concat_set( const sc_signed& src, int low_i )
00171 {
00172 m_right_p->concat_set( src, low_i );
00173 m_left_p->concat_set( src, low_i+m_len_r);
00174 }
00175
00176 virtual void concat_set( const sc_unsigned& src, int low_i )
00177 {
00178 m_right_p->concat_set( src, low_i );
00179 m_left_p->concat_set( src, low_i+m_len_r);
00180 }
00181
00182 virtual void concat_set( uint64 src, int low_i )
00183 {
00184 m_right_p->concat_set( src, low_i );
00185 m_left_p->concat_set( src, low_i+m_len_r);
00186 }
00187
00188
00189
00190
00191 uint64 to_uint64() const
00192 {
00193 uint64 mask;
00194 uint64 result;
00195
00196 result = m_right_p->concat_get_uint64();
00197 if ( m_len_r < 64 )
00198 {
00199 mask = ~0;
00200 result = (m_left_p->concat_get_uint64() << m_len_r) |
00201 (result & ~(mask << m_len_r));
00202 }
00203 if ( m_len < 64 )
00204 {
00205 mask = ~0;
00206 result = result & ~(mask << m_len);
00207 }
00208 return result;
00209 }
00210
00211 const sc_unsigned& to_sc_unsigned() const
00212 {
00213 bool left_non_zero;
00214 sc_unsigned* result_p = sc_unsigned::m_pool.allocate();
00215 bool right_non_zero;
00216
00217 result_p->nbits = result_p->num_bits(m_len);
00218 result_p->ndigits = (result_p->nbits+BITS_PER_DIGIT-1) /
00219 BITS_PER_DIGIT;
00220 result_p->digit = (unsigned long*)
00221 sc_temp_heap.allocate( 4*result_p->ndigits );
00222 right_non_zero = m_right_p->concat_get_data( result_p->digit, 0 );
00223 left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r);
00224 if ( left_non_zero || right_non_zero )
00225 result_p->sgn = SC_POS;
00226 else
00227 result_p->sgn = SC_ZERO;
00228 return *result_p;
00229 }
00230
00231
00232
00233 const sc_unsigned& value() const
00234 { return to_sc_unsigned(); }
00235 int64 to_int64() const
00236 {
00237
00238
00239
00240
00241 return (int64)to_uint64();
00242 }
00243 int to_int() const
00244 { return (int)to_int64(); }
00245 unsigned int to_uint() const
00246 { return (unsigned int)to_uint64(); }
00247 long to_long() const
00248 { return (long)to_int64(); }
00249 unsigned long to_ulong() const
00250 { return (unsigned long)to_uint64(); }
00251 double to_double() const
00252 { return to_sc_unsigned().to_double(); }
00253
00254
00255
00256 operator uint64 () const
00257 { return to_uint64(); }
00258
00259 operator const sc_unsigned& () const
00260 { return to_sc_unsigned(); }
00261
00262
00263
00264 sc_unsigned operator + () const
00265 { return to_sc_unsigned(); }
00266
00267 sc_unsigned operator - () const
00268 { return -to_sc_unsigned(); }
00269
00270 sc_unsigned operator ~ () const
00271 { return ~to_sc_unsigned(); }
00272
00273
00274
00275 const sc_string to_string( sc_numrep numrep = SC_DEC ) const;
00276 const sc_string to_string( sc_numrep numrep, bool w_prefix ) const;
00277
00278
00279
00280
00281 inline const sc_concatref& operator = ( int v )
00282 {
00283 m_right_p->concat_set((int64)v, 0);
00284 m_left_p->concat_set((int64)v, m_len_r);
00285 return *this;
00286 }
00287
00288 inline const sc_concatref& operator = ( long v )
00289 {
00290 m_right_p->concat_set((int64)v, 0);
00291 m_left_p->concat_set((int64)v, m_len_r);
00292 return *this;
00293 }
00294
00295 inline const sc_concatref& operator = ( int64 v )
00296 {
00297 m_right_p->concat_set(v, 0);
00298 m_left_p->concat_set(v, m_len_r);
00299 return *this;
00300 }
00301
00302 inline const sc_concatref& operator = ( unsigned int v )
00303 {
00304 m_right_p->concat_set((uint64)v, 0);
00305 m_left_p->concat_set((uint64)v, m_len_r);
00306 return *this;
00307 }
00308
00309 inline const sc_concatref& operator = ( unsigned long v )
00310 {
00311 m_right_p->concat_set((uint64)v, 0);
00312 m_left_p->concat_set((uint64)v, m_len_r);
00313 return *this;
00314 }
00315
00316 inline const sc_concatref& operator = ( uint64 v )
00317 {
00318 m_right_p->concat_set(v, 0);
00319 m_left_p->concat_set(v, m_len_r);
00320 return *this;
00321 }
00322
00323 const sc_concatref& operator = ( const sc_concatref& v )
00324 {
00325 sc_unsigned temp(v.length());
00326 temp = v.to_sc_unsigned();
00327 m_right_p->concat_set(temp, 0);
00328 m_left_p->concat_set(temp, m_len_r);
00329 return *this;
00330 }
00331
00332 const sc_concatref& operator = ( const sc_signed& v )
00333 {
00334 m_right_p->concat_set(v, 0);
00335 m_left_p->concat_set(v, m_len_r);
00336 return *this;
00337 }
00338
00339 const sc_concatref& operator = ( const sc_unsigned& v )
00340 {
00341 m_right_p->concat_set(v, 0);
00342 m_left_p->concat_set(v, m_len_r);
00343 return *this;
00344 }
00345
00346 const sc_concatref& operator = ( const char* v_p )
00347 {
00348 sc_unsigned v(strlen(v_p));
00349 v = v_p;
00350 m_right_p->concat_set(v, 0);
00351 m_left_p->concat_set(v, m_len_r);
00352 return *this;
00353 }
00354
00355 const sc_concatref& operator = ( const sc_bv_base& v )
00356 {
00357 sc_unsigned temp(v.length());
00358 temp = v;
00359 m_right_p->concat_set(temp, 0);
00360 m_left_p->concat_set(temp, m_len_r);
00361 return *this;
00362 }
00363
00364 const sc_concatref& operator = ( const sc_lv_base& v )
00365 {
00366 sc_unsigned data(v.length());
00367 data = v;
00368 m_right_p->concat_set(data, 0);
00369 m_left_p->concat_set(data, m_len_r);
00370 return *this;
00371 }
00372
00373
00374
00375
00376 bool and_reduce() const
00377 { return to_sc_unsigned().and_reduce(); }
00378
00379 bool nand_reduce() const
00380 { return to_sc_unsigned().nand_reduce(); }
00381
00382 bool or_reduce() const
00383 { return to_sc_unsigned().or_reduce(); }
00384
00385 bool nor_reduce() const
00386 { return to_sc_unsigned().nor_reduce(); }
00387
00388 bool xor_reduce() const
00389 { return to_sc_unsigned().xor_reduce(); }
00390
00391 bool xnor_reduce() const
00392 { return to_sc_unsigned().xnor_reduce(); }
00393
00394
00395
00396 void print( ostream& os = cout ) const
00397 { os << this->to_sc_unsigned(); }
00398
00399 public:
00400 static sc_vpool<sc_concatref> m_pool;
00401
00402 public:
00403 enum concat_flags {
00404 cf_none = 0,
00405 cf_read_only = 1,
00406 cf_xz_present = 2
00407 };
00408
00409 protected:
00410 sc_value_base* m_left_p;
00411 sc_value_base* m_right_p;
00412 int m_len;
00413 int m_len_r;
00414 concat_flags m_flags;
00415 };
00416
00417
00418
00419
00420 inline
00421 bool
00422 and_reduce( const sc_concatref& a )
00423 {
00424 return a.and_reduce();
00425 }
00426
00427 inline
00428 bool
00429 nand_reduce( const sc_concatref& a )
00430 {
00431 return a.nand_reduce();
00432 }
00433
00434 inline
00435 bool
00436 or_reduce( const sc_concatref& a )
00437 {
00438 return a.or_reduce();
00439 }
00440
00441 inline
00442 bool
00443 nor_reduce( const sc_concatref& a )
00444 {
00445 return a.nor_reduce();
00446 }
00447
00448 inline
00449 bool
00450 xor_reduce( const sc_concatref& a )
00451 {
00452 return a.xor_reduce();
00453 }
00454
00455 inline
00456 bool
00457 xnor_reduce( const sc_concatref& a )
00458 {
00459 return a.xnor_reduce();
00460 }
00461
00462
00463
00464
00465
00466 inline
00467 ostream&
00468 operator << ( ostream& os, const sc_concatref& v )
00469 {
00470 return os << v.to_sc_unsigned();
00471 }
00472
00473 inline
00474 istream&
00475 operator >> ( istream& is, sc_concatref& a )
00476 {
00477 sc_unsigned temp(a.concat_length(0));
00478 temp.scan( is );
00479 a = temp;
00480 return is;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490 class sc_concat_bool : public sc_value_base
00491 {
00492 protected:
00493 static sc_vpool<sc_concat_bool> m_pool;
00494 bool m_value;
00495
00496 public:
00497
00498
00499
00500 virtual ~sc_concat_bool()
00501 { }
00502
00503
00504
00505 static inline sc_concat_bool* allocate( bool v )
00506 {
00507 sc_concat_bool* result_p = m_pool.allocate();
00508 result_p->m_value = v;
00509 return result_p;
00510 }
00511
00512
00513
00514 virtual int concat_length( bool* xz_present_p ) const
00515 {
00516 if ( xz_present_p ) *xz_present_p = false;
00517 return 1;
00518 }
00519
00520 virtual bool concat_get_ctrl( unsigned long* dst_p, int low_i ) const
00521 {
00522 int bit = 1 << (low_i % BITS_PER_DIGIT);
00523 int word_i = low_i / BITS_PER_DIGIT;
00524 dst_p[word_i] &= ~bit;
00525 return false;
00526 }
00527
00528 virtual bool concat_get_data( unsigned long* dst_p, int low_i ) const
00529 {
00530 int bit = 1 << (low_i % BITS_PER_DIGIT);
00531 int word_i = low_i / BITS_PER_DIGIT;
00532 if ( m_value )
00533 dst_p[word_i] |= bit;
00534 else
00535 dst_p[word_i] &= ~bit;
00536 return m_value;
00537 }
00538
00539 virtual uint64 concat_get_uint64() const
00540 {
00541 return m_value ? 1 : 0;
00542 }
00543 };
00544
00545
00546
00547
00548
00549
00550 inline sc_concatref& concat(sc_value_base& a, sc_value_base& b)
00551 {
00552 sc_concatref* result_p;
00553
00554 result_p = sc_concatref::m_pool.allocate();
00555 result_p->initialize( a, b );
00556 return *result_p;
00557 }
00558
00559 inline
00560 CONCONST
00561 sc_concatref& concat(const sc_value_base& a, const sc_value_base& b)
00562 {
00563 sc_concatref* result_p;
00564
00565 result_p = sc_concatref::m_pool.allocate();
00566 result_p->initialize( a, b );
00567 return *result_p;
00568 }
00569
00570 inline
00571 CONCONST
00572 sc_concatref& concat(const sc_value_base& a, bool b)
00573 {
00574 const sc_concat_bool* b_p;
00575 sc_concatref* result_p;
00576
00577 b_p = sc_concat_bool::allocate(b);
00578 result_p = sc_concatref::m_pool.allocate();
00579 result_p->initialize( a, *b_p );
00580 return *result_p;
00581 }
00582
00583 inline
00584 CONCONST
00585 sc_concatref& concat(bool a, const sc_value_base& b)
00586 {
00587 const sc_concat_bool* a_p;
00588 sc_concatref* result_p;
00589
00590 a_p = sc_concat_bool::allocate(a);
00591 result_p = sc_concatref::m_pool.allocate();
00592 result_p->initialize( *a_p, b );
00593 return *result_p;
00594 }
00595
00596 inline sc_concatref& operator , (sc_value_base& a, sc_value_base& b)
00597 {
00598 sc_concatref* result_p;
00599
00600 result_p = sc_concatref::m_pool.allocate();
00601 result_p->initialize( a, b );
00602 return *result_p;
00603 }
00604
00605 inline
00606 CONCONST
00607 sc_concatref& operator , (const sc_value_base& a, const sc_value_base& b)
00608 {
00609 sc_concatref* result_p;
00610
00611 result_p = sc_concatref::m_pool.allocate();
00612 result_p->initialize( a, b );
00613 return *result_p;
00614 }
00615
00616 inline
00617 CONCONST
00618 sc_concatref& operator , (const sc_value_base& a, bool b)
00619 {
00620 const sc_concat_bool* b_p;
00621 sc_concatref* result_p;
00622
00623 b_p = sc_concat_bool::allocate(b);
00624 result_p = sc_concatref::m_pool.allocate();
00625 result_p->initialize( a, *b_p );
00626 return *result_p;
00627 }
00628
00629 inline
00630 CONCONST
00631 sc_concatref& operator , (bool a, const sc_value_base& b)
00632 {
00633 const sc_concat_bool* a_p;
00634 sc_concatref* result_p;
00635
00636 a_p = sc_concat_bool::allocate(a);
00637 result_p = sc_concatref::m_pool.allocate();
00638 result_p->initialize( *a_p, b );
00639 return *result_p;
00640 }
00641
00642
00643
00644
00645
00646
00647 #define SC_CONCAT_OP_TYPE(RESULT,OP,OTHER_TYPE) \
00648 inline RESULT operator OP ( const sc_concatref& a, OTHER_TYPE b ) \
00649 { \
00650 return a.to_sc_unsigned() OP b; \
00651 } \
00652 inline RESULT operator OP ( OTHER_TYPE a, const sc_concatref& b ) \
00653 { \
00654 return a OP b.to_sc_unsigned(); \
00655 }
00656
00657
00658 #define SC_CONCAT_OP(RESULT,OP) \
00659 inline RESULT operator OP ( const sc_concatref& a, const sc_concatref& b ) \
00660 { \
00661 return a.to_sc_unsigned() OP b.to_sc_unsigned(); \
00662 } \
00663 SC_CONCAT_OP_TYPE(RESULT,OP,int) \
00664 SC_CONCAT_OP_TYPE(RESULT,OP,long) \
00665 SC_CONCAT_OP_TYPE(RESULT,OP,int64) \
00666 SC_CONCAT_OP_TYPE(RESULT,OP,unsigned int) \
00667 SC_CONCAT_OP_TYPE(RESULT,OP,unsigned long) \
00668 SC_CONCAT_OP_TYPE(RESULT,OP,uint64) \
00669 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_int_base&) \
00670 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_uint_base&) \
00671 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_signed&) \
00672 SC_CONCAT_OP_TYPE(RESULT,OP,const sc_unsigned&) \
00673 inline RESULT operator OP ( const sc_concatref& a, bool b ) \
00674 { \
00675 return a.to_sc_unsigned() OP (int)b; \
00676 } \
00677 inline RESULT operator OP ( bool a, const sc_concatref& b ) \
00678 { \
00679 return (int)a OP b.to_sc_unsigned(); \
00680 }
00681
00682 SC_CONCAT_OP(const sc_unsigned,+)
00683 SC_CONCAT_OP(const sc_unsigned,-)
00684 SC_CONCAT_OP(const sc_unsigned,*)
00685 SC_CONCAT_OP(const sc_unsigned,/)
00686 SC_CONCAT_OP(const sc_unsigned,%)
00687 SC_CONCAT_OP(const sc_unsigned,&)
00688 SC_CONCAT_OP(const sc_unsigned,|)
00689 SC_CONCAT_OP(const sc_unsigned,^)
00690 SC_CONCAT_OP(bool,==)
00691 SC_CONCAT_OP(bool,<=)
00692 SC_CONCAT_OP(bool,>=)
00693 SC_CONCAT_OP(bool,!=)
00694 SC_CONCAT_OP(bool,>)
00695 SC_CONCAT_OP(bool,<)
00696
00697 #undef SC_CONCAT_OP
00698 #undef SC_CONCAT_OP_TYPE
00699
00700 #undef CONCONST
00701
00702 }
00703
00704 #endif // SC_CONCATREF_H
00705