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