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