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

📄 scfx_rep.cpp

📁 system C源码 一种替代verilog的语言
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************  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. *****************************************************************************//*****************************************************************************  scfx_rep.cpp -   Original Author: Robert Graulich, Synopsys, Inc.                   Martin Janssen,  Synopsys, Inc. *****************************************************************************//*****************************************************************************  MODIFICATION LOG - modifiers, enter your name, affiliation, date and  changes you are making here.      Name, Affiliation, Date:  Description of Modification: *****************************************************************************/// $Log: scfx_rep.cpp,v $// Revision 1.1.1.1  2006/12/15 20:31:36  acg// SystemC 2.2//// Revision 1.3  2006/01/13 18:53:58  acg// Andy Goodrich: added $Log command so that CVS comments are reproduced in// the source.//#include "sysc/utils/sc_machine.h"#include "sysc/datatypes/fx/scfx_rep.h"#include "sysc/datatypes/fx/scfx_ieee.h"#include "sysc/datatypes/fx/scfx_pow10.h"#include "sysc/datatypes/fx/scfx_utils.h"#include "sysc/datatypes/bit/sc_bv_base.h"#include <ctype.h>#include <math.h>namespace sc_dt{// ----------------------------------------------------------------------------//  some utilities// ----------------------------------------------------------------------------static scfx_pow10 pow10_fx;static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;static inlineintn_word( int x ){    return ( x + bits_in_word - 1 ) / bits_in_word;}// ----------------------------------------------------------------------------//  CONSTRUCTORS// ----------------------------------------------------------------------------scfx_rep::scfx_rep(): m_mant( min_mant ), m_r_flag( false ){    set_zero();}scfx_rep::scfx_rep( int a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_wp = m_msw = m_lsw = 2;	m_state = normal;	if( a > 0 )	{	    m_mant[2] = a;	    m_sign = 1;	}	else	{	    m_mant[2] = -a;	    m_sign = -1;	}    }    else        set_zero();}scfx_rep::scfx_rep( unsigned int a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_wp = m_msw = m_lsw = 2;	m_state = normal;	m_mant[2] = a;	m_sign = 1;    }    else        set_zero();}scfx_rep::scfx_rep( long a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_state = normal;        if ( a > 0 )        {	    m_sign = 1;        }        else        {            a = -a;            m_sign = -1;        } #       if defined(SC_LONG_64)            m_wp = 1;            m_mant[1] = static_cast<word>( a );            m_mant[2] = static_cast<word>( a >> bits_in_word );	    find_sw();#       else            m_wp = 2;            m_msw = 2;            m_lsw = 2;            m_mant[2] = a;#       endif    }    else        set_zero();}scfx_rep::scfx_rep( unsigned long a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_wp = m_msw = m_lsw = 2;	m_state = normal;#       if defined(SC_LONG_64)	    m_wp = 1;	    m_mant[1] = static_cast<word>( a );	    m_mant[2] = static_cast<word>( a >> bits_in_word );	    find_sw();#       else	    m_wp = 2;	    m_msw = 2;	    m_lsw = 2;	    m_mant[2] = a;#	endif	m_sign = 1;    }    else        set_zero();}scfx_rep::scfx_rep( double a ): m_mant( min_mant ), m_wp( 0 ), m_state( normal ), m_msw( 0 ), m_lsw( 0 ),  m_r_flag( false ){    m_mant.clear();    scfx_ieee_double id( a );    m_sign = id.negative() ? -1 : 1;    if( id.is_nan() )        m_state = not_a_number;    else if( id.is_inf() )        m_state = infinity;    else if( id.is_subnormal() )    {	m_mant[0] = id.mantissa1();	m_mant[1] = id.mantissa0();	normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE );    }    else if( id.is_normal() )    {	m_mant[0] = id.mantissa1();	m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size );	normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE );    }}scfx_rep::scfx_rep( int64 a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_wp = 1;	m_state = normal;	if( a > 0 )	{	    m_mant[1] = static_cast<word>( a );	    m_mant[2] = static_cast<word>( a >> bits_in_word );	    m_sign = 1;	}	else	{	    m_mant[1] = static_cast<word>( -a );	    m_mant[2] = static_cast<word>( (-a) >> bits_in_word );	    m_sign = -1;	}	find_sw();    }    else        set_zero();}scfx_rep::scfx_rep( uint64 a ): m_mant( min_mant ), m_r_flag( false ){    if( a != 0 )    {        m_mant.clear();	m_wp = 1;	m_state = normal;	m_mant[1] = static_cast<word>( a );	m_mant[2] = static_cast<word>( a >> bits_in_word );	m_sign = 1;	find_sw();    }    else        set_zero();}scfx_rep::scfx_rep( const sc_signed& a ): m_mant( min_mant ), m_r_flag( false ){    if( a.iszero() )	set_zero();    else    {	int words = n_word( a.length() );	if( words > size() )	    resize_to( words );	m_mant.clear();	m_wp = 0;	m_state = normal;	if( a.sign() )	{	    sc_signed a2 = -a;	    for( int i = 0; i < a2.length(); ++ i )	    {		if( a2[i] )		{		    scfx_index x = calc_indices( i );		    m_mant[x.wi()] |= 1 << x.bi();		}	    }	    m_sign = -1;	}	else	{	    for( int i = 0; i < a.length(); ++ i )	    {		if( a[i] )		{		    scfx_index x = calc_indices( i );		    m_mant[x.wi()] |= 1 << x.bi();		}	    }	    m_sign = 1;	}	find_sw();    }}scfx_rep::scfx_rep( const sc_unsigned& a ): m_mant( min_mant ), m_r_flag( false ){    if( a.iszero() )	set_zero();    else    {	int words = n_word( a.length() );	if( words > size() )	    resize_to( words );	m_mant.clear();	m_wp = 0;	m_state = normal;	for( int i = 0; i < a.length(); ++ i )	{	    if( a[i] )	    {		scfx_index x = calc_indices( i );		m_mant[x.wi()] |= 1 << x.bi();	    }	}	m_sign = 1;	find_sw();    }}// copy constructorscfx_rep::scfx_rep( const scfx_rep& a ): m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ),  m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false ){}// ----------------------------------------------------------------------------//  OPERATORS : new, delete////  Memory management for class scfx_rep.// ----------------------------------------------------------------------------union scfx_rep_node{    char           data[sizeof( scfx_rep )];    scfx_rep_node* next;};static scfx_rep_node* list = 0;void*scfx_rep::operator new( std::size_t size ){    const int ALLOC_SIZE = 1024;    if( size != sizeof( scfx_rep ) )	return ::operator new( size );    if( ! list )    {	list = new scfx_rep_node[ALLOC_SIZE];	for( int i = 0; i < ALLOC_SIZE - 1; i ++ )	    list[i].next = list + i + 1;	list[ALLOC_SIZE - 1].next = 0;    }    scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data );    list = list->next;    return ptr;}void scfx_rep::operator delete( void* ptr, std::size_t size ){    if( size != sizeof( scfx_rep ) )    {	::operator delete( ptr );	return;    }    scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr );    node->next = list;    list = node;}// ----------------------------------------------------------------------------//  METHOD : from_string////  Convert from character string to sc_fxrep.// ----------------------------------------------------------------------------#define SCFX_FAIL_IF_(cnd)                                                    \{                                                                             \    if( ( cnd ) )                                                             \    {                                                                         \        m_state = not_a_number;                                               \	m_mant.clear(); /* to avoid Purify UMRs during assignment */          \        return;                                                               \    }                                                                         \}voidscfx_rep::from_string( const char* s, int cte_wl ){    SCFX_FAIL_IF_( s == 0 || *s == 0 );    scfx_string s2;    s2 += s;    s2 += '\0';    bool sign_char;    m_sign = scfx_parse_sign( s, sign_char );    sc_numrep numrep = scfx_parse_prefix( s );    int base = 0;    switch( numrep )    {	case SC_DEC:	{	    base = 10;	    if( scfx_is_nan( s ) )	    {   // special case: NaN		m_state = not_a_number;		m_mant.clear(); /* to avoid Purify UMRs during assignment */		return;	    }	    if( scfx_is_inf( s ) )	    {   // special case: Infinity		m_state = infinity;		m_mant.clear(); /* to avoid Purify UMRs during assignment */		return;	    }	    break;	}	case SC_BIN:	case SC_BIN_US:	{	    SCFX_FAIL_IF_( sign_char );	    base = 2;	    break;	}		case SC_BIN_SM:	{	    base = 2;	    break;	}	case SC_OCT:	case SC_OCT_US:	{	    SCFX_FAIL_IF_( sign_char );	    base = 8;	    break;	}	case SC_OCT_SM:	{	    base = 8;	    break;	}	case SC_HEX:	case SC_HEX_US:	{	    SCFX_FAIL_IF_( sign_char );	    base = 16;	    break;	}	case SC_HEX_SM:	{	    base = 16;	    break;	}	case SC_CSD:	{	    SCFX_FAIL_IF_( sign_char );	    base = 2;	    scfx_csd2tc( s2 );	    s = (const char*) s2 + 4;	    numrep = SC_BIN;	    break;	}        default:;    }    //    // find end of mantissa and count the digits and points    //    const char *end = s;    bool based_point = false;    int int_digits = 0;    int frac_digits = 0;    while( *end )    {	if( scfx_exp_start( end ) )	    break;		if( *end == '.' )	{	    SCFX_FAIL_IF_( based_point );	    based_point = true;	}	else	{	    SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );	    if( based_point )		frac_digits ++;	    else		int_digits ++;	}	++ end;    }    SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );    // [ exponent ]        int exponent = 0;    if( *end )    {	for( const char *e = end + 2; *e; ++ e )	    SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );	exponent = atoi( end + 1 );    }    //    // check if the mantissa is negative    //    bool mant_is_neg = false;    switch( numrep )    {	case SC_BIN:	case SC_OCT:	case SC_HEX:	{	    const char* p = s;	    if( *p == '.' )		++ p;	    mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) );	    break;	}	default:	    ;    }    //    // convert the mantissa    //    switch( base )    {        case 2:	{	    int bit_offset = exponent % bits_in_word;	    int word_offset = exponent / bits_in_word;	    int_digits += bit_offset;	    frac_digits -= bit_offset;	    int words = n_word( int_digits ) + n_word( frac_digits );	    if( words > size() )		resize_to( words );	    m_mant.clear();	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 1;	    	    for( ; s < end; s ++ )	    {		switch( *s )		{		    case '1':		        set_bin( j );		    case '0':			j --;		    case '.':			break;		    default:			SCFX_FAIL_IF_( true );  // should not happen		}	    }	    m_wp = n_word( frac_digits ) - word_offset;	    break;	}        case 8:	{	    exponent *= 3;	    int_digits *= 3;	    frac_digits *= 3;	    int bit_offset = exponent % bits_in_word;	    int word_offset = exponent / bits_in_word;	    int_digits += bit_offset;	    frac_digits -= bit_offset;	    int words = n_word( int_digits ) + n_word( frac_digits );	    if( words > size() )		resize_to( words );	    m_mant.clear();	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 3;	    	    for( ; s < end; s ++ )	    {		switch( *s )		{		    case '7': case '6': case '5': case '4':		    case '3': case '2': case '1':		        set_oct( j, *s - '0' );		    case '0':			j -= 3;		    case '.':			break;		    default:			SCFX_FAIL_IF_( true );  // should not happen		}	    }	    m_wp = n_word( frac_digits ) - word_offset;	    break;	}        case 10:	{	    word carry, temp;	    int length = int_digits + frac_digits;	    resize_to( sc_max( min_mant, n_word( 4 * length ) ) );	    m_mant.clear();	    m_msw = m_lsw = 0;	    	    for( ; s < end; s ++ )	    {		switch( *s )		{		    case '9': case '8': case '7': case '6': case '5':		    case '4': case '3': case '2': case '1': case '0':		        multiply_by_ten();			carry = *s - '0';			for ( int i = 0; carry && i < m_mant.size(); i++ )			{			    temp = m_mant[i];                            temp += carry;			    			    carry = temp < m_mant[i];			    m_mant[i] = temp;			}		    case '.':			break;		    default:			SCFX_FAIL_IF_( true );  // should not happen		}	    }	    	    m_wp = 0;	    find_sw();	    int denominator = frac_digits - exponent;	    	    if( denominator )	    {		scfx_rep frac_num = pow10_fx( denominator );		scfx_rep* temp_num =		    div_scfx_rep( const_cast<const scfx_rep&>( *this ),				   frac_num, cte_wl );		*this = *temp_num;		delete temp_num;	    }	    break;	}        case 16:	{	    exponent *= 4;	    int_digits *= 4;	    frac_digits *= 4;	    int bit_offset = exponent % bits_in_word;	    int word_offset = exponent / bits_in_word;	    int_digits += bit_offset;	    frac_digits -= bit_offset;	    int words = n_word( int_digits ) + n_word( frac_digits );	    if( words > size() )		resize_to( words );	    m_mant.clear();	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 4;	    	    for( ; s < end; s ++ )	    {		switch( *s )		{		    case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':		       set_hex( j, *s - 'a' + 10 );		       j -= 4;		       break;		    case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':		       set_hex( j, *s - 'A' + 10 );		       j -= 4;		       break;		    case '9': case '8': case '7': case '6': case '5':		    case '4': case '3': case '2': case '1':		       set_hex( j, *s - '0' );		    case '0':		       j -= 4;		    case '.':		       break;		   default:		       SCFX_FAIL_IF_( true );  // should not happen		}	    }	    m_wp = n_word( frac_digits ) - word_offset;	    break;	}    }

⌨️ 快捷键说明

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