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