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

📄 scfx_rep.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		    if( under )			o_set_low( x, SC_TC_ );		    else			o_set_high( x, x2, SC_TC_ );		}		break;	    }            default:	        ;	}	find_sw();    }}// ----------------------------------------------------------------------------//  PUBLIC METHOD : cast////  Performs a destructive cast operation on a scfx_rep.// ----------------------------------------------------------------------------voidscfx_rep::cast( const scfx_params& params, bool& q_flag, bool& o_flag ){    q_flag = false;    o_flag = false;    // check for special cases        if( is_zero() )    {	if( is_neg() )	    m_sign = 1;	return;    }    // perform casting    quantization( params, q_flag );    overflow( params, o_flag );    // check for special case: -0    if( is_zero() && is_neg() )	m_sign = 1;}// ----------------------------------------------------------------------------//  make sure, the two mantissas are aligned// ----------------------------------------------------------------------------voidalign( const scfx_rep& lhs, const scfx_rep& rhs, int& new_wp,       int& len_mant, scfx_mant_ref& lhs_mant, scfx_mant_ref& rhs_mant ){    bool need_lhs = true;    bool need_rhs = true;    if( lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size() )    {	int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;	int upper_bound_lhs = lhs.m_msw - lhs.m_wp;	int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;	int upper_bound_rhs = rhs.m_msw - rhs.m_wp;	int lower_bound = sc_min( lower_bound_lhs, lower_bound_rhs );	int upper_bound = sc_max( upper_bound_lhs, upper_bound_rhs );	new_wp   = -lower_bound;	len_mant = sc_max( min_mant, upper_bound - lower_bound + 1 );	if( new_wp != lhs.m_wp || len_mant != lhs.size() )	{	    lhs_mant = lhs.resize( len_mant, new_wp );	    need_lhs = false;	}	if( new_wp != rhs.m_wp || len_mant != rhs.size() )        {	    rhs_mant = rhs.resize( len_mant, new_wp );	    need_rhs = false;	}    }    if( need_lhs )    {	lhs_mant = lhs.m_mant;    }    if( need_rhs )    {	rhs_mant = rhs.m_mant;    }}// ----------------------------------------------------------------------------//  compare two mantissas// ----------------------------------------------------------------------------intcompare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs ){    // special case: rhs.m_mant[rhs.m_msw + 1] == 1    if( rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0 )    {	return -1;    }    int lhs_size = lhs.m_msw - lhs.m_lsw + 1;    int rhs_size = rhs.m_msw - rhs.m_lsw + 1;    int size = sc_min( lhs_size, rhs_size );    int lhs_index = lhs.m_msw;    int rhs_index = rhs.m_msw;    int i;    for( i = 0;	 i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];	 i ++ )    {	lhs_index --;	rhs_index --;    }    if( i == size )    {	if( lhs_size == rhs_size )	{	    return 0;	}	if( lhs_size < rhs_size )	{	    return -1;	}	else	{	    return 1;	}  }  if( lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index] )  {      return -1;  } else {      return 1;  }}// ----------------------------------------------------------------------------//  divide the mantissa by ten// ----------------------------------------------------------------------------unsigned intscfx_rep::divide_by_ten(){#if defined( SC_BIG_ENDIAN )    half_word* hw = (half_word*) &m_mant[m_msw];#elif defined( SC_LITTLE_ENDIAN )    half_word* hw = ( (half_word*) &m_mant[m_msw] ) + 1;#endif    unsigned int remainder = 0;    word_short ls;    ls.l = 0;#if defined( SC_BIG_ENDIAN )    for( int i = 0, end = ( m_msw - m_wp + 1 ) * 2; i < end; i ++ )#elif defined( SC_LITTLE_ENDIAN )    for( int i = 0, end = -( m_msw - m_wp + 1 ) * 2; i > end; i -- )#endif    {	ls.s.u = static_cast<half_word>( remainder );	ls.s.l = hw[i];	remainder = ls.l % 10;	ls.l /= 10;	hw[i] = ls.s.l;    }    return remainder;}// ----------------------------------------------------------------------------//  multiply the mantissa by ten// ----------------------------------------------------------------------------voidscfx_rep::multiply_by_ten(){    int size = m_mant.size() + 1;    scfx_mant mant8( size );    scfx_mant mant2( size );    size --;    mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));    mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));    while( -- size )    {	mant8[size] = ( m_mant[size] << 3 ) |	              ( m_mant[size - 1] >> ( bits_in_word - 3 ) );	mant2[size] = ( m_mant[size] << 1 ) |	              ( m_mant[size - 1] >> ( bits_in_word - 1 ) );    }    mant8[0] = ( m_mant[0] << 3 );    mant2[0] = ( m_mant[0] << 1 );    add_mants( m_mant.size(), m_mant, mant8, mant2 );#if 0    for( int i = size() - 1; i > 0; i -- )    {	m_mant[i] = ( m_mant[i] << 3 ) |                    ( m_mant[i-1] >> ( bits_in_word - 3 ) )	          + ( m_mant[i] << 1 ) |                    ( m_mant[i-1] >> ( bits_in_word - 1 ) );    }    m_mant[0] = ( m_mant[0] << 3 ) + ( m_mant[0] << 1 );#endif}// ----------------------------------------------------------------------------//  normalize// ----------------------------------------------------------------------------voidscfx_rep::normalize( int exponent ){    int shift = exponent % bits_in_word;    if( shift < 0 )    {	shift += bits_in_word;    }    if( shift )    {	shift_left( shift );    }    find_sw();    m_wp = (shift - exponent) / bits_in_word;}// ----------------------------------------------------------------------------//  return a new mantissa that is aligned and resized// ----------------------------------------------------------------------------scfx_mant*scfx_rep::resize( int new_size, int new_wp ) const{    scfx_mant *result = new scfx_mant( new_size );    result->clear();    int shift = new_wp - m_wp;    for( int j = m_lsw; j <= m_msw; j ++ )    {	(*result)[j+shift] = m_mant[j];    }    return result;}// ----------------------------------------------------------------------------//  set a single bit// ----------------------------------------------------------------------------voidscfx_rep::set_bin( int i ){    m_mant[i >> 5] |= 1 << ( i & 31 );}// ----------------------------------------------------------------------------//  set three bits// ----------------------------------------------------------------------------voidscfx_rep::set_oct( int i, int n ){    if( n & 1 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }    i ++;    if( n & 2 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }    i ++;    if( n & 4 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }}// ----------------------------------------------------------------------------//  set four bits// ----------------------------------------------------------------------------voidscfx_rep::set_hex( int i, int n ){    if( n & 1 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }    i ++;    if( n & 2 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }    i ++;    if( n & 4 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }    i ++;    if( n & 8 )    {	m_mant[i >> 5] |= 1 << ( i & 31 );    }}// ----------------------------------------------------------------------------//  PRIVATE METHOD : shift_left////  Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits.// ----------------------------------------------------------------------------voidscfx_rep::shift_left( int n ){    if( n != 0 )    {	int shift_left  = n;	int shift_right = bits_in_word - n;	SC_ASSERT_( !(m_mant[size()-1] >> shift_right),		    "shift_left overflow" );	for( int i = size() - 1; i > 0; i -- )	{	    m_mant[i] = ( m_mant[i] << shift_left ) |		       ( m_mant[i-1] >> shift_right );	}	m_mant[0] <<= shift_left;    }}// ----------------------------------------------------------------------------//  PRIVATE METHOD : shift_right////  Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits.// ----------------------------------------------------------------------------voidscfx_rep::shift_right( int n ){    if( n != 0 )    {	int shift_left  = bits_in_word - n;	int shift_right = n;	SC_ASSERT_( !(m_mant[0] << shift_left), "shift_right overflow" );	for( int i = 0; i < size() - 1; i ++ )	{	    m_mant[i] = ( m_mant[i] >> shift_right ) |		       ( m_mant[i+1] << shift_left );	}	m_mant[size()-1] >>= shift_right;    }}// ----------------------------------------------------------------------------//  METHOD : get_bit////  Tests a bit, in two's complement.// ----------------------------------------------------------------------------boolscfx_rep::get_bit( int i ) const{    if( ! is_normal() )	return false;    scfx_index x = calc_indices( i );    if( x.wi() >= size() )	return is_neg();    if( x.wi() < 0 )	return false;    const_cast<scfx_rep*>( this )->toggle_tc();    bool result = ( m_mant[x.wi()] & ( 1 << x.bi() ) ) != 0;    const_cast<scfx_rep*>( this )->toggle_tc();    return result;}// ----------------------------------------------------------------------------//  METHOD : set////  Sets a bit, in two's complement, between iwl-1 and -fwl.// ----------------------------------------------------------------------------boolscfx_rep::set( int i, const scfx_params& params ){    if( ! is_normal() )	return false;    scfx_index x = calc_indices( i );    if( x.wi() >= size() )    {	if( is_neg() )	    return true;	else	    resize_to( x.wi() + 1, 1 );    }    else if( x.wi() < 0 )    {	resize_to( size() - x.wi(), -1 );	x.wi( 0 );    }    toggle_tc();    m_mant[x.wi()] |= 1 << x.bi();    if( i == params.iwl() - 1 )        o_extend( x, params.enc() );  // sign extension    toggle_tc();    find_sw();    return true;}// ----------------------------------------------------------------------------//  METHOD : clear////  Clears a bit, in two's complement, between iwl-1 and -fwl.// ----------------------------------------------------------------------------boolscfx_rep::clear( int i, const scfx_params& params ){    if( ! is_normal() )	return false;    scfx_index x = calc_indices( i );    if( x.wi() >= size() )    {	if( ! is_neg() )	    return true;	else	    resize_to( x.wi() + 1, 1 );    }    else if( x.wi() < 0 )	return true;    toggle_tc();    m_mant[x.wi()] &= ~( 1 << x.bi() );    if( i == params.iwl() - 1 )        o_extend( x, params.enc() );  // sign extension    toggle_tc();    find_sw();    return true;}// ----------------------------------------------------------------------------//  METHOD : get_slice// ----------------------------------------------------------------------------boolscfx_rep::get_slice( int i, int j, const scfx_params&,		     sc_bv_base& bv ) const{    if( is_nan() || is_inf() )	return false;    // get the bits    int l = j;    for( int k = 0; k < bv.length(); ++ k )    {	bv[k] = get_bit( l );	if( i >= j )	    ++ l;	else	    -- l;    }    return true;}boolscfx_rep::set_slice( int i, int j, const scfx_params& params,		     const sc_bv_base& bv ){    if( is_nan() || is_inf() )        return false;    // set the bits    int l = j;    for( int k = 0; k < bv.length(); ++ k )    {	if( bv[k].to_bool() )	    set( l, params );	else	    clear( l, params );	if( i >= j )	    ++ l;	else	    -- l;    }    return true;}// ----------------------------------------------------------------------------//  METHOD : print// ----------------------------------------------------------------------------voidscfx_rep::print( ::std::ostream& os ) const{    os << to_string( SC_DEC, -1, SC_E );}// ----------------------------------------------------------------------------//  METHOD : dump// ----------------------------------------------------------------------------voidscfx_rep::dump( ::std::ostream& os ) const{    os << "scfx_rep" << ::std::endl;    os << "(" << ::std::endl;    os << "mant  =" << ::std::endl;    for( int i = size() - 1; i >= 0; i -- )    {	char buf[BUFSIZ];	std::sprintf( buf, " %d: %10u (%8x)", i, (int) m_mant[i], (int) m_mant[i] );	os << buf << ::std::endl;    }    os << "wp    = " << m_wp << ::std::endl;    os << "sign  = " << m_sign << ::std::endl;    os << "state = ";    switch( m_state )    {        case normal:	    os << "normal";	    break;        case infinity:	    os << "infinity";	    break;        case not_a_number:	    os << "not_a_number";	    break;        default:	    os << "unknown";    }    os << ::std::endl;    os << "msw   = " << m_msw << ::std::endl;    os << "lsw   = " << m_lsw << ::std::endl;    os << ")" << ::std::endl;}// ----------------------------------------------------------------------------//  METHOD : get_type// ----------------------------------------------------------------------------voidscfx_rep::get_type( int& wl, int& iwl, sc_enc& enc ) const{    if( is_nan() || is_inf() )    {        wl  = 0;        iwl = 0;        enc = SC_TC_;        return;    }    if( is_zero() )    {        wl  = 1;        iwl = 1;        enc = SC_US_;        return;    }    int msb = ( m_msw - m_wp ) * bits_in_word            + scfx_find_msb( m_mant[ m_msw ] ) + 1;    while( get_bit( msb ) == get_bit( msb - 1 ) )    {        -- msb;    }    int lsb = ( m_lsw - m_wp ) * bits_in_word            + scfx_find_lsb( m_mant[ m_lsw ] );    if( is_neg() )    {        wl  = msb - lsb + 1;        iwl = msb + 1;        enc = SC_TC_;    }    else    {        wl  = msb - lsb;        iwl = msb;        enc = SC_US_;    }}// ----------------------------------------------------------------------------//  PRIVATE METHOD : round////  Performs convergent rounding (rounding to even) as in floating-point.// ----------------------------------------------------------------------------voidscfx_rep::round( int wl ){    // check for special cases        if( is_nan() || is_inf() || is_zero() )	return;    // estimate effective wordlength and compare    int wl_effective;    wl_effective = ( m_msw - m_lsw + 1 ) * bits_in_word;    if( wl_effective <= wl )	return;    // calculate effective wordlength and compare    int msb = scfx_find_msb( m_mant[m_msw] );    int lsb = scfx_find_lsb( m_mant[m_lsw] );    wl_effective = ( m_msw * bits_in_word + msb ) -	           ( m_lsw * bits_in_word + lsb ) + 1;    if( wl_effective <= wl )	return;    // perform rounding    int wi = m_msw - ( wl - 1 ) / bits_in_word;    int bi =  msb - ( wl - 1 ) % bits_in_word;    if( bi < 0 )    {	-- wi;	bi += bits_in_word;    }    scfx_index x( wi, bi );    if( q_bit( x ) && ! q_zero( x ) ||	q_bit( x ) && q_zero( x ) && q_odd( x ) )	q_incr( x );    q_clear( x );    find_sw();    m_r_flag = true;}} // namespace sc_dt// Taf!

⌨️ 快捷键说明

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