📄 sc_nbutils.cpp
字号:
case '7': data = data | 7; break; case '6': data = data | 6; break; case '5': data = data | 5; break; case '4': data = data | 4; break; case '3': data = data | 3; break; case '2': data = data | 2; break; case '1': data = data | 1; break; case '0': break; case 'Z': case 'z': ctrl = ctrl | 15; break; default: { char msg[BUFSIZ]; std::sprintf( msg, "character string '%s' is not valid", src_p ); SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); } break; } } if ( ctrl_p ) ctrl_p[word_i] = ctrl; data_p[word_i] = data; src_n = src_n - BITS_PER_DIGIT; }} // ----------------------------------------------------------------------------// SECTION: Utility functions involving unsigned vectors.// ----------------------------------------------------------------------------// Read u from a null terminated char string v. Note that operator>>// in sc_nbcommon.cpp is similar to this function.small_typevec_from_str(int unb, int und, sc_digit *u, const char *v, sc_numrep base) {#ifdef DEBUG_SYSTEMC assert((unb > 0) && (und > 0) && (u != NULL)); assert(v != NULL);#endif is_valid_base(base); small_type b, s; // base and sign. v = get_base_and_sign(v, b, s); if (base != SC_NOBASE) { if (b == NB_DEFAULT_BASE) b = base; else { char msg[BUFSIZ]; std::sprintf( msg, "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " "base = %s does not match the default base", to_string( base ).c_str() ); SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); } } vec_zero(und, u); char c; for ( ; (c = *v); ++v) { if (isalnum(c)) { small_type val; // Numeric value of a char. if (isalpha(c)) // Hex digit. val = toupper(c) - 'A' + 10; else val = c - '0'; if (val >= b) { char msg[BUFSIZ]; std::sprintf( msg, "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " "'%c' is not a valid digit in base %d", *v, b ); SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); } // digit = digit * b + val; vec_mul_small_on(und, u, b); if (val) vec_add_small_on(und, u, val); } else { char msg[BUFSIZ]; std::sprintf( msg, "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : " "'%c' is not a valid digit in base %d", *v, b ); SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg ); } } return convert_signed_SM_to_2C_to_SM(s, unb, und, u);}// All vec_ functions assume that the vector to hold the result,// called w, has sufficient length to hold the result. For efficiency// reasons, we do not test whether or not we are out of bounds.// Compute w = u + v, where w, u, and v are vectors. // - ulen >= vlen// - wlen >= sc_max(ulen, vlen) + 1voidvec_add(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL)); assert((vlen > 0) && (v != NULL)); assert(w != NULL); assert(ulen >= vlen);#endif const sc_digit *uend = (u + ulen); const sc_digit *vend = (v + vlen); register sc_digit carry = 0; // Also used as sum to save space. // Add along the shorter v. while (v < vend) { carry += (*u++) + (*v++); (*w++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; } // Propagate the carry. while (carry && (u < uend)) { carry = (*u++) + 1; (*w++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; } // Copy the rest of u to the result. while (u < uend) (*w++) = (*u++); // Propagate the carry if it is still 1. if (carry) (*w) = 1;}// Compute u += v, where u and v are vectors.// - ulen >= vlenvoidvec_add_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (ubegin != NULL)); assert((vlen > 0) && (v != NULL)); assert(ulen >= vlen);#endif register sc_digit *u = ubegin; const sc_digit *uend = (u + ulen); const sc_digit *vend = (v + vlen); register sc_digit carry = 0; // Also used as sum to save space. // Add along the shorter v. while (v < vend) { carry += (*u) + (*v++); (*u++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; } // Propagate the carry. while (carry && (u < uend)) { carry = (*u) + 1; (*u++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; }#ifdef DEBUG_SYSTEMC if( carry != 0 ) { SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, "vec_add_on( int, sc_digit*, int, const " "sc_digit* ) : " "result of addition is wrapped around" ); }#endif}// Compute u += v, where u and v are vectors.// - ulen < vlenvoidvec_add_on2(int ulen, sc_digit *ubegin, int#ifdef DEBUG_SYSTEMC vlen#endif , const sc_digit *v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (ubegin != NULL)); assert((vlen > 0) && (v != NULL)); assert(ulen < vlen);#endif register sc_digit *u = ubegin; const sc_digit *uend = (u + ulen); register sc_digit carry = 0; // Also used as sum to save space. // Add along the shorter u. while (u < uend) { carry += (*u) + (*v++); (*u++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; }#ifdef DEBUG_SYSTEMC if( carry != 0 ) { SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, "vec_add_on2( int, sc_digit*, int, const " "sc_digit* ) : " "result of addition is wrapped around" ); }#endif}// Compute w = u + v, where w and u are vectors, and v is a scalar.voidvec_add_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL)); assert(w != NULL);#endif const sc_digit *uend = (u + ulen); // Add along the shorter v. register sc_digit carry = (*u++) + v; (*w++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; // Propagate the carry. while (carry && (u < uend)) { carry = (*u++) + 1; (*w++) = carry & DIGIT_MASK; carry >>= BITS_PER_DIGIT; } // Copy the rest of u to the result. while (u < uend) (*w++) = (*u++); // Propagate the carry if it is still 1. if (carry) (*w) = 1;}// Compute u += v, where u is vectors, and v is a scalar.void vec_add_small_on(int ulen, sc_digit *u, sc_digit v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL));#endif register int i = 0; while (v && (i < ulen)) { v += u[i]; u[i++] = v & DIGIT_MASK; v >>= BITS_PER_DIGIT; }#ifdef DEBUG_SYSTEMC if( v != 0 ) { SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, "vec_add_small_on( int, sc_digit*, unsigned " "long ) : " "result of addition is wrapped around" ); }#endif}// Compute w = u - v, where w, u, and v are vectors.// - ulen >= vlen// - wlen >= sc_max(ulen, vlen)voidvec_sub(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL)); assert((vlen > 0) && (v != NULL)); assert(w != NULL); assert(ulen >= vlen);#endif const sc_digit *uend = (u + ulen); const sc_digit *vend = (v + vlen); register sc_digit borrow = 0; // Also used as diff to save space. // Subtract along the shorter v. while (v < vend) { borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow; (*w++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); } // Propagate the borrow. while (borrow && (u < uend)) { borrow = ((*u++) + DIGIT_RADIX) - 1; (*w++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); }#ifdef DEBUG_SYSTEMC assert(borrow == 0);#endif // Copy the rest of u to the result. while (u < uend) (*w++) = (*u++);}// Compute u = u - v, where u and v are vectors.// - u > v// - ulen >= vlenvoidvec_sub_on(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (ubegin != NULL)); assert((vlen > 0) && (v != NULL)); assert(ulen >= vlen);#endif register sc_digit *u = ubegin; const sc_digit *uend = (u + ulen); const sc_digit *vend = (v + vlen); register sc_digit borrow = 0; // Also used as diff to save space. // Subtract along the shorter v. while (v < vend) { borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow; (*u++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); } // Propagate the borrow. while (borrow && (u < uend)) { borrow = ((*u) + DIGIT_RADIX) - 1; (*u++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); }#ifdef DEBUG_SYSTEMC assert(borrow == 0);#endif}// Compute u = v - u, where u and v are vectors.// - v > u// - ulen <= vlen or ulen > ulenvoidvec_sub_on2(int ulen, sc_digit *ubegin, int vlen, const sc_digit *v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (ubegin != NULL)); assert((vlen > 0) && (v != NULL));#endif register sc_digit *u = ubegin; const sc_digit *uend = (u + sc_min(ulen, vlen)); register sc_digit borrow = 0; // Also used as diff to save space. // Subtract along the shorter u. while (u < uend) { borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow; (*u++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); }#ifdef DEBUG_SYSTEMC if( borrow != 0 ) { SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_, "vec_sub_on2( int, sc_digit*, int, const " "sc_digit* ) : " "result of subtraction is wrapped around" ); }#endif}// Compute w = u - v, where w and u are vectors, and v is a scalar.voidvec_sub_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w){#ifdef DEBUG_SYSTEMC assert(ulen > 0); assert(u != NULL);#endif const sc_digit *uend = (u + ulen); // Add along the shorter v. register sc_digit borrow = ((*u++) + DIGIT_RADIX) - v; (*w++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); // Propagate the borrow. while (borrow && (u < uend)) { borrow = ((*u++) + DIGIT_RADIX) - 1; (*w++) = borrow & DIGIT_MASK; borrow = 1 - (borrow >> BITS_PER_DIGIT); }#ifdef DEBUG_SYSTEMC assert(borrow == 0);#endif // Copy the rest of u to the result. while (u < uend) (*w++) = (*u++);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -