⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc_nbutils.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#ifdef SC_MAX_NBITS  uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];  uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];#else  uchar *x = new uchar[xlen];  uchar *y = new uchar[ylen];#endif  // r corresponds to w.  // Set (uchar) x = (sc_digit) u.  xlen = vec_to_char(ulen, u, xlen, x);  // Skip all the leading zeros in x.  while ((--xlen >= 0) && (! x[xlen]));  xlen++;  // Set (uchar) y = (sc_digit) v.  ylen = vec_to_char(vlen, v, ylen, y);  // Skip all the leading zeros in y.  while ((--ylen >= 0) && (! y[ylen]));  ylen++;#ifdef DEBUG_SYSTEMC  assert(xlen > 1);  assert(ylen > 1);#endif  // At this point, all the leading zeros are eliminated from x and y.  // Zero the last digit of x.  x[xlen] = 0;  // The first two digits of y.  register sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];  const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;  // Find each q[k].  for (register int k = xlen - ylen; k >= 0; --k) {    // qk is a guess for q[k] such that q[k] = qk or qk - 1.    register sc_digit qk;    // Find qk by just using 2 digits of y and 3 digits of x. The    // following code assumes that sizeof(sc_digit) >= 3 BYTEs.    int k2 = k + ylen;    qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +      (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;    if (qk >= BYTE_RADIX)     // qk cannot be larger than the largest      qk = BYTE_RADIX - 1;    // digit in BYTE_RADIX.    // q[k] = qk or qk - 1. The following if-statement determines which.    if (qk) {      register uchar *xk = (x + k);  // A shortcut for x[k].      // x = x - y * qk;      register sc_digit carry = 0;      for (register int i = 0; i < ylen; ++i) {        carry += y[i] * qk;        sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);        xk[i] = (uchar)(diff & BYTE_MASK);        carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));      }      if (carry) {        // 2's complement the last digit.        carry = (xk[ylen] + BYTE_RADIX) - carry;        xk[ylen] = (uchar)(carry & BYTE_MASK);        carry = 1 - (carry >> BITS_PER_BYTE);                if (carry) {          // qk was one too large, so decrement it.          // --qk;                  // x = x - y * (qk - 1) = x - y * qk + y = x_above + y.          carry = 0;          for (register int i = 0; i < ylen; ++i) {            carry += xk[i] + y[i];            xk[i] = (uchar)(carry & BYTE_MASK);            carry >>= BITS_PER_BYTE;          }          if (carry)            xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);        }  // second if carry      } // first if carry    }  // if qk  }  // for k  // Set (sc_digit) w = (uchar) x for the remainder.  vec_from_char(ylen, x, ulen, w);#ifndef SC_MAX_NBITS  delete [] x;  delete [] y;#endif}// Compute r = u % v, where u is a vector, and r and v are scalars.// - 0 < v < HALF_DIGIT_RADIX. // - The remainder r is returned.sc_digitvec_rem_small(int ulen, const sc_digit *u, sc_digit v){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));  assert((0 < v) && (v < HALF_DIGIT_RADIX));#endif  // This function is adapted from vec_div_small().  register sc_digit r = 0;  const sc_digit *ubegin = u;  u += ulen;  while (ubegin < u) {    register sc_digit u_AB = (*--u);  // A|B#ifdef DEBUG_SYSTEMC    // The overflow bits must be zero.    assert(high_half(u_AB) == high_half_masked(u_AB));#endif    // r = (((r|A) % v)|B) % v    r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;  }  return r;}// u = u / v, r = u % v.sc_digitvec_rem_on_small(int ulen, sc_digit *u, sc_digit v){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));  assert(v > 0);#endif#define q_h r  register sc_digit r = 0;  const sc_digit *ubegin = u;  u += ulen;  while (ubegin < u) {    sc_digit u_AB = (*--u);       // A|B#ifdef DEBUG_SYSTEMC    // The overflow bits must be zero.    assert(high_half(u_AB) == high_half_masked(u_AB));#endif    register sc_digit num = concat(r, high_half(u_AB));  // num = r|A    q_h = num / v;                           // C    num = concat((num % v), low_half(u_AB)); // num = (((r|A) % v)|B)     (*u) = concat(q_h, num / v);             // q = C|D    r = num % v;  }#undef q_h  return r;}// Set (uchar) v = (sc_digit) u. Return the new vlen.intvec_to_char(int ulen, const sc_digit *u,            int vlen, uchar *v){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));  assert((vlen > 0) && (v != NULL));#endif  register int nbits = ulen * BITS_PER_DIGIT;  register int right = 0;  register int left = right + BITS_PER_BYTE - 1;  vlen = 0;  while (nbits > 0) {    int left_digit = left / BITS_PER_DIGIT;    int right_digit = right / BITS_PER_DIGIT;    register int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);    int d = u[right_digit] >> nsr;    if (left_digit != right_digit) {      if (left_digit < ulen)        d |= u[left_digit] << (BITS_PER_DIGIT - nsr);    }    v[vlen++] = (uchar)(d & BYTE_MASK);    left += BITS_PER_BYTE;    right += BITS_PER_BYTE;    nbits -= BITS_PER_BYTE;  }  return vlen;}// Set (sc_digit) v = (uchar) u. // - sizeof(uchar) <= sizeof(sc_digit), void vec_from_char(int ulen, const uchar *u,               int vlen, sc_digit *v){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));  assert((vlen > 0) && (v != NULL));  assert(sizeof(uchar) <= sizeof(sc_digit));#endif  sc_digit *vend = (v + vlen);  const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;  const sc_digit mask = one_and_ones(nsr);  (*v) = (sc_digit) u[ulen - 1];  for (register int i = ulen - 2; i >= 0; --i) {    // Manual inlining of vec_shift_left().    register sc_digit *viter = v;    register sc_digit carry = 0;    while (viter < vend) {      register sc_digit vval = (*viter);      (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);      carry = vval >> nsr;    }    if (viter < vend)      (*viter) = carry;    (*v) |= (sc_digit) u[i];  }}// Set u <<= nsl.// If nsl is negative, it is ignored.void vec_shift_left(int ulen, sc_digit *u, int nsl){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));#endif  if (nsl <= 0)    return;  // Shift left whole digits if nsl is large enough.  if (nsl >= (int) BITS_PER_DIGIT) {    int nd;    if (nsl % BITS_PER_DIGIT == 0) {      nd = nsl / BITS_PER_DIGIT;  // No need to use DIV_CEIL(nsl).      nsl = 0;    }    else {      nd = DIV_CEIL(nsl) - 1;      nsl -= nd * BITS_PER_DIGIT;    }    if (nd) {      // Shift left for nd digits.      for (register int j = ulen - 1; j >= nd; --j)        u[j] = u[j - nd];            vec_zero( sc_min( nd, ulen ), u );          }    if (nsl == 0)      return;  }  // Shift left if nsl < BITS_PER_DIGIT.  register sc_digit *uiter = u;  sc_digit *uend = uiter + ulen;  int nsr = BITS_PER_DIGIT - nsl;  sc_digit mask = one_and_ones(nsr);  register sc_digit carry = 0;  while (uiter < uend) {    register sc_digit uval = (*uiter);    (*uiter++) = (((uval & mask) << nsl) | carry);    carry = uval >> nsr;  }  if (uiter < uend)    (*uiter) = carry;}// Set u >>= nsr.// If nsr is negative, it is ignored.void vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill){#ifdef DEBUG_SYSTEMC  assert((ulen > 0) && (u != NULL));#endif  // fill is usually either 0 or DIGIT_MASK; it can be any value.  if (nsr <= 0)    return;  // Shift right whole digits if nsr is large enough.  if (nsr >= (int) BITS_PER_DIGIT) {    int nd;    if (nsr % BITS_PER_DIGIT == 0) {      nd = nsr / BITS_PER_DIGIT;      nsr = 0;    }    else {      nd = DIV_CEIL(nsr) - 1;      nsr -= nd * BITS_PER_DIGIT;    }        if (nd) {      // Shift right for nd digits.      for (register int j = 0; j < (ulen - nd); ++j)        u[j] = u[j + nd];      if (fill) {        for (register int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)          u[j] = fill;      }      else        vec_zero(ulen - sc_min( nd, ulen ), ulen, u);         }    if (nsr == 0)      return;  }  // Shift right if nsr < BITS_PER_DIGIT.  sc_digit *ubegin = u;  register sc_digit *uiter = (ubegin + ulen);  int nsl = BITS_PER_DIGIT - nsr;  sc_digit mask = one_and_ones(nsr);  register sc_digit carry = (fill & mask) << nsl;  while (ubegin < uiter) {    register sc_digit uval = (*--uiter);    (*uiter) = (uval >> nsr) | carry;    carry = (uval & mask) << nsl;  }}// Let u[l..r], where l and r are left and right bit positions// respectively, be equal to its mirror image.voidvec_reverse(int unb, int und, sc_digit *ud,             int l, int r){#ifdef DEBUG_SYSTEMC  assert((unb > 0) && (und > 0) && (ud != NULL));  assert((0 <= r) && (r <= l) && (l < unb));#endif  if (l < r) {      char msg[BUFSIZ];      std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : "	       "l = %d < r = %d is not valid",	       l, r );      SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );  }  // Make sure that l and r are within bounds.  r = sc_max(r, 0);  l = sc_min(l, unb - 1);  // Allocate memory for processing.#ifdef SC_MAX_NBITS  sc_digit d[MAX_NDIGITS];#else  sc_digit *d = new sc_digit[und];#endif  // d is a copy of ud.  vec_copy(und, d, ud);  // Based on the value of the ith in d, find the value of the jth bit  // in ud.  for (register int i = l, j = r; i >= r; --i, ++j) {    if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0) // Test.      ud[digit_ord(j)] |= one_and_zeros(bit_ord(j));     // Set.    else        ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j)));  // Clear.  }#ifndef SC_MAX_NBITS  delete [] d;#endif    }} // namespace sc_dt// End of file.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -