📄 sc_nbcommon.inc
字号:
longCLASS_TYPE::to_long() const{ TO_INTX(long, LONG);}intCLASS_TYPE::to_int() const{ TO_INTX(int, INT);}// Convert to unsigned int64, unsigned long or unsigned// int. to_uint64, to_ulong, and to_uint have the same body except for// the type of v defined inside.uint64CLASS_TYPE::to_uint64() const{ if (sgn == SC_ZERO) return 0; int vnd = sc_min((int)DIGITS_PER_INT64, ndigits); uint64 v = 0; if (sgn == SC_NEG) {#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[ndigits];#endif vec_copy(ndigits, d, digit); convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + d[vnd];#ifndef SC_MAX_NBITS delete [] d;#endif } else { while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + digit[vnd]; } return v;}unsigned longCLASS_TYPE::to_ulong() const{ if (sgn == SC_ZERO) return 0; int vnd = sc_min((int)DIGITS_PER_LONG, ndigits); unsigned long v = 0; if (sgn == SC_NEG) {#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[ndigits];#endif vec_copy(ndigits, d, digit); convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + d[vnd];#ifndef SC_MAX_NBITS delete [] d;#endif } else { while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + digit[vnd]; } return v;}unsigned intCLASS_TYPE::to_uint() const{ if (sgn == SC_ZERO) return 0; int vnd = sc_min((int)DIGITS_PER_INT, ndigits); unsigned int v = 0; if (sgn == SC_NEG) {#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[ndigits];#endif vec_copy(ndigits, d, digit); convert_SM_to_2C_trimmed(IF_SC_SIGNED, sgn, nbits, ndigits, d); while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + d[vnd];#ifndef SC_MAX_NBITS delete [] d;#endif } else { while (--vnd >= 0) v = (v << BITS_PER_DIGIT) + digit[vnd]; } return v;}// Convert to double.doubleCLASS_TYPE::to_double() const{ if (sgn == SC_ZERO) return (double) 0.0; int vnd = ndigits; double v = 0.0; while (--vnd >= 0) v = v * DIGIT_RADIX + digit[vnd]; if (sgn == SC_NEG) return -v; else return v;}// Return true if the bit i is 1, false otherwise. If i is outside the// bounds, return 1/0 according to the sign of the number by assuming// that the number has infinite length.boolCLASS_TYPE::test(int i) const{#ifdef SC_SIGNED if (check_if_outside(i)) { if (sgn == SC_NEG) return 1; else return 0; }#else if (check_if_outside(i)) return 0;#endif int bit_num = bit_ord(i); int digit_num = digit_ord(i); if (sgn == SC_NEG) {#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[ndigits];#endif vec_copy(ndigits, d, digit); vec_complement(ndigits, d); bool val = ((d[digit_num] & one_and_zeros(bit_num)) != 0);#ifndef SC_MAX_NBITS delete [] d;#endif return val; } else return ((digit[digit_num] & one_and_zeros(bit_num)) != 0);}// Set the ith bit with 1.void CLASS_TYPE::set(int i) { if (check_if_outside(i)) return; int bit_num = bit_ord(i); int digit_num = digit_ord(i); convert_SM_to_2C(); digit[digit_num] |= one_and_zeros(bit_num); digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. convert_2C_to_SM();}// Set the ith bit with 0, i.e., clear the ith bit.void CLASS_TYPE::clear(int i){ if (check_if_outside(i)) return; int bit_num = bit_ord(i); int digit_num = digit_ord(i); convert_SM_to_2C(); digit[digit_num] &= ~(one_and_zeros(bit_num)); digit[digit_num] &= DIGIT_MASK; // Needed to zero the overflow bits. convert_2C_to_SM();}// Create a mirror image of the number.voidCLASS_TYPE::reverse(){ convert_SM_to_2C(); vec_reverse(length(), ndigits, digit, length() - 1); convert_2C_to_SM();}// Get a packed bit representation of the number.void CLASS_TYPE::get_packed_rep(sc_digit *buf) const{ int buf_ndigits = (length() - 1) / BITS_PER_DIGIT_TYPE + 1; // Initialize buf to zero. vec_zero(buf_ndigits, buf); if (sgn == SC_ZERO) return; const sc_digit *digit_or_d;#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else sc_digit *d = new sc_digit[ndigits];#endif if (sgn == SC_POS) digit_or_d = digit; else { // If sgn is negative, we have to convert digit to its 2's // complement. Since this function is const, we can not do it on // digit. Since buf doesn't have overflow bits, we cannot also do // it on buf. Thus, we have to do the complementation on a copy of // digit, i.e., on d. vec_copy(ndigits, d, digit); vec_complement(ndigits, d); buf[buf_ndigits - 1] = ~((sc_digit) 0); digit_or_d = d; } // Copy the bits from digit to buf. The division and mod operations // below can be converted to addition/subtraction and comparison // operations at the expense of complicating the code. We can do it // if we see any performance problems. for (register int i = length() - 1; i >= 0; --i) { if ((digit_or_d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test. buf[i / BITS_PER_DIGIT_TYPE] |= one_and_zeros(i % BITS_PER_DIGIT_TYPE); // Set. else buf[i / BITS_PER_DIGIT_TYPE] &= ~(one_and_zeros(i % BITS_PER_DIGIT_TYPE)); // Clear. }#ifndef SC_MAX_NBITS delete[] d;#endif}// Set a packed bit representation of the number.void CLASS_TYPE::set_packed_rep(sc_digit *buf){ // Initialize digit to zero. vec_zero(ndigits, digit); // Copy the bits from buf to digit. for (register int i = length() - 1; i >= 0; --i) { if ((buf[i / BITS_PER_DIGIT_TYPE] & one_and_zeros(i % BITS_PER_DIGIT_TYPE)) != 0) // Test. digit[digit_ord(i)] |= one_and_zeros(bit_ord(i)); // Set. else digit[digit_ord(i)] &= ~(one_and_zeros(bit_ord(i))); // Clear } convert_2C_to_SM();}// ----------------------------------------------------------------------------// SECTION: Private members.// ----------------------------------------------------------------------------// Create a copy of v with sgn s.CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE& v, small_type s){ sgn = s; nbits = v.nbits; ndigits = v.ndigits;#ifndef SC_MAX_NBITS digit = new sc_digit[ndigits];#endif vec_copy(ndigits, digit, v.digit);}// Create a copy of v where v is of the different type.CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE& v, small_type s){ sgn = s; nbits = num_bits(v.nbits);#if (IF_SC_SIGNED == 1) ndigits = v.ndigits;#else ndigits = DIV_CEIL(nbits);#endif#ifndef SC_MAX_NBITS digit = new sc_digit[ndigits];#endif copy_digits(v.nbits, v.ndigits, v.digit);}// Create a signed number with (s, nb, nd, d) as its attributes (as// defined in class CLASS_TYPE). If alloc is set, delete d.CLASS_TYPE::CLASS_TYPE(small_type s, int nb, int nd, sc_digit *d, bool alloc){ sgn = s; nbits = nb; ndigits = DIV_CEIL(nbits);#ifndef SC_MAX_NBITS digit = new sc_digit[ndigits];#endif if (ndigits <= nd) vec_copy(ndigits, digit, d); else vec_copy_and_zero(ndigits, digit, nd, d);#ifndef SC_MAX_NBITS if (alloc) delete [] d;#endif}// This constructor is mainly used in finding a "range" of bits from a// number of type CLASS_TYPE. The function range(l, r) can have// arbitrary precedence between l and r. If l is smaller than r, then// the output is the reverse of range(r, l). CLASS_TYPE::CLASS_TYPE(const CLASS_TYPE* u, int l, int r){ bool reversed = false; if( l < r ) { reversed = true; int tmp = l; l = r; r = tmp; } // at this point, l >= r // make sure that l and r point to the bits of u r = sc_max( r, 0 ); l = sc_min( l, u->nbits - 1 ); nbits = num_bits( l - r + 1 ); // nbits can still be <= 0 because l and r have just been updated // with the bounds of u. // if u == 0 or the range is out of bounds, return 0 if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) { sgn = SC_ZERO; if( nbits <= num_bits( 0 ) ) { nbits = 1; } ndigits = DIV_CEIL( nbits );#ifndef SC_MAX_NBITS digit = new sc_digit[ndigits];#endif vec_zero( ndigits, digit ); return; } // The rest will be executed if u is not zero. ndigits = DIV_CEIL(nbits); // The number of bits up to and including l and r, respectively. int nl = l + 1; int nr = r + 1; // The indices of the digits that have lth and rth bits, respectively. int left_digit = DIV_CEIL(nl) - 1; int right_digit = DIV_CEIL(nr) - 1; int nd; // The range is performed on the 2's complement representation, so // first get the indices for that. if (u->sgn == SC_NEG) nd = left_digit + 1; else nd = left_digit - right_digit + 1; // Allocate memory for the range.#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else digit = new sc_digit[ndigits]; sc_digit *d = new sc_digit[nd];#endif // Getting the range on the 2's complement representation. if (u->sgn == SC_NEG) { vec_copy(nd, d, u->digit); vec_complement(nd, d); // d = -d; vec_shift_right(nd, d, r, DIGIT_MASK); } else { for (register int i = right_digit; i <= left_digit; ++i) d[i - right_digit] = u->digit[i]; vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); } vec_zero(ndigits, digit); if (! reversed) vec_copy(sc_min(nd, ndigits), digit, d); else { // If l < r, i.e., reversed is set, reverse the bits of digit. d // will be used as a temporary store. The following code tries to // minimize the use of bit_ord and digit_ord, which use mod and // div operators. Since these operators are function calls to // standard library routines, they are slow. The main idea in // reversing is "read bits out of d from left to right and push // them into digit using right shifting." // Take care of the last digit. int nd_less_1 = nd - 1; // Deletions will start from the left end and move one position // after each deletion. register sc_digit del_mask = one_and_zeros(bit_ord(l - r)); while (del_mask) { vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0)); del_mask >>= 1; } // Take care of the other digits if any. // Insertion to digit will always occur at the left end. sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); for (register int j = nd - 2; j >= 0; --j) { // j = nd - 2 // Deletions will start from the left end and move one position // after each deletion. del_mask = ins_mask; while (del_mask) { vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); del_mask >>= 1; } } if (u->sgn == SC_NEG) vec_shift_right(ndigits, digit, ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); else vec_shift_right(ndigits, digit, ndigits * BITS_PER_DIGIT - length(), 0); } // if reversed. convert_2C_to_SM(); #ifndef SC_MAX_NBITS delete [] d;#endif}// This constructor is mainly used in finding a "range" of bits from a// number of type OTHER_CLASS_TYPE. The function range(l, r) can have// arbitrary precedence between l and r. If l is smaller than r, then// the output is the reverse of range(r, l). CLASS_TYPE::CLASS_TYPE(const OTHER_CLASS_TYPE* u, int l, int r){ bool reversed = false; if( l < r ) { reversed = true; int tmp = l; l = r; r = tmp; } // at this point, l >= r // make sure that l and r point to the bits of u r = sc_max( r, 0 ); l = sc_min( l, u->nbits - 1 ); nbits = num_bits( l - r + 1 ); // nbits can still be <= 0 because l and r have just been updated // with the bounds of u. // if u == 0 or the range is out of bounds, return 0 if( u->sgn == SC_ZERO || nbits <= num_bits( 0 ) ) { sgn = SC_ZERO; if( nbits <= num_bits( 0 ) ) { nbits = 1; } ndigits = DIV_CEIL( nbits );#ifndef SC_MAX_NBITS digit = new sc_digit[ndigits];#endif vec_zero( ndigits, digit ); return; } // The rest will be executed if u is not zero. ndigits = DIV_CEIL(nbits); // The number of bits up to and including l and r, respectively. int nl = l + 1; int nr = r + 1; // The indices of the digits that have lth and rth bits, respectively. int left_digit = DIV_CEIL(nl) - 1; int right_digit = DIV_CEIL(nr) - 1; int nd; // The range is performed on the 2's complement representation, so // first get the indices for that. if (u->sgn == SC_NEG) nd = left_digit + 1; else nd = left_digit - right_digit + 1; // Allocate memory for the range.#ifdef SC_MAX_NBITS sc_digit d[MAX_NDIGITS];#else digit = new sc_digit[ndigits]; sc_digit *d = new sc_digit[nd];#endif // Getting the range on the 2's complement representation. if (u->sgn == SC_NEG) { vec_copy(nd, d, u->digit); vec_complement(nd, d); // d = -d; vec_shift_right(nd, d, r, DIGIT_MASK); } else { for (register int i = right_digit; i <= left_digit; ++i) d[i - right_digit] = u->digit[i]; vec_shift_right(nd, d, r - right_digit * BITS_PER_DIGIT, 0); } vec_zero(ndigits, digit); if (! reversed) vec_copy(sc_min(nd, ndigits), digit, d); else { // If l < r, i.e., reversed is set, reverse the bits of digit. d // will be used as a temporary store. The following code tries to // minimize the use of bit_ord and digit_ord, which use mod and // div operators. Since these operators are function calls to // standard library routines, they are slow. The main idea in // reversing is "read bits out of d from left to right and push // them into digit using right shifting." // Take care of the last digit. int nd_less_1 = nd - 1; // Deletions will start from the left end and move one position // after each deletion. register sc_digit del_mask = one_and_zeros(bit_ord(l - r)); while (del_mask) { vec_shift_right(ndigits, digit, 1, ((d[nd_less_1] & del_mask) != 0)); del_mask >>= 1; } // Take care of the other digits if any. // Insertion to digit will always occur at the left end. sc_digit ins_mask = one_and_zeros(BITS_PER_DIGIT - 1); for (register int j = nd - 2; j >= 0; --j) { // j = nd - 2 // Deletions will start from the left end and move one position // after each deletion. del_mask = ins_mask; while (del_mask) { vec_shift_right(ndigits, digit, 1, ((d[j] & del_mask) != 0)); del_mask >>= 1; } } if (u->sgn == SC_NEG) vec_shift_right(ndigits, digit, ndigits * BITS_PER_DIGIT - length(), DIGIT_MASK); else vec_shift_right(ndigits, digit, ndigits * BITS_PER_DIGIT - length(), 0); } // if reversed. convert_2C_to_SM(); #ifndef SC_MAX_NBITS delete [] d;#endif}// Print out all the physical attributes.voidCLASS_TYPE::dump(::std::ostream& os) const{ // Save the current setting, and set the base to decimal. fmtflags old_flags = os.setf(::std::ios::dec, ::std::ios::basefield); os << "width = " << length() << ::std::endl; os << "value = " << *this << ::std::endl; os << "bits = "; int len = length(); for (int i = len - 1; i >= 0; --i) { os << "01"[test(i)]; if (--len % 4 == 0) os << " "; } os << ::std::endl; // Restore old_flags. os.setf(old_flags, ::std::ios::basefield);}// Checks to see if bit_num is out of bounds.boolCLASS_TYPE::check_if_outside(int bit_num) const{ if ((bit_num < 0) || (num_bits(bit_num) >= nbits)) {#ifdef DEBUG_SYSTEMC if( bit_num < 0 || bit_num >= nbits ) { char msg[BUFSIZ]; std::sprintf( msg, "%s::check_if_outside( int bit_num ) : " "bit_num = %d is out of bounds", CLASS_TYPE_STR, bit_num ); SC_REPORT_WARNING( sc_core::SC_ID_OUT_OF_BOUNDS_, msg ); }#endif return true; } return false;}// End of file.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -