📄 sc_nbutils.h
字号:
/***************************************************************************** The following code is derived, directly or indirectly, from the SystemC source code Copyright (c) 1996-2006 by all Contributors. All Rights reserved. The contents of this file are subject to the restrictions and limitations set forth in the SystemC Open Source License Version 2.4 (the "License"); You may not use this file except in compliance with such restrictions and limitations. You may obtain instructions on how to receive a copy of the License at http://www.systemc.org/. Software distributed by Contributors under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. *****************************************************************************//***************************************************************************** sc_nbutils.h -- External and friend functions for both sc_signed and sc_unsigned classes. Original Author: Ali Dasdan, Synopsys, Inc. *****************************************************************************//***************************************************************************** MODIFICATION LOG - modifiers, enter your name, affiliation, date and changes you are making here. Name, Affiliation, Date: Description of Modification: *****************************************************************************/// $Log: sc_nbutils.h,v $// Revision 1.1.1.1 2006/12/15 20:31:36 acg// SystemC 2.2//// Revision 1.3 2006/01/13 18:49:32 acg// Added $Log command so that CVS check in comments are reproduced in the// source.//#ifndef SC_NBUTILS_H#define SC_NBUTILS_H#if !defined(__ppc__) && !defined(_MSC_VER) && !defined(__x86_64__) && !defined(i386) && !defined(__hpux) && !defined( __BORLANDC__ )#include <ieeefp.h>#else#include <cmath>#endif#include "sysc/datatypes/bit/sc_bit_ids.h"#include "sysc/datatypes/int/sc_int_ids.h"#include "sysc/datatypes/int/sc_nbdefs.h"#include "sysc/utils/sc_string.h"#include "sysc/utils/sc_report.h"namespace sc_dt{inlinevoidis_valid_base(sc_numrep base){ switch (base) { case SC_NOBASE: case SC_BIN: case SC_OCT: case SC_DEC: case SC_HEX: break; case SC_BIN_US: case SC_BIN_SM: case SC_OCT_US: case SC_OCT_SM: case SC_HEX_US: case SC_HEX_SM: SC_REPORT_ERROR( sc_core::SC_ID_NOT_IMPLEMENTED_, "is_valid_base( sc_numrep base ) : " "base ending in _US and _SM is not supported yet" ); default: char msg[BUFSIZ]; std::sprintf( msg, "is_valid_base( sc_numrep base ) : " "base = %s is not valid", to_string( base ).c_str() ); SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg ); }}// One transition of the FSM to find base and sign of a number.externsmall_type fsm_move(char c, small_type &b, small_type &s, small_type &state);// Parse a character string into its equivalent binary bits.externvoid parse_binary_bits( const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0);// Parse a character string into its equivalent hexadecimal bits.externvoid parse_hex_bits( const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0);// Find the base and sign of a number in v.extern const char *get_base_and_sign(const char *v, small_type &base, small_type &sign);// Create a number out of v in base.extern small_type vec_from_str(int unb, int und, sc_digit *u, const char *v, sc_numrep base = SC_NOBASE) ;// ----------------------------------------------------------------------------// Naming convention for the vec_ functions below:// vec_OP(u, v, w) : computes w = u OP v.// vec_OP_on(u, v) : computes u = u OP v if u has more digits than v.// vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v.// _large : parameters are vectors.// _small : one of the parameters is a single digit.// Xlen : the number of digits in X.// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------// Functions for vector addition: w = u + v or u += v.// ----------------------------------------------------------------------------extern void vec_add(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w);extern void vec_add_on(int ulen, sc_digit *u, int vlen, const sc_digit *v);extern void vec_add_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v);extern void vec_add_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w);extern void vec_add_small_on(int ulen, sc_digit *u, sc_digit v);// ----------------------------------------------------------------------------// Functions for vector subtraction: w = u - v, u -= v, or u = v - u.// ----------------------------------------------------------------------------extern void vec_sub(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w);extern void vec_sub_on(int ulen, sc_digit *u, int vlen, const sc_digit *v);extern void vec_sub_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v);extern void vec_sub_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w);extern void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v);// ----------------------------------------------------------------------------// Functions for vector multiplication: w = u * v or u *= v.// ----------------------------------------------------------------------------extern void vec_mul(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w);extern void vec_mul_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w);extern void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v);// ----------------------------------------------------------------------------// Functions for vector division: w = u / v.// ----------------------------------------------------------------------------extern void vec_div_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w);extern void vec_div_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w);// ----------------------------------------------------------------------------// Functions for vector remainder: w = u % v or u %= v.// ----------------------------------------------------------------------------extern void vec_rem_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w);extern sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v);extern sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v);// ----------------------------------------------------------------------------// Functions to convert between vectors of char and sc_digit.// ----------------------------------------------------------------------------extern int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v);extern void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v);// ----------------------------------------------------------------------------// Functions to shift left or right, or to create a mirror image of vectors.// ----------------------------------------------------------------------------extern void vec_shift_left(int ulen, sc_digit *u, int nsl);extern void vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill = 0);externvoid vec_reverse(int unb, int und, sc_digit *ud, int l, int r = 0);// ----------------------------------------------------------------------------// Various utility functions. // ----------------------------------------------------------------------------// Return the low half part of d.inline sc_digit low_half(sc_digit d) { return (d & HALF_DIGIT_MASK);}// Return the high half part of d. The high part of the digit may have// more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the// multiplication. Hence, in other functions that use high_half(),// make sure that the result contains BITS_PER_HALF_DIGIT if// necessary. This is done by high_half_masked().inline sc_digit high_half(sc_digit d) { return (d >> BITS_PER_HALF_DIGIT);}inlinesc_digithigh_half_masked(sc_digit d){ return (high_half(d) & HALF_DIGIT_MASK);}// Concatenate the high part h and low part l. Assumes that h and l// are less than or equal to HALF_DIGIT_MASK;inline sc_digit concat(sc_digit h, sc_digit l) { return ((h << BITS_PER_HALF_DIGIT) | l);}// Create a number with n 1's.inlinesc_digitone_and_ones(int n){ return (((sc_digit) 1 << n) - 1);}// Create a number with one 1 and n 0's.inlinesc_digitone_and_zeros(int n){ return ((sc_digit) 1 << n);}// ----------------------------------------------------------------------------// Find the digit that bit i is in.inlineint digit_ord(int i){ return (i / BITS_PER_DIGIT);}// Find the bit in digit_ord(i) that bit i corressponds to.inlineint bit_ord(int i){ return (i % BITS_PER_DIGIT);}// ----------------------------------------------------------------------------// Functions to compare, zero, complement vector(s).// ----------------------------------------------------------------------------// Compare u and v and return r// r = 0 if u == v// r < 0 if u < v// r > 0 if u > v// - Assume that all the leading zero digits are already skipped.// - ulen and/or vlen can be zero.// - Every digit is less than or equal to DIGIT_MASK;inline intvec_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v){#ifdef DEBUG_SYSTEMC // assert((ulen <= 0) || (u != NULL)); // assert((vlen <= 0) || (v != NULL)); // ulen and vlen can be equal to 0 because vec_cmp can be called // after vec_skip_leading_zeros. assert((ulen >= 0) && (u != NULL)); assert((vlen >= 0) && (v != NULL)); // If ulen > 0, then the leading digit of u must be non-zero. assert((ulen <= 0) || (u[ulen - 1] != 0)); assert((vlen <= 0) || (v[vlen - 1] != 0));#endif if (ulen != vlen) return (ulen - vlen); // ulen == vlen >= 1 while ((--ulen >= 0) && (u[ulen] == v[ulen])) ; if (ulen < 0) return 0;#ifdef DEBUG_SYSTEMC // Test to see if the result is wrong due to the presence of // overflow bits. assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK));#endif return (int) (u[ulen] - v[ulen]);}// Find the index of the first non-zero digit.// - ulen (before) = the number of digits in u.// - the returned value = the index of the first non-zero digit. // A negative value of -1 indicates that every digit in u is zero.inlineintvec_find_first_nonzero(int ulen, const sc_digit *u){#ifdef DEBUG_SYSTEMC // assert((ulen <= 0) || (u != NULL)); assert((ulen > 0) && (u != NULL));#endif while ((--ulen >= 0) && (! u[ulen])) ; return ulen; }// Skip all the leading zero digits. // - ulen (before) = the number of digits in u.// - the returned value = the number of non-zero digits in u.// - the returned value is non-negative.inline intvec_skip_leading_zeros(int ulen, const sc_digit *u){#ifdef DEBUG_SYSTEMC // assert((ulen <= 0) || (u != NULL)); assert((ulen > 0) && (u != NULL));#endif return (1 + vec_find_first_nonzero(ulen, u));}// Compare u and v and return r// r = 0 if u == v// r < 0 if u < v// r > 0 if u > vinline int vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL)); assert((vlen > 0) && (v != NULL));#endif ulen = vec_skip_leading_zeros(ulen, u); vlen = vec_skip_leading_zeros(vlen, v); // ulen and/or vlen can be equal to zero here. return vec_cmp(ulen, u, vlen, v);}// Set u[i] = 0 where i = from ... (ulen - 1).inlinevoidvec_zero(int from, int ulen, sc_digit *u){#ifdef DEBUG_SYSTEMC assert((ulen > 0) && (u != NULL));#endif for(int i = from; i < ulen; i++) u[i] = 0;}// Set u[i] = 0 where i = 0 .. (ulen - 1).inlinevoidvec_zero(int ulen, sc_digit *u){ vec_zero(0, ulen, u);}// Copy n digits from v to u.inlinevoidvec_copy(int n, sc_digit *u, const sc_digit *v){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -