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
00053
00054
00055
00056
00057
00058
00059
00060
00061 #ifndef SC_NBUTILS_H
00062 #define SC_NBUTILS_H
00063
00064 #include <cmath>
00065 #include <limits>
00066
00067 #include "sysc/datatypes/bit/sc_bit_ids.h"
00068 #include "sysc/datatypes/int/sc_int_ids.h"
00069 #include "sysc/datatypes/int/sc_nbdefs.h"
00070 #include "sysc/utils/sc_report.h"
00071
00072
00073 namespace sc_dt
00074 {
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 #if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC)
00090 inline sc_numrep
00091 sc_io_base( systemc_ostream& os, sc_numrep def_base )
00092 {
00093 std::ios::fmtflags flags = os.flags() & std::ios::basefield;
00094 if ( flags & ::std::ios::dec ) return SC_DEC;
00095 if ( flags & ::std::ios::hex ) return SC_HEX;
00096 if ( flags & ::std::ios::oct ) return SC_OCT;
00097 return def_base;
00098 }
00099
00100 inline bool
00101 sc_io_show_base( systemc_ostream& os )
00102 {
00103 return (os.flags() & ::std::ios::showbase) != 0 ;
00104 }
00105 #else // Other
00106 inline sc_numrep
00107 sc_io_base( systemc_ostream& , sc_numrep )
00108 {
00109 return SC_DEC;
00110 }
00111 inline bool
00112 sc_io_show_base( systemc_ostream& )
00113 {
00114 return false;
00115 }
00116 #endif
00117
00118 const std::string to_string( sc_numrep );
00119
00120 inline
00121 systemc_ostream&
00122 operator << ( systemc_ostream& os, sc_numrep numrep )
00123 {
00124 os << to_string( numrep );
00125 return os;
00126 }
00127
00128
00129 inline void
00130 is_valid_base(sc_numrep base)
00131 {
00132 switch (base) {
00133 case SC_NOBASE: case SC_BIN:
00134 case SC_OCT: case SC_DEC:
00135 case SC_HEX:
00136 break;
00137 case SC_BIN_US: case SC_BIN_SM:
00138 case SC_OCT_US: case SC_OCT_SM:
00139 case SC_HEX_US: case SC_HEX_SM:
00140 case SC_CSD:
00141 SC_REPORT_ERROR( sc_core::SC_ID_NOT_IMPLEMENTED_,
00142 "is_valid_base( sc_numrep base ) : "
00143 "bases SC_CSD, or ending in _US and _SM are not supported" );
00144 break;
00145 default:
00146 char msg[BUFSIZ];
00147 std::sprintf( msg, "is_valid_base( sc_numrep base ) : "
00148 "base = %s is not valid",
00149 to_string( base ).c_str() );
00150 SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
00151 }
00152 }
00153
00154
00155
00156
00157 extern
00158 small_type
00159 fsm_move(char c, small_type &b, small_type &s, small_type &state);
00160
00161
00162 extern
00163 void parse_binary_bits(
00164 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
00165 );
00166
00167
00168
00169 extern
00170 void parse_hex_bits(
00171 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
00172 );
00173
00174
00175
00176 extern
00177 const char *
00178 get_base_and_sign(const char *v, small_type &base, small_type &sign);
00179
00180
00181 extern
00182 small_type
00183 vec_from_str(int unb, int und, sc_digit *u,
00184 const char *v, sc_numrep base = SC_NOBASE) ;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 extern
00202 void
00203 vec_add(int ulen, const sc_digit *u,
00204 int vlen, const sc_digit *v, sc_digit *w);
00205
00206 extern
00207 void
00208 vec_add_on(int ulen, sc_digit *u,
00209 int vlen, const sc_digit *v);
00210
00211 extern
00212 void
00213 vec_add_on2(int ulen, sc_digit *u,
00214 int vlen, const sc_digit *v);
00215
00216 extern
00217 void
00218 vec_add_small(int ulen, const sc_digit *u,
00219 sc_digit v, sc_digit *w);
00220
00221 extern
00222 void
00223 vec_add_small_on(int ulen, sc_digit *u, sc_digit v);
00224
00225
00226
00227
00228
00229
00230 extern
00231 void
00232 vec_sub(int ulen, const sc_digit *u,
00233 int vlen, const sc_digit *v, sc_digit *w);
00234
00235 extern
00236 void
00237 vec_sub_on(int ulen, sc_digit *u,
00238 int vlen, const sc_digit *v);
00239
00240 extern
00241 void
00242 vec_sub_on2(int ulen, sc_digit *u,
00243 int vlen, const sc_digit *v);
00244
00245 extern
00246 void
00247 vec_sub_small(int ulen, const sc_digit *u,
00248 sc_digit v, sc_digit *w);
00249
00250 extern
00251 void
00252 vec_sub_small_on(int ulen, sc_digit *u, sc_digit v);
00253
00254
00255
00256
00257
00258
00259 extern
00260 void
00261 vec_mul(int ulen, const sc_digit *u,
00262 int vlen, const sc_digit *v, sc_digit *w);
00263
00264 extern
00265 void
00266 vec_mul_small(int ulen, const sc_digit *u,
00267 sc_digit v, sc_digit *w);
00268
00269 extern
00270 void
00271 vec_mul_small_on(int ulen, sc_digit *u, sc_digit v);
00272
00273
00274
00275
00276
00277
00278 extern
00279 void
00280 vec_div_large(int ulen, const sc_digit *u,
00281 int vlen, const sc_digit *v, sc_digit *w);
00282
00283 extern
00284 void
00285 vec_div_small(int ulen, const sc_digit *u,
00286 sc_digit v, sc_digit *w);
00287
00288
00289
00290
00291
00292
00293 extern
00294 void
00295 vec_rem_large(int ulen, const sc_digit *u,
00296 int vlen, const sc_digit *v, sc_digit *w);
00297
00298 extern
00299 sc_digit
00300 vec_rem_small(int ulen, const sc_digit *u, sc_digit v);
00301
00302 extern
00303 sc_digit
00304 vec_rem_on_small(int ulen, sc_digit *u, sc_digit v);
00305
00306
00307
00308
00309
00310
00311 extern
00312 int
00313 vec_to_char(int ulen, const sc_digit *u,
00314 int vlen, uchar *v);
00315
00316 extern
00317 void
00318 vec_from_char(int ulen, const uchar *u,
00319 int vlen, sc_digit *v);
00320
00321
00322
00323
00324
00325
00326 extern
00327 void
00328 vec_shift_left(int ulen, sc_digit *u, int nsl);
00329
00330 extern
00331 void
00332 vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill = 0);
00333
00334 extern
00335 void
00336 vec_reverse(int unb, int und, sc_digit *ud,
00337 int l, int r = 0);
00338
00339
00340
00341
00342
00343
00344
00345 inline
00346 sc_digit
00347 low_half(sc_digit d)
00348 {
00349 return (d & HALF_DIGIT_MASK);
00350 }
00351
00352
00353
00354
00355
00356
00357 inline
00358 sc_digit
00359 high_half(sc_digit d)
00360 {
00361 return (d >> BITS_PER_HALF_DIGIT);
00362 }
00363
00364 inline
00365 sc_digit
00366 high_half_masked(sc_digit d)
00367 {
00368 return (high_half(d) & HALF_DIGIT_MASK);
00369 }
00370
00371
00372
00373 inline
00374 sc_digit
00375 concat(sc_digit h, sc_digit l)
00376 {
00377 return ((h << BITS_PER_HALF_DIGIT) | l);
00378 }
00379
00380
00381 inline
00382 sc_digit
00383 one_and_ones(int n)
00384 {
00385 return (((sc_digit) 1 << n) - 1);
00386 }
00387
00388
00389 inline
00390 sc_digit
00391 one_and_zeros(int n)
00392 {
00393 return ((sc_digit) 1 << n);
00394 }
00395
00396
00397
00398
00399
00400 inline
00401 int
00402 digit_ord(int i)
00403 {
00404 return (i / BITS_PER_DIGIT);
00405 }
00406
00407
00408 inline
00409 int
00410 bit_ord(int i)
00411 {
00412 return (i % BITS_PER_DIGIT);
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 inline
00428 int
00429 vec_cmp(int ulen, const sc_digit *u,
00430 int vlen, const sc_digit *v)
00431 {
00432
00433 #ifdef DEBUG_SYSTEMC
00434
00435
00436
00437
00438
00439 assert((ulen >= 0) && (u != NULL));
00440 assert((vlen >= 0) && (v != NULL));
00441
00442 assert((ulen <= 0) || (u[ulen - 1] != 0));
00443 assert((vlen <= 0) || (v[vlen - 1] != 0));
00444 #endif
00445
00446 if (ulen != vlen)
00447 return (ulen - vlen);
00448
00449
00450 while ((--ulen >= 0) && (u[ulen] == v[ulen]))
00451 ;
00452
00453 if (ulen < 0)
00454 return 0;
00455
00456 #ifdef DEBUG_SYSTEMC
00457
00458
00459 assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK));
00460 #endif
00461
00462 return (int) (u[ulen] - v[ulen]);
00463
00464 }
00465
00466
00467
00468
00469
00470 inline
00471 int
00472 vec_find_first_nonzero(int ulen, const sc_digit *u)
00473 {
00474
00475 #ifdef DEBUG_SYSTEMC
00476
00477 assert((ulen > 0) && (u != NULL));
00478 #endif
00479
00480 while ((--ulen >= 0) && (! u[ulen]))
00481 ;
00482
00483 return ulen;
00484
00485 }
00486
00487
00488
00489
00490
00491 inline
00492 int
00493 vec_skip_leading_zeros(int ulen, const sc_digit *u)
00494 {
00495
00496 #ifdef DEBUG_SYSTEMC
00497
00498 assert((ulen > 0) && (u != NULL));
00499 #endif
00500
00501 return (1 + vec_find_first_nonzero(ulen, u));
00502
00503 }
00504
00505
00506
00507
00508
00509 inline
00510 int
00511 vec_skip_and_cmp(int ulen, const sc_digit *u,
00512 int vlen, const sc_digit *v)
00513 {
00514
00515 #ifdef DEBUG_SYSTEMC
00516 assert((ulen > 0) && (u != NULL));
00517 assert((vlen > 0) && (v != NULL));
00518 #endif
00519
00520 ulen = vec_skip_leading_zeros(ulen, u);
00521 vlen = vec_skip_leading_zeros(vlen, v);
00522
00523 return vec_cmp(ulen, u, vlen, v);
00524
00525 }
00526
00527
00528 inline
00529 void
00530 vec_zero(int from, int ulen, sc_digit *u)
00531 {
00532
00533 #ifdef DEBUG_SYSTEMC
00534 assert((ulen > 0) && (u != NULL));
00535 #endif
00536
00537 for(int i = from; i < ulen; i++)
00538 u[i] = 0;
00539
00540 }
00541
00542
00543 inline
00544 void
00545 vec_zero(int ulen, sc_digit *u)
00546 {
00547 vec_zero(0, ulen, u);
00548 }
00549
00550
00551 inline
00552 void
00553 vec_copy(int n, sc_digit *u, const sc_digit *v)
00554 {
00555
00556 #ifdef DEBUG_SYSTEMC
00557 assert((n > 0) && (u != NULL) && (v != NULL));
00558 #endif
00559
00560 for (int i = 0; i < n; ++i)
00561 u[i] = v[i];
00562 }
00563
00564
00565 inline
00566 void
00567 vec_copy_and_zero(int ulen, sc_digit *u,
00568 int vlen, const sc_digit *v)
00569 {
00570
00571 #ifdef DEBUG_SYSTEMC
00572 assert((ulen > 0) && (u != NULL));
00573 assert((vlen > 0) && (v != NULL));
00574 assert(ulen >= vlen);
00575 #endif
00576
00577 vec_copy(vlen, u, v);
00578 vec_zero(vlen, ulen, u);
00579
00580 }
00581
00582
00583 inline
00584 void
00585 vec_complement(int ulen, sc_digit *u)
00586 {
00587
00588 #ifdef DEBUG_SYSTEMC
00589 assert((ulen > 0) && (u != NULL));
00590 #endif
00591
00592 sc_digit carry = 1;
00593
00594 for (int i = 0; i < ulen; ++i) {
00595 carry += (~u[i] & DIGIT_MASK);
00596 u[i] = carry & DIGIT_MASK;
00597 carry >>= BITS_PER_DIGIT;
00598 }
00599
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609 template< class Type >
00610 inline
00611 void
00612 from_uint(int ulen, sc_digit *u, Type v)
00613 {
00614
00615 #ifdef DEBUG_SYSTEMC
00616
00617 assert((ulen > 0) && (u != NULL));
00618 assert(v >= 0);
00619 #endif
00620
00621 int i = 0;
00622
00623 while (v && (i < ulen)) {
00624 #ifndef _WIN32
00625 u[i++] = static_cast<sc_digit>( v & DIGIT_MASK );
00626 #else
00627 u[i++] = ((sc_digit) v) & DIGIT_MASK;
00628 #endif
00629 v >>= BITS_PER_DIGIT;
00630 }
00631
00632 vec_zero(i, ulen, u);
00633
00634 }
00635
00636
00637
00638
00639 template< class Type >
00640 inline
00641 small_type
00642 get_sign(Type &u)
00643 {
00644 if (u > 0)
00645 return SC_POS;
00646
00647 if (u == 0)
00648 return SC_ZERO;
00649
00650
00651
00652 if( SC_LIKELY_( u > (std::numeric_limits<Type>::min)() ) )
00653 u = -u;
00654
00655 return SC_NEG;
00656 }
00657
00658
00659
00660
00661
00662
00663 inline
00664 small_type
00665 mul_signs(small_type us, small_type vs)
00666 {
00667 if ((us == SC_ZERO) || (vs == SC_ZERO))
00668 return SC_ZERO;
00669
00670 if (us == vs)
00671 return SC_POS;
00672
00673 return SC_NEG;
00674 }
00675
00676
00677
00678
00679
00680
00681 #ifdef SC_MAX_NBITS
00682
00683 inline
00684 void
00685 test_bound(int nb)
00686 {
00687 if (nb > SC_MAX_NBITS) {
00688 char msg[BUFSIZ];
00689 std::sprintf( msg, "test_bound( int nb ) : "
00690 "nb = %d > SC_MAX_NBITS = %d is not valid",
00691 nb, SC_MAX_NBITS );
00692 SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
00693 }
00694 }
00695
00696 #endif
00697
00698 template< class Type >
00699 inline
00700 void
00701 div_by_zero(Type s)
00702 {
00703 if (s == 0) {
00704 SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_,
00705 "div_by_zero<Type>( Type ) : division by zero" );
00706 }
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716 inline
00717 small_type
00718 check_for_zero(small_type s, int ulen, const sc_digit *u)
00719 {
00720
00721 #ifdef DEBUG_SYSTEMC
00722
00723 assert((ulen > 0) && (u != NULL));
00724 #endif
00725
00726 if (vec_find_first_nonzero(ulen, u) < 0)
00727 return SC_ZERO;
00728
00729 return s;
00730
00731 }
00732
00733
00734
00735 inline
00736 bool
00737 check_for_zero(int ulen, const sc_digit *u)
00738 {
00739
00740 #ifdef DEBUG_SYSTEMC
00741
00742 assert((ulen > 0) && (u != NULL));
00743 #endif
00744
00745 if (vec_find_first_nonzero(ulen, u) < 0)
00746 return true;
00747
00748 return false;
00749
00750 }
00751
00752 inline
00753 small_type
00754 make_zero(int nd, sc_digit *d)
00755 {
00756 vec_zero(nd, d);
00757 return SC_ZERO;
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 inline
00771 void
00772 trim(small_type added, int nb, int nd, sc_digit *d)
00773 {
00774 #ifdef DEBUG_SYSTEMC
00775 assert((nb > 0) && (nd > 0) && (d != NULL));
00776 #endif
00777
00778 d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added);
00779 }
00780
00781
00782
00783 inline
00784 void
00785 convert_SM_to_2C_trimmed(small_type added,
00786 small_type s, int nb, int nd, sc_digit *d)
00787 {
00788 if (s == SC_NEG) {
00789 vec_complement(nd, d);
00790 trim(added, nb, nd, d);
00791 }
00792 }
00793
00794
00795
00796 inline
00797 void
00798 convert_SM_to_2C(small_type s, int nd, sc_digit *d)
00799 {
00800 if (s == SC_NEG)
00801 vec_complement(nd, d);
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811 inline
00812 void
00813 trim_signed(int nb, int nd, sc_digit *d)
00814 {
00815 #ifdef DEBUG_SYSTEMC
00816 assert((nb > 0) && (nd > 0) && (d != NULL));
00817 #endif
00818
00819 d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1);
00820 }
00821
00822
00823
00824
00825 inline
00826 small_type
00827 convert_signed_2C_to_SM(int nb, int nd, sc_digit *d)
00828 {
00829
00830 #ifdef DEBUG_SYSTEMC
00831 assert((nb > 0) && (nd > 0) && (d != NULL));
00832 #endif
00833
00834 small_type s;
00835
00836 int xnb = bit_ord(nb - 1) + 1;
00837
00838
00839 if (d[nd - 1] & one_and_zeros(xnb - 1)) {
00840 s = SC_NEG;
00841 vec_complement(nd, d);
00842 }
00843 else
00844 s = SC_POS;
00845
00846
00847 d[nd - 1] &= one_and_ones(xnb);
00848
00849
00850 if (s == SC_POS)
00851 return check_for_zero(s, nd, d);
00852
00853 return s;
00854
00855 }
00856
00857
00858
00859
00860
00861 inline
00862 small_type
00863 convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
00864 {
00865 convert_SM_to_2C(s, nd, d);
00866 return convert_signed_2C_to_SM(nb, nd, d);
00867 }
00868
00869
00870
00871 inline
00872 void
00873 convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
00874 {
00875 convert_SM_to_2C_trimmed(1, s, nb, nd, d);
00876 }
00877
00878
00879
00880 inline
00881 void
00882 convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d)
00883 {
00884 convert_SM_to_2C(s, nd, d);
00885 }
00886
00887
00888
00889
00890
00891
00892
00893
00894 inline
00895 void
00896 trim_unsigned(int nb, int nd, sc_digit *d)
00897 {
00898 #ifdef DEBUG_SYSTEMC
00899 assert((nb > 0) && (nd > 0) && (d != NULL));
00900 #endif
00901
00902 d[nd - 1] &= one_and_ones(bit_ord(nb - 1));
00903 }
00904
00905
00906
00907
00908 inline
00909 small_type
00910 convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d)
00911 {
00912 trim_unsigned(nb, nd, d);
00913 return check_for_zero(SC_POS, nd, d);
00914 }
00915
00916
00917
00918
00919
00920 inline
00921 small_type
00922 convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
00923 {
00924 convert_SM_to_2C(s, nd, d);
00925 return convert_unsigned_2C_to_SM(nb, nd, d);
00926 }
00927
00928
00929
00930 inline
00931 void
00932 convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
00933 {
00934 convert_SM_to_2C_trimmed(0, s, nb, nd, d);
00935 }
00936
00937
00938
00939 inline
00940 void
00941 convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d)
00942 {
00943 convert_SM_to_2C(s, nd, d);
00944 }
00945
00946
00947
00948
00949
00950
00951
00952 inline
00953 void
00954 copy_digits_signed(small_type &us,
00955 int unb, int und, sc_digit *ud,
00956 int vnb, int vnd, const sc_digit *vd)
00957 {
00958
00959 if (und <= vnd) {
00960
00961 vec_copy(und, ud, vd);
00962
00963 if (unb <= vnb)
00964 us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud);
00965
00966 }
00967 else
00968 vec_copy_and_zero(und, ud, vnd, vd);
00969
00970 }
00971
00972
00973 inline
00974 void
00975 copy_digits_unsigned(small_type &us,
00976 int unb, int und, sc_digit *ud,
00977 int , int vnd, const sc_digit *vd)
00978 {
00979
00980 if (und <= vnd)
00981 vec_copy(und, ud, vd);
00982
00983 else
00984 vec_copy_and_zero(und, ud, vnd, vd);
00985
00986 us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud);
00987
00988 }
00989
00990
00991
00992
00993
00994
00995
00996 inline
00997 void
00998 safe_set(int i, bool v, sc_digit *d)
00999 {
01000
01001 #ifdef DEBUG_SYSTEMC
01002 assert((i >= 0) && (d != NULL));
01003 #endif
01004
01005 int bit_num = bit_ord(i);
01006 int digit_num = digit_ord(i);
01007
01008 if (v)
01009 d[digit_num] |= one_and_zeros(bit_num);
01010 else
01011 d[digit_num] &= ~(one_and_zeros(bit_num));
01012
01013 }
01014
01015
01016
01017
01018
01019
01020 inline
01021 bool
01022 is_nan( double v )
01023 {
01024 return std::numeric_limits<double>::has_quiet_NaN && (v != v);
01025 }
01026
01027 inline
01028 bool
01029 is_inf( double v )
01030 {
01031 return v == std::numeric_limits<double>::infinity()
01032 || v == -std::numeric_limits<double>::infinity();
01033 }
01034
01035 inline
01036 void
01037 is_bad_double(double v)
01038 {
01039
01040 if( is_nan(v) || is_inf(v) )
01041 SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_,
01042 "is_bad_double( double v ) : "
01043 "v is not finite - NaN or Inf" );
01044 }
01045
01046 }
01047
01048
01049 #endif