diff options
Diffstat (limited to 'ext/systemc/src/sysc/datatypes/fx')
33 files changed, 23595 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/datatypes/fx/fx.h b/ext/systemc/src/sysc/datatypes/fx/fx.h new file mode 100644 index 000000000..9c35014fa --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/fx.h @@ -0,0 +1,61 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + fx.h - Master include file for the fixed-point types. + + Original Author: 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: fx.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef FX_H +#define FX_H + + +#include "sysc/datatypes/fx/sc_fixed.h" +#include "sysc/datatypes/fx/sc_fxcast_switch.h" +#include "sysc/datatypes/fx/sc_fxtype_params.h" +#include "sysc/datatypes/fx/sc_ufixed.h" + +#include "sysc/datatypes/fx/scfx_other_defs.h" + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_context.h b/ext/systemc/src/sysc/datatypes/fx/sc_context.h new file mode 100644 index 000000000..1e313a486 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_context.h @@ -0,0 +1,316 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_context.h - + + Original Author: 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: sc_context.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/26 20:36:52 acg +// Andy Goodrich: added a using for sc_core::default_ptr_hash_fn to keep HP +// aCC happy. +// +// Revision 1.4 2006/03/21 00:00:31 acg +// Andy Goodrich: changed name of sc_get_current_process_base() to be +// sc_get_current_process_b() since its returning an sc_process_b instance. +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_CONTEXT_H +#define SC_CONTEXT_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/kernel/sc_simcontext.h" +#include "sysc/utils/sc_hash.h" + + +namespace sc_core { + class sc_process_b; +} + +using sc_core::default_ptr_hash_fn; // To keep HP aCC happy. + +namespace sc_dt +{ + +// classes defined in this module +class sc_without_context; +template <class T> class sc_global; +template <class T> class sc_context; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_without_context +// +// Empty class that is used for its type only. +// ---------------------------------------------------------------------------- + +class sc_without_context {}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_global +// +// Template global variable class; singleton; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_global +{ + + sc_global(); + + void update(); + +public: + + static sc_global<T>* instance(); + + const T*& value_ptr(); + +private: + static sc_global<T>* m_instance; + + sc_core::sc_phash<void*,const T*> m_map; + void* m_proc; // context (current process or NULL) + const T* m_value_ptr; + +}; + + +// ---------------------------------------------------------------------------- +// ENUM : sc_context_begin +// +// Enumeration of context begin options. +// ---------------------------------------------------------------------------- + +enum sc_context_begin +{ + SC_NOW, + SC_LATER +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_context +// +// Template context class; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_context +{ + // disabled + sc_context( const sc_context<T>& ); + void* operator new( std::size_t ); + +public: + + explicit sc_context( const T&, sc_context_begin = SC_NOW ); + ~sc_context(); + + void begin(); + void end(); + + static const T& default_value(); + const T& value() const; + +private: + + const T m_value; + const T*& m_def_value_ptr; + const T* m_old_value_ptr; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_global +// +// Template global variable class; singleton; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +sc_global<T>* sc_global<T>::m_instance = 0; + +template <class T> +inline +sc_global<T>::sc_global() + : m_map() + // use &m_instance as unique "non-process" key (NULL denotes 'sc_main' context) + , m_proc( &m_instance ) + , m_value_ptr( 0 ) +{} + + +template <class T> +inline +void +sc_global<T>::update() +{ + void* p = sc_core::sc_get_current_process_b(); + if( p != m_proc ) + { + const T* vp = m_map[p]; + if( vp == 0 ) + { + vp = new T( sc_without_context() ); + m_map.insert( p, vp ); + } + m_proc = p; + m_value_ptr = vp; + } +} + + +template <class T> +inline +sc_global<T>* +sc_global<T>::instance() +{ + if( m_instance == 0 ) + { + m_instance = new sc_global<T>; + } + return m_instance; +} + + +template <class T> +inline +const T*& +sc_global<T>::value_ptr() +{ + update(); + return m_value_ptr; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_context +// +// Template context class; co-routine safe. +// ---------------------------------------------------------------------------- + +template <class T> +inline +sc_context<T>::sc_context( const T& value_, sc_context_begin begin ) +: m_value( value_ ), + m_def_value_ptr( sc_global<T>::instance()->value_ptr() ), + m_old_value_ptr( 0 ) +{ + if( begin == SC_NOW ) + { + m_old_value_ptr = m_def_value_ptr; + m_def_value_ptr = &m_value; + } +} + +template <class T> +inline +sc_context<T>::~sc_context() +{ + if( m_old_value_ptr != 0 ) + { + m_def_value_ptr = m_old_value_ptr; + m_old_value_ptr = 0; + } +} + + +template <class T> +inline +void +sc_context<T>::begin() +{ + if( m_old_value_ptr == 0 ) + { + m_old_value_ptr = m_def_value_ptr; + m_def_value_ptr = &m_value; + } + else + { + SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_BEGIN_FAILED_, 0 ); + } +} + +template <class T> +inline +void +sc_context<T>::end() +{ + if( m_old_value_ptr != 0 ) + { + m_def_value_ptr = m_old_value_ptr; + m_old_value_ptr = 0; + } + else + { + SC_REPORT_ERROR( sc_core::SC_ID_CONTEXT_END_FAILED_, 0 ); + } +} + + +template <class T> +inline +const T& +sc_context<T>::default_value() +{ + return *sc_global<T>::instance()->value_ptr(); +} + +template <class T> +inline +const T& +sc_context<T>::value() const +{ + return m_value; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fix.h b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h new file mode 100644 index 000000000..80df65a2c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fix.h @@ -0,0 +1,1938 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fix.h - + + Original Author: 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: sc_fix.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FIX_H +#define SC_FIX_H + + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fix; +class sc_fix_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix +// +// "Unconstrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fix : public sc_fxnum +{ + +public: + + // constructors + + explicit sc_fix( sc_fxnum_observer* = 0 ); + sc_fix( int, int, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + explicit sc_fix( const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_fix( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + explicit sc_fix( const sc_fxtype_params&, + sc_fxnum_observer* = 0 ); + sc_fix( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_fix( tp, \ + int, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_observer* = 0 ); \ + sc_fix( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fix( const sc_fix& ); + + + // unary bitwise operators + + const sc_fix operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_fix&, const sc_fix& ); + + + // binary bitwise operators + + friend const sc_fix operator & ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator & ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator & ( const sc_fix_fast&, const sc_fix& ); + friend const sc_fix operator | ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator | ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator | ( const sc_fix_fast&, const sc_fix& ); + friend const sc_fix operator ^ ( const sc_fix&, const sc_fix& ); + friend const sc_fix operator ^ ( const sc_fix&, const sc_fix_fast& ); + friend const sc_fix operator ^ ( const sc_fix_fast&, const sc_fix& ); + + + // binary bitwise functions + + friend void b_and( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_and( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_and( sc_fix&, const sc_fix_fast&, const sc_fix& ); + friend void b_or ( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_or ( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_or ( sc_fix&, const sc_fix_fast&, const sc_fix& ); + friend void b_xor( sc_fix&, const sc_fix&, const sc_fix& ); + friend void b_xor( sc_fix&, const sc_fix&, const sc_fix_fast& ); + friend void b_xor( sc_fix&, const sc_fix_fast&, const sc_fix& ); + + + // assignment operators + + sc_fix& operator = ( const sc_fix& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fix& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fix& operator ++ (); + sc_fix& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix_fast +// +// "Unconstrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fix_fast : public sc_fxnum_fast +{ + +public: + + // constructors + + explicit sc_fix_fast( sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + explicit sc_fix_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + explicit sc_fix_fast( const sc_fxtype_params&, + sc_fxnum_fast_observer* = 0 ); + sc_fix_fast( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_fix_fast( tp, \ + int, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_fix_fast( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fix_fast( const sc_fix_fast& ); + + + // unary bitwise operators + + const sc_fix_fast operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_fix_fast&, const sc_fix_fast& ); + + + // binary bitwise operators + + friend const sc_fix_fast operator & ( const sc_fix_fast&, + const sc_fix_fast& ); + friend const sc_fix_fast operator ^ ( const sc_fix_fast&, + const sc_fix_fast& ); + friend const sc_fix_fast operator | ( const sc_fix_fast&, + const sc_fix_fast& ); + + + // binary bitwise functions + + friend void b_and( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + friend void b_or ( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + friend void b_xor( sc_fix_fast&, const sc_fix_fast&, const sc_fix_fast& ); + + + // assignment operators + + sc_fix_fast& operator = ( const sc_fix_fast& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fix_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fix_fast& operator ++ (); + sc_fix_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix +// +// "Unconstrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_fix::sc_fix( sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxtype_params& type_params, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix::sc_fix( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_TC_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix::sc_fix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_fix::sc_fix( const sc_fix& a ) +: sc_fxnum( a, + a.type_params(), + SC_TC_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_fix +sc_fix::operator ~ () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_fix c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_fix( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_fix& c, const sc_fix& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_fix \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_fix c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_fix( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix) +DEFN_BIN_OP_T(&,&&,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix) + +DEFN_BIN_OP_T(|,||,sc_fix,sc_fix) +DEFN_BIN_OP_T(|,||,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix) + +DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix) +DEFN_BIN_OP_T(^,!=,sc_fix,sc_fix_fast) +DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_fix& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_and,&&,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix) + +DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_or,||,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix) + +DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix,sc_fix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_fix& +sc_fix::operator = ( const sc_fix& a ) +{ + sc_fxnum::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fix& \ +sc_fix::operator op ( tp a ) \ +{ \ + sc_fxnum::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_fix& \ +sc_fix::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_fix) +DEFN_ASN_OP_T(&=,&&,sc_fix_fast) +DEFN_ASN_OP_T(|=,||,sc_fix) +DEFN_ASN_OP_T(|=,||,sc_fix_fast) +DEFN_ASN_OP_T(^=,!=,sc_fix) +DEFN_ASN_OP_T(^=,!=,sc_fix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fix::operator ++ ( int ) +{ + return sc_fxval( sc_fxnum::operator ++ ( 0 ) ); +} + +inline +const sc_fxval +sc_fix::operator -- ( int ) +{ + return sc_fxval( sc_fxnum::operator -- ( 0 ) ); +} + +inline +sc_fix& +sc_fix::operator ++ () +{ + sc_fxnum::operator ++ (); + return *this; +} + +inline +sc_fix& +sc_fix::operator -- () +{ + sc_fxnum::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fix_fast +// +// "Unconstrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_fix_fast::sc_fix_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_TC_, + cast_sw, + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_TC_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_fix_fast::sc_fix_fast( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_TC_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_fix_fast::sc_fix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_TC_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_fix_fast::sc_fix_fast( const sc_fix_fast& a ) +: sc_fxnum_fast( a, + a.type_params(), + SC_TC_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_fix_fast +sc_fix_fast::operator ~ () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_fix_fast c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_fix_fast( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_fix_fast& c, const sc_fix_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_fix_fast \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_fix_fast c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_fix_fast( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_fix_fast,sc_fix_fast) +DEFN_BIN_OP_T(|,||,sc_fix_fast,sc_fix_fast) +DEFN_BIN_OP_T(^,!=,sc_fix_fast,sc_fix_fast) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_fix_fast& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_fix_fast,sc_fix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_fix_fast,sc_fix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_fix_fast,sc_fix_fast) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_fix_fast& +sc_fix_fast::operator = ( const sc_fix_fast& a ) +{ + sc_fxnum_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fix_fast& \ +sc_fix_fast::operator op ( tp a ) \ +{ \ + sc_fxnum_fast::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_fix_fast& \ +sc_fix_fast::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_fix) +DEFN_ASN_OP_T(&=,&&,sc_fix_fast) +DEFN_ASN_OP_T(|=,||,sc_fix) +DEFN_ASN_OP_T(|=,||,sc_fix_fast) +DEFN_ASN_OP_T(^=,!=,sc_fix) +DEFN_ASN_OP_T(^=,!=,sc_fix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fix_fast::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) ); +} + +inline +const sc_fxval_fast +sc_fix_fast::operator -- ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) ); +} + +inline +sc_fix_fast& +sc_fix_fast::operator ++ () +{ + sc_fxnum_fast::operator ++ (); + return *this; +} + +inline +sc_fix_fast& +sc_fix_fast::operator -- () +{ + sc_fxnum_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h new file mode 100644 index 000000000..b885da1f9 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fixed.h @@ -0,0 +1,660 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fixed.h - + + Original Author: 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: sc_fixed.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FIXED_H +#define SC_FIXED_H + + +#include "sysc/datatypes/fx/sc_fix.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed; +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_fixed_fast; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed +// +// "Constrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_fixed : public sc_fix +{ + +public: + + // constructors + + explicit sc_fixed( sc_fxnum_observer* = 0 ); + explicit sc_fixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fixed( tp, sc_fxnum_observer* = 0 ); \ + sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fixed( tp, sc_fxnum_observer* = 0 ); \ + sc_fixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fixed( const sc_fixed<W,I,Q,O,N>& ); + + + // assignment operators + + sc_fixed& operator = ( const sc_fixed<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fixed& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fixed& operator ++ (); + sc_fixed& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed_fast +// +// "Constrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_fixed_fast : public sc_fix_fast +{ + +public: + + // constructors + + explicit sc_fixed_fast( sc_fxnum_fast_observer* = 0 ); + explicit sc_fixed_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_fixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_fixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_fixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& ); + + + // assignment operators + + sc_fixed_fast& operator = ( const sc_fixed_fast<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_fixed_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_fix&) + DECL_ASN_OP_T(&=,const sc_fix_fast&) + DECL_ASN_OP_T(|=,const sc_fix&) + DECL_ASN_OP_T(|=,const sc_fix_fast&) + DECL_ASN_OP_T(^=,const sc_fix&) + DECL_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fixed_fast& operator ++ (); + sc_fixed_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed +// +// "Constrained" signed fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( sc_fxnum_observer* observer_ ) +: sc_fix( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fix( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fix( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>::sc_fixed( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fix( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>::sc_fixed( const sc_fixed<W,I,Q,O,N>& a ) +: sc_fix( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator = ( const sc_fixed<W,I,Q,O,N>& a ) +{ + sc_fix::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed<W,I,Q,O,N>& \ +sc_fixed<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_fix::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_fix&) +DEFN_ASN_OP_T(&=,const sc_fix_fast&) +DEFN_ASN_OP_T(|=,const sc_fix&) +DEFN_ASN_OP_T(|=,const sc_fix_fast&) +DEFN_ASN_OP_T(^=,const sc_fix&) +DEFN_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_fixed<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval( sc_fix::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_fixed<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval( sc_fix::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator ++ () +{ + sc_fix::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed<W,I,Q,O,N>& +sc_fixed<W,I,Q,O,N>::operator -- () +{ + sc_fix::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_fixed_fast +// +// "Constrained" signed fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fix_fast( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fix_fast( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fix_fast( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>::sc_fixed_fast( const sc_fixed_fast<W,I,Q,O,N>& a ) +: sc_fix_fast( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator = ( const sc_fixed_fast<W,I,Q,O,N>& a ) +{ + sc_fix_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_fixed_fast<W,I,Q,O,N>& \ +sc_fixed_fast<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_fix_fast::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_fix&) +DEFN_ASN_OP_T(&=,const sc_fix_fast&) +DEFN_ASN_OP_T(|=,const sc_fix&) +DEFN_ASN_OP_T(|=,const sc_fix_fast&) +DEFN_ASN_OP_T(^=,const sc_fix&) +DEFN_ASN_OP_T(^=,const sc_fix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_fixed_fast<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fix_fast::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_fixed_fast<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval_fast( sc_fix_fast::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator ++ () +{ + sc_fix_fast::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_fixed_fast<W,I,Q,O,N>& +sc_fixed_fast<W,I,Q,O,N>::operator -- () +{ + sc_fix_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h new file mode 100644 index 000000000..b40c2dc48 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fx_ids.h @@ -0,0 +1,96 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fx_ids.h -- Report ids for the datatypes/fx code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_fx_ids.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FX_IDS_H +#define SC_FX_IDS_H + + +#include "sysc/utils/sc_report.h" + + +// ---------------------------------------------------------------------------- +// Report ids (datatypes/fx) +// +// Report ids in the range of 300-399. +// ---------------------------------------------------------------------------- + +#ifndef SC_DEFINE_MESSAGE +#define SC_DEFINE_MESSAGE(id,unused1,unused2) \ + namespace sc_core { extern const char id[]; } +namespace sc_core { + extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp +} +#endif + + +SC_DEFINE_MESSAGE( SC_ID_INVALID_WL_, 300, + "total wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_N_BITS_, 301, + "number of bits < 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_DIV_WL_, 302, + "division wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_CTE_WL_, 303, + "constant wordlength <= 0 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_MAX_WL_, 304, + "maximum wordlength <= 0 and != -1 is not valid" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_FX_VALUE_, 305, + "invalid fixed-point value" ) +SC_DEFINE_MESSAGE( SC_ID_INVALID_O_MODE_, 306, + "invalid overflow mode" ) +SC_DEFINE_MESSAGE( SC_ID_OUT_OF_RANGE_, 307, + "index out of range" ) +SC_DEFINE_MESSAGE( SC_ID_CONTEXT_BEGIN_FAILED_, 308, + "context begin failed" ) +SC_DEFINE_MESSAGE( SC_ID_CONTEXT_END_FAILED_, 309, + "context end failed" ) +SC_DEFINE_MESSAGE( SC_ID_WRAP_SM_NOT_DEFINED_, 310, + "SC_WRAP_SM not defined for unsigned numbers" ) + + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp new file mode 100644 index 000000000..c5c5a939c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.cpp @@ -0,0 +1,88 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxcast_switch.cpp - + + Original Author: Martin Janssen, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushuyev, Synopsys, Inc. + Description of Modification: - fix explicit instantiation syntax. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + + +// $Log: sc_fxcast_switch.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxcast_switch.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxcast_switch +// +// Fixed-point cast switch class. +// ---------------------------------------------------------------------------- + +const std::string +sc_fxcast_switch::to_string() const +{ + return sc_dt::to_string( m_sw ); +} + + +void +sc_fxcast_switch::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_sw ); +} + +void +sc_fxcast_switch::dump( ::std::ostream& os ) const +{ + os << "sc_fxcast_switch" << ::std::endl; + os << "(" << ::std::endl; + os << "sw = " << sc_dt::to_string( m_sw ) << ::std::endl; + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h new file mode 100644 index 000000000..6bfbd25a4 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxcast_switch.h @@ -0,0 +1,174 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxcast_switch.h - + + Original Author: 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: sc_fxcast_switch.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXCAST_SWITCH_H +#define SC_FXCAST_SWITCH_H + + +#include "sysc/datatypes/fx/sc_context.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxcast_switch; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxcast_switch +// +// Fixed-point cast switch class. +// ---------------------------------------------------------------------------- + +class sc_fxcast_switch +{ + +public: + + sc_fxcast_switch(); + sc_fxcast_switch( sc_switch ); + sc_fxcast_switch( const sc_fxcast_switch& ); + explicit sc_fxcast_switch( sc_without_context ); + + sc_fxcast_switch& operator = ( const sc_fxcast_switch& ); + + friend bool operator == ( const sc_fxcast_switch&, + const sc_fxcast_switch& ); + friend bool operator != ( const sc_fxcast_switch&, + const sc_fxcast_switch& ); + + const std::string to_string() const; + + void print( ::std::ostream& = ::std::cout ) const; + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_switch m_sw; + +}; + + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_fxcast_context +// +// Context type for the fixed-point cast switch parameter. +// ---------------------------------------------------------------------------- + +typedef sc_context<sc_fxcast_switch> sc_fxcast_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +sc_fxcast_switch::sc_fxcast_switch() +: m_sw() +{ + *this = sc_fxcast_context::default_value(); +} + +inline +sc_fxcast_switch::sc_fxcast_switch( sc_switch sw_ ) +: m_sw( sw_ ) +{} + +inline +sc_fxcast_switch::sc_fxcast_switch( const sc_fxcast_switch& a ) +: m_sw( a.m_sw ) +{} + +inline +sc_fxcast_switch::sc_fxcast_switch( sc_without_context ) +: m_sw( SC_DEFAULT_CAST_SWITCH_ ) +{} + + +inline +sc_fxcast_switch& +sc_fxcast_switch::operator = ( const sc_fxcast_switch& a ) +{ + if( &a != this ) + { + m_sw = a.m_sw; + } + return *this; +} + + +inline +bool +operator == ( const sc_fxcast_switch& a, const sc_fxcast_switch& b ) +{ + return ( a.m_sw == b.m_sw ); +} + + +inline +bool +operator != ( const sc_fxcast_switch& a, const sc_fxcast_switch& b ) +{ + return ( a.m_sw != b.m_sw ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxcast_switch& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp new file mode 100644 index 000000000..66ade2076 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.cpp @@ -0,0 +1,175 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxdefs.cpp - + + Original Author: 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: sc_fxdefs.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_enc +// +// Enumeration of sign encodings. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_enc enc ) +{ + switch( enc ) + { + case SC_TC_: + return std::string( "SC_TC_" ); + case SC_US_: + return std::string( "SC_US_" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_q_mode +// +// Enumeration of quantization modes. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_q_mode q_mode ) +{ + switch( q_mode ) + { + case SC_RND: + return std::string( "SC_RND" ); + case SC_RND_ZERO: + return std::string( "SC_RND_ZERO" ); + case SC_RND_MIN_INF: + return std::string( "SC_RND_MIN_INF" ); + case SC_RND_INF: + return std::string( "SC_RND_INF" ); + case SC_RND_CONV: + return std::string( "SC_RND_CONV" ); + case SC_TRN: + return std::string( "SC_TRN" ); + case SC_TRN_ZERO: + return std::string( "SC_TRN_ZERO" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_o_mode +// +// Enumeration of overflow modes. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_o_mode o_mode ) +{ + switch( o_mode ) + { + case SC_SAT: + return std::string( "SC_SAT" ); + case SC_SAT_ZERO: + return std::string( "SC_SAT_ZERO" ); + case SC_SAT_SYM: + return std::string( "SC_SAT_SYM" ); + case SC_WRAP: + return std::string( "SC_WRAP" ); + case SC_WRAP_SM: + return std::string( "SC_WRAP_SM" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_switch +// +// Enumeration of switch states. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_switch sw ) +{ + switch( sw ) { + case SC_OFF: + return std::string( "SC_OFF" ); + case SC_ON: + return std::string( "SC_ON" ); + default: + return std::string( "unknown" ); + } +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_fmt +// +// Enumeration of formats for character string conversion. +// ---------------------------------------------------------------------------- + +const std::string +to_string( sc_fmt fmt ) +{ + switch( fmt ) { + case SC_F: + return std::string( "SC_F" ); + case SC_E: + return std::string( "SC_E" ); + default: + return std::string( "unknown" ); + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h new file mode 100644 index 000000000..1ac1bb707 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxdefs.h @@ -0,0 +1,308 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxdefs.h - + + Original Author: 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: sc_fxdefs.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXDEFS_H +#define SC_FXDEFS_H + + +#include "sysc/utils/sc_machine.h" +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/int/sc_nbutils.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// ENUM : sc_enc +// +// Enumeration of sign encodings. +// ---------------------------------------------------------------------------- + +enum sc_enc +{ + SC_TC_, // two's complement + SC_US_ // unsigned +}; + + +const std::string to_string( sc_enc ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_enc enc ) +{ + return os << to_string( enc ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_q_mode +// +// Enumeration of quantization modes. +// ---------------------------------------------------------------------------- + +enum sc_q_mode +{ + SC_RND, // rounding to plus infinity + SC_RND_ZERO, // rounding to zero + SC_RND_MIN_INF, // rounding to minus infinity + SC_RND_INF, // rounding to infinity + SC_RND_CONV, // convergent rounding + SC_TRN, // truncation + SC_TRN_ZERO // truncation to zero +}; + + +const std::string to_string( sc_q_mode ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_q_mode q_mode ) +{ + return os << to_string( q_mode ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_o_mode +// +// Enumeration of overflow modes. +// ---------------------------------------------------------------------------- + +enum sc_o_mode +{ + SC_SAT, // saturation + SC_SAT_ZERO, // saturation to zero + SC_SAT_SYM, // symmetrical saturation + SC_WRAP, // wrap-around (*) + SC_WRAP_SM // sign magnitude wrap-around (*) +}; + +// (*) uses the number of saturated bits argument, see the documentation. + + +const std::string to_string( sc_o_mode ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_o_mode o_mode ) +{ + return os << to_string( o_mode ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_switch +// +// Enumeration of switch states. +// ---------------------------------------------------------------------------- + +enum sc_switch +{ + SC_OFF, + SC_ON +}; + + +const std::string to_string( sc_switch ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_switch sw ) +{ + return os << to_string( sw ); +} + + +// ---------------------------------------------------------------------------- +// ENUM : sc_fmt +// +// Enumeration of formats for character string conversion. +// ---------------------------------------------------------------------------- + +enum sc_fmt +{ + SC_F, // fixed + SC_E // scientific +}; + + +const std::string to_string( sc_fmt ); + + +inline +::std::ostream& +operator << ( ::std::ostream& os, sc_fmt fmt ) +{ + return os << to_string( fmt ); +} + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point type parameter values. +// ---------------------------------------------------------------------------- + +const int SC_BUILTIN_WL_ = 32; +const int SC_BUILTIN_IWL_ = 32; +const sc_q_mode SC_BUILTIN_Q_MODE_ = SC_TRN; +const sc_o_mode SC_BUILTIN_O_MODE_ = SC_WRAP; +const int SC_BUILTIN_N_BITS_ = 0; + + +const int SC_DEFAULT_WL_ = SC_BUILTIN_WL_; +const int SC_DEFAULT_IWL_ = SC_BUILTIN_IWL_; +const sc_q_mode SC_DEFAULT_Q_MODE_ = SC_BUILTIN_Q_MODE_; +const sc_o_mode SC_DEFAULT_O_MODE_ = SC_BUILTIN_O_MODE_; +const int SC_DEFAULT_N_BITS_ = SC_BUILTIN_N_BITS_; + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point cast switch parameter values. +// ---------------------------------------------------------------------------- + +const sc_switch SC_BUILTIN_CAST_SWITCH_ = SC_ON; + + +const sc_switch SC_DEFAULT_CAST_SWITCH_ = SC_BUILTIN_CAST_SWITCH_; + + +// ---------------------------------------------------------------------------- +// Built-in & default fixed-point value type parameter values. +// ---------------------------------------------------------------------------- + +const int SC_BUILTIN_DIV_WL_ = 64; +const int SC_BUILTIN_CTE_WL_ = 64; +const int SC_BUILTIN_MAX_WL_ = 1024; + + +#if defined( SC_FXDIV_WL ) && ( SC_FXDIV_WL > 0 ) +const int SC_DEFAULT_DIV_WL_ = SC_FXDIV_WL; +#else +const int SC_DEFAULT_DIV_WL_ = SC_BUILTIN_DIV_WL_; +#endif + +#if defined( SC_FXCTE_WL ) && ( SC_FXCTE_WL > 0 ) +const int SC_DEFAULT_CTE_WL_ = SC_FXCTE_WL; +#else +const int SC_DEFAULT_CTE_WL_ = SC_BUILTIN_CTE_WL_; +#endif + +#if defined( SC_FXMAX_WL ) && ( SC_FXMAX_WL > 0 || SC_FXMAX_WL == -1 ) +const int SC_DEFAULT_MAX_WL_ = SC_FXMAX_WL; +#else +const int SC_DEFAULT_MAX_WL_ = SC_BUILTIN_MAX_WL_; +#endif + + +// ---------------------------------------------------------------------------- +// Dedicated error reporting and checking. +// ---------------------------------------------------------------------------- + +#ifdef DEBUG_SYSTEMC +#define SC_ASSERT_(cnd,msg) \ +{ \ + if( ! (cnd) ) \ + SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, msg ); \ +} +#else +#define SC_ASSERT_(cnd,msg) +#endif + +#define SC_ERROR_IF_(cnd,id) \ +{ \ + if( cnd ) \ + SC_REPORT_ERROR( id, 0 ); \ +} + + +#define SC_CHECK_WL_(wl) \ + SC_ERROR_IF_( (wl) <= 0, sc_core::SC_ID_INVALID_WL_ ) + +#define SC_CHECK_N_BITS_(n_bits) \ + SC_ERROR_IF_( (n_bits) < 0, sc_core::SC_ID_INVALID_N_BITS_ ) + +#define SC_CHECK_DIV_WL_(div_wl) \ + SC_ERROR_IF_( (div_wl) <= 0, sc_core::SC_ID_INVALID_DIV_WL_ ) + +#define SC_CHECK_CTE_WL_(cte_wl) \ + SC_ERROR_IF_( (cte_wl) <= 0, sc_core::SC_ID_INVALID_CTE_WL_ ) + +#define SC_CHECK_MAX_WL_(max_wl) \ + SC_ERROR_IF_( (max_wl) <= 0 && (max_wl) != -1, \ + sc_core::SC_ID_INVALID_MAX_WL_ ) + + +// ---------------------------------------------------------------------------- +// Generic observer macros. +// ---------------------------------------------------------------------------- + +#define SC_OBSERVER_(object,observer_type,event) \ +{ \ + if( (object).observer() != 0 ) \ + { \ + observer_type observer = (object).lock_observer(); \ + observer->event( (object) ); \ + (object).unlock_observer( observer ); \ + } \ +} + +#define SC_OBSERVER_DEFAULT_(observer_type) \ +{ \ + if( m_observer == 0 && observer_type ## ::default_observer != 0 ) \ + m_observer = (* ## observer_type ## ::default_observer)(); \ +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp new file mode 100644 index 000000000..520c41854 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.cpp @@ -0,0 +1,958 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum.cpp - + + Original Author: 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: sc_fxnum.cpp,v $ +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:57 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#include <math.h> + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_bitref::get() const +{ + return m_num.get_bit( m_idx ); +} + +void +sc_fxnum_bitref::set( bool high ) +{ + m_num.set_bit( m_idx, high ); +} + + +// print or dump content + +void +sc_fxnum_bitref::print( ::std::ostream& os ) const +{ + os << get(); +} + +void +sc_fxnum_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + +void +sc_fxnum_bitref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_bitref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "idx = " << m_idx << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_fast_bitref::get() const +{ + return m_num.get_bit( m_idx ); +} + +void +sc_fxnum_fast_bitref::set( bool high ) +{ + m_num.set_bit( m_idx, high ); +} + + +// print or dump content + +void +sc_fxnum_fast_bitref::print( ::std::ostream& os ) const +{ + os << get(); +} + +void +sc_fxnum_fast_bitref::scan( ::std::istream& is ) +{ + bool b; + is >> b; + *this = b; +} + +void +sc_fxnum_fast_bitref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast_bitref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "idx = " << m_idx << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_subref::get() const +{ + return m_num.get_slice( m_from, m_to, m_bv ); +} + +bool +sc_fxnum_subref::set() +{ + return m_num.set_slice( m_from, m_to, m_bv ); +} + + +// print or dump content + +void +sc_fxnum_subref::print( ::std::ostream& os ) const +{ + get(); + m_bv.print( os ); +} + +void +sc_fxnum_subref::scan( ::std::istream& is ) +{ + m_bv.scan( is ); + set(); +} + +void +sc_fxnum_subref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_subref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "from = " << m_from << ::std::endl; + os << "to = " << m_to << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +bool +sc_fxnum_fast_subref::get() const +{ + return m_num.get_slice( m_from, m_to, m_bv ); +} + +bool +sc_fxnum_fast_subref::set() +{ + return m_num.set_slice( m_from, m_to, m_bv ); +} + + +// print or dump content + +void +sc_fxnum_fast_subref::print( ::std::ostream& os ) const +{ + get(); + m_bv.print( os ); +} + +void +sc_fxnum_fast_subref::scan( ::std::istream& is ) +{ + m_bv.scan( is ); + set(); +} + +void +sc_fxnum_fast_subref::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast_subref" << ::std::endl; + os << "(" << ::std::endl; + os << "num = "; + m_num.dump( os ); + os << "from = " << m_from << ::std::endl; + os << "to = " << m_to << ::std::endl; + os << ")" << ::std::endl; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +// explicit conversion to character string + +const std::string +sc_fxnum::to_string() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep ) const +{ + return std::string( m_rep->to_string( numrep, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), + SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( SC_DEC, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), + fmt, &m_params ) ); +} + + +const std::string +sc_fxnum::to_dec() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_bin() const +{ + return std::string( m_rep->to_string( SC_BIN, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_oct() const +{ + return std::string( m_rep->to_string( SC_OCT, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum::to_hex() const +{ + return std::string( m_rep->to_string( SC_HEX, -1, SC_F, &m_params ) ); +} + + +// print or dump content + +void +sc_fxnum::print( ::std::ostream& os ) const +{ + os << m_rep->to_string( SC_DEC, -1, SC_F, &m_params ); +} + +void +sc_fxnum::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxnum::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum" << ::std::endl; + os << "(" << ::std::endl; + os << "rep = "; + m_rep->dump( os ); + os << "params = "; + m_params.dump( os ); + os << "q_flag = " << m_q_flag << ::std::endl; + os << "o_flag = " << m_o_flag << ::std::endl; + // TO BE COMPLETED + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +sc_fxnum_observer* +sc_fxnum::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxnum_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxnum::unlock_observer( sc_fxnum_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +static +void +quantization( double& c, const scfx_params& params, bool& q_flag ) +{ + int fwl = params.wl() - params.iwl(); + double scale = scfx_pow2( fwl ); + double val = scale * c; + double int_part; + double frac_part = modf( val, &int_part ); + + q_flag = ( frac_part != 0.0 ); + + if( q_flag ) + { + val = int_part; + + switch( params.q_mode() ) + { + case SC_TRN: // truncation + { + if( c < 0.0 ) + val -= 1.0; + break; + } + case SC_RND: // rounding to plus infinity + { + if( frac_part >= 0.5 ) + val += 1.0; + else if( frac_part < -0.5 ) + val -= 1.0; + break; + } + case SC_TRN_ZERO: // truncation to zero + { + break; + } + case SC_RND_INF: // rounding to infinity + { + if( frac_part >= 0.5 ) + val += 1.0; + else if( frac_part <= -0.5 ) + val -= 1.0; + break; + } + case SC_RND_CONV: // convergent rounding + { + if( frac_part > 0.5 || + ( frac_part == 0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) + val += 1.0; + else if( frac_part < -0.5 || + ( frac_part == -0.5 && fmod( int_part, 2.0 ) != 0.0 ) ) + val -= 1.0; + break; + } + case SC_RND_ZERO: // rounding to zero + { + if( frac_part > 0.5 ) + val += 1.0; + else if( frac_part < -0.5 ) + val -= 1.0; + break; + } + case SC_RND_MIN_INF: // rounding to minus infinity + { + if( frac_part > 0.5 ) + val += 1.0; + else if( frac_part <= -0.5 ) + val -= 1.0; + break; + } + default: + ; + } + } + + val /= scale; + c = val; +} + +static +void +overflow( double& c, const scfx_params& params, bool& o_flag ) +{ + int iwl = params.iwl(); + int fwl = params.wl() - iwl; + double full_circle = scfx_pow2( iwl ); + double resolution = scfx_pow2( -fwl ); + double low, high; + if( params.enc() == SC_TC_ ) + { + high = full_circle / 2.0 - resolution; + if( params.o_mode() == SC_SAT_SYM ) + low = - high; + else + low = - full_circle / 2.0; + } + else + { + low = 0.0; + high = full_circle - resolution; + } + double val = c; + sc_fxval_fast c2(c); + + bool under = ( val < low ); + bool over = ( val > high ); + + o_flag = ( under || over ); + + if( o_flag ) + { + switch( params.o_mode() ) + { + case SC_WRAP: // wrap-around + { + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits < params.wl() ) + { + double X = scfx_pow2( iwl - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits + val -= floor( val / X ) * X; + if( val > ( X - resolution ) ) + val -= X; + + // saturate most significant 'n_bits' bits + if( under ) + val += low; + else + { + if( params.enc() == SC_TC_ ) + val += full_circle / 2.0 - X; + else + val += full_circle - X; + } + } + else + { + // saturate all 'wl' bits + if( under ) + val = low; + else + val = high; + } + break; + } + case SC_SAT: // saturation + case SC_SAT_SYM: // symmetrical saturation + { + if( under ) + val = low; + else + val = high; + break; + } + case SC_SAT_ZERO: // saturation to zero + { + val = 0.0; + break; + } + case SC_WRAP_SM: // sign magnitude wrap-around + { + SC_ERROR_IF_( params.enc() == SC_US_, + sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); + + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // invert conditionally + if( c2.get_bit( iwl ) != c2.get_bit( iwl - 1 ) ) + val = -val - resolution; + + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits == 1 ) + { + // invert conditionally + if( c2.is_neg() != c2.get_bit( iwl - 1 ) ) + val = -val - resolution; + + // wrap-around all 'wl' bits + val -= floor( val / full_circle ) * full_circle; + if( val > high ) + val -= full_circle; + } + else if( n_bits < params.wl() ) + { + // invert conditionally + if( c2.is_neg() == c2.get_bit( iwl - n_bits ) ) + val = -val - resolution; + + double X = scfx_pow2( iwl - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits + val -= floor( val / X ) * X; + if( val > ( X - resolution ) ) + val -= X; + + // saturate most significant 'n_bits' bits + if( under ) + val += low; + else + val += full_circle / 2.0 - X; + } else { + // saturate all 'wl' bits + if( under ) + val = low; + else + val = high; + } + break; + } + default: + ; + } + + c = val; + } +} + + +void +sc_fxnum_fast::cast() +{ + scfx_ieee_double id( m_val ); + SC_ERROR_IF_( id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_); + + if( m_params.cast_switch() == SC_ON ) + { + m_q_flag = false; + m_o_flag = false; + + // check for special cases + + if( id.is_zero() ) + { + if( id.negative() != 0 ) + m_val = -m_val; + return; + } + + // perform casting + + sc_dt::quantization( m_val, m_params, m_q_flag ); + sc_dt::overflow( m_val, m_params, m_o_flag ); + + // check for special case: -0 + + id = m_val; + if( id.is_zero() && id.negative() != 0 ) { + m_val = -m_val; + } + + // check for special case: NaN of Inf + + if( id.is_nan() || id.is_inf() ) { + m_val = 0.0; + } + } +} + + +// defined in sc_fxval.cpp; +extern +const char* +to_string( const scfx_ieee_double&, + sc_numrep, + int, + sc_fmt, + const scfx_params* = 0 ); + + +// explicit conversion to character string + +const std::string +sc_fxnum_fast::to_string() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, fmt, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + fmt, &m_params ) ); +} + + +const std::string +sc_fxnum_fast::to_dec() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_bin() const +{ + return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_oct() const +{ + return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_F, &m_params ) ); +} + +const std::string +sc_fxnum_fast::to_hex() const +{ + return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_F, &m_params ) ); +} + + +// print or dump content + +void +sc_fxnum_fast::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_val, SC_DEC, -1, SC_F, &m_params ); +} + +void +sc_fxnum_fast::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxnum_fast::dump( ::std::ostream& os ) const +{ + os << "sc_fxnum_fast" << ::std::endl; + os << "(" << ::std::endl; + os << "val = " << m_val << ::std::endl; + os << "params = "; + m_params.dump( os ); + os << "q_flag = " << m_q_flag << ::std::endl; + os << "o_flag = " << m_o_flag << ::std::endl; + // TO BE COMPLETED + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// internal use only; +bool +sc_fxnum_fast::get_bit( int i ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_zero() || id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the right bit + + int j = i - id.exponent(); + if( ( j += 20 ) >= 32 ) + return ( ( m0 & 1U << 31 ) != 0 ); + else if( j >= 0 ) + return ( ( m0 & 1U << j ) != 0 ); + else if( ( j += 32 ) >= 0 ) + return ( ( m1 & 1U << j ) != 0 ); + else + return false; +} + + +bool +sc_fxnum_fast::set_bit( int i, bool high ) +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + if( high ) + { + if( get_bit( i ) ) + return true; + + if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) + m_val -= scfx_pow2( i ); + else + m_val += scfx_pow2( i ); + } + else + { + if( ! get_bit( i ) ) + return true; + + if( m_params.enc() == SC_TC_ && i == m_params.iwl() - 1 ) + m_val += scfx_pow2( i ); + else + m_val -= scfx_pow2( i ); + } + + return true; +} + + +bool +sc_fxnum_fast::get_slice( int i, int j, sc_bv_base& bv ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + bool b = false; + + int n = l - id.exponent(); + if( ( n += 20 ) >= 32 ) + b = ( ( m0 & 1U << 31 ) != 0 ); + else if( n >= 0 ) + b = ( ( m0 & 1U << n ) != 0 ); + else if( ( n += 32 ) >= 0 ) + b = ( ( m1 & 1U << n ) != 0 ); + + bv[k] = b; + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + +bool +sc_fxnum_fast::set_slice( int i, int j, const sc_bv_base& bv ) +{ + scfx_ieee_double id( m_val ); + if( id.is_nan() || id.is_inf() ) + return false; + + // set the bits + + int l = j; + for( int k = 0; k < bv.length(); ++ k ) + { + if( bv[k].to_bool() ) + { + if( ! get_bit( l ) ) + { + if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) + m_val -= scfx_pow2( l ); + else + m_val += scfx_pow2( l ); + } + } + else + { + if( get_bit( l ) ) + { + if( m_params.enc() == SC_TC_ && l == m_params.iwl() - 1 ) + m_val += scfx_pow2( l ); + else + m_val -= scfx_pow2( l ); + } + } + + + if( i >= j ) + ++ l; + else + -- l; + } + + return true; +} + + +sc_fxnum_fast_observer* +sc_fxnum_fast::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxnum_fast_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxnum_fast::unlock_observer( sc_fxnum_fast_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h new file mode 100644 index 000000000..ed3750811 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum.h @@ -0,0 +1,5102 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum.h - + + Original Author: 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: sc_fxnum.h,v $ +// Revision 1.5 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.4 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2009/03/09 17:26:46 acg +// Andy Goodrich: removed ; from namespace { } +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXNUM_H +#define SC_FXNUM_H + + +#include "sysc/datatypes/bit/sc_lv_base.h" +#include "sysc/datatypes/fx/sc_fxval.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/sc_fxnum_observer.h" + + +namespace sc_core { + class vcd_sc_fxnum_trace; + class vcd_sc_fxnum_fast_trace; + class wif_sc_fxnum_trace; + class wif_sc_fxnum_fast_trace; +} + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxnum_bitref; +class sc_fxnum_fast_bitref; +class sc_fxnum_subref; +class sc_fxnum_fast_subref; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +class sc_fxnum_bitref +{ + friend class sc_fxnum; + friend class sc_fxnum_fast_bitref; + + + bool get() const; + void set( bool ); + + + // constructor + + sc_fxnum_bitref( sc_fxnum&, int ); + +public: + + // copy constructor + + sc_fxnum_bitref( const sc_fxnum_bitref& ); + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_bitref& operator op ( tp ); + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \ + DECL_ASN_OP_T(op,const sc_bit&) \ + DECL_ASN_OP_T(op,bool) + + DECL_ASN_OP(=) + + DECL_ASN_OP(&=) + DECL_ASN_OP(|=) + DECL_ASN_OP(^=) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP + + + // implicit conversion + + operator bool() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum& m_num; + int m_idx; + +private: + + // disabled + sc_fxnum_bitref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_bitref +{ + friend class sc_fxnum_fast; + friend class sc_fxnum_bitref; + + + bool get() const; + void set( bool ); + + + // constructor + + sc_fxnum_fast_bitref( sc_fxnum_fast&, int ); + +public: + + // copy constructor + + sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& ); + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_fast_bitref& operator op ( tp ); + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,const sc_fxnum_bitref&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast_bitref&) \ + DECL_ASN_OP_T(op,const sc_bit&) \ + DECL_ASN_OP_T(op,bool) + + DECL_ASN_OP(=) + + DECL_ASN_OP(&=) + DECL_ASN_OP(|=) + DECL_ASN_OP(^=) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP + + + // implicit conversion + + operator bool() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum_fast& m_num; + int m_idx; + +private: + + // disabled + sc_fxnum_fast_bitref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +class sc_fxnum_subref +{ + friend class sc_fxnum; + friend class sc_fxnum_fast_subref; + + bool get() const; + bool set(); + + + // constructor + + sc_fxnum_subref( sc_fxnum&, int, int ); + +public: + + // copy constructor + + sc_fxnum_subref( const sc_fxnum_subref& ); + + + // destructor + + ~sc_fxnum_subref(); + + + // assignment operators + +#define DECL_ASN_OP_T(tp) \ + sc_fxnum_subref& operator = ( tp ); + + DECL_ASN_OP_T(const sc_fxnum_subref&) + DECL_ASN_OP_T(const sc_fxnum_fast_subref&) + DECL_ASN_OP_T(const sc_bv_base&) + DECL_ASN_OP_T(const sc_lv_base&) + DECL_ASN_OP_T(const char*) + DECL_ASN_OP_T(const bool*) + DECL_ASN_OP_T(const sc_signed&) + DECL_ASN_OP_T(const sc_unsigned&) + DECL_ASN_OP_T(const sc_int_base&) + DECL_ASN_OP_T(const sc_uint_base&) + DECL_ASN_OP_T(int64) + DECL_ASN_OP_T(uint64) + DECL_ASN_OP_T(int) + DECL_ASN_OP_T(unsigned int) + DECL_ASN_OP_T(long) + DECL_ASN_OP_T(unsigned long) + DECL_ASN_OP_T(char) + +#undef DECL_ASN_OP_T + +#define DECL_ASN_OP_T_A(op,tp) \ + sc_fxnum_subref& operator op ## = ( tp ); + +#define DECL_ASN_OP_A(op) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \ + DECL_ASN_OP_T_A(op,const sc_bv_base&) \ + DECL_ASN_OP_T_A(op,const sc_lv_base&) + + DECL_ASN_OP_A(&) + DECL_ASN_OP_A(|) + DECL_ASN_OP_A(^) + +#undef DECL_ASN_OP_T_A +#undef DECL_ASN_OP_A + + + // relational operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_subref&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_subref& ); + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_subref&, \ + const sc_fxnum_subref& ); \ + friend bool operator op ( const sc_fxnum_subref&, \ + const sc_fxnum_fast_subref& ); \ + DECL_REL_OP_T(op,const sc_bv_base&) \ + DECL_REL_OP_T(op,const sc_lv_base&) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const bool*) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) + + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP + + + // reduce functions + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const; + bool xnor_reduce() const; + + + // query parameter + + int length() const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const; + unsigned int to_unsigned() const; +#endif + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + + + // implicit conversion + + operator sc_bv_base() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum& m_num; + int m_from; + int m_to; + + sc_bv_base& m_bv; + +private: + + // disabled + sc_fxnum_subref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_subref +{ + friend class sc_fxnum_fast; + friend class sc_fxnum_subref; + + bool get() const; + bool set(); + + + // constructor + + sc_fxnum_fast_subref( sc_fxnum_fast&, int, int ); + +public: + + // copy constructor + + sc_fxnum_fast_subref( const sc_fxnum_fast_subref& ); + + + // destructor + + ~sc_fxnum_fast_subref(); + + + // assignment operators + +#define DECL_ASN_OP_T(tp) \ + sc_fxnum_fast_subref& operator = ( tp ); + + DECL_ASN_OP_T(const sc_fxnum_subref&) + DECL_ASN_OP_T(const sc_fxnum_fast_subref&) + DECL_ASN_OP_T(const sc_bv_base&) + DECL_ASN_OP_T(const sc_lv_base&) + DECL_ASN_OP_T(const char*) + DECL_ASN_OP_T(const bool*) + DECL_ASN_OP_T(const sc_signed&) + DECL_ASN_OP_T(const sc_unsigned&) + DECL_ASN_OP_T(const sc_int_base&) + DECL_ASN_OP_T(const sc_uint_base&) + DECL_ASN_OP_T(int64) + DECL_ASN_OP_T(uint64) + DECL_ASN_OP_T(int) + DECL_ASN_OP_T(unsigned int) + DECL_ASN_OP_T(long) + DECL_ASN_OP_T(unsigned long) + DECL_ASN_OP_T(char) + +#undef DECL_ASN_OP_T + +#define DECL_ASN_OP_T_A(op,tp) \ + sc_fxnum_fast_subref& operator op ## = ( tp ); + +#define DECL_ASN_OP_A(op) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_subref&) \ + DECL_ASN_OP_T_A(op,const sc_fxnum_fast_subref&) \ + DECL_ASN_OP_T_A(op,const sc_bv_base&) \ + DECL_ASN_OP_T_A(op,const sc_lv_base&) + + DECL_ASN_OP_A(&) + DECL_ASN_OP_A(|) + DECL_ASN_OP_A(^) + +#undef DECL_ASN_OP_T_A +#undef DECL_ASN_OP_A + + + // relational operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_fast_subref&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_fast_subref& ); + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_fast_subref&, \ + const sc_fxnum_fast_subref& ); \ + friend bool operator op ( const sc_fxnum_fast_subref&, \ + const sc_fxnum_subref& ); \ + DECL_REL_OP_T(op,const sc_bv_base&) \ + DECL_REL_OP_T(op,const sc_lv_base&) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const bool*) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) + + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP + + + // reduce functions + + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const; + bool xnor_reduce() const; + + + // query parameter + + int length() const; + + + // explicit conversions + + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + +#ifdef SC_DT_DEPRECATED + int to_signed() const; + unsigned int to_unsigned() const; +#endif + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + + + // implicit conversion + + operator sc_bv_base() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + sc_fxnum_fast& m_num; + int m_from; + int m_to; + + sc_bv_base& m_bv; + +private: + + // disabled + sc_fxnum_fast_subref(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum +{ + friend class sc_fxval; + + friend class sc_fxnum_bitref; + friend class sc_fxnum_subref; + friend class sc_fxnum_fast_bitref; + friend class sc_fxnum_fast_subref; + + friend class sc_core::vcd_sc_fxnum_trace; + friend class sc_core::wif_sc_fxnum_trace; + +protected: + + sc_fxnum_observer* observer() const; + + + void cast(); + + + // constructors + + sc_fxnum( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch&, + sc_fxnum_observer* ); + +#define DECL_CTOR_T(tp) \ + sc_fxnum( tp, \ + const sc_fxtype_params&, \ + sc_enc, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* ); + + DECL_CTOR_T(int) + DECL_CTOR_T(unsigned int) + DECL_CTOR_T(long) + DECL_CTOR_T(unsigned long) + DECL_CTOR_T(float) + DECL_CTOR_T(double) + DECL_CTOR_T(const char*) + DECL_CTOR_T(const sc_fxval&) + DECL_CTOR_T(const sc_fxval_fast&) + DECL_CTOR_T(const sc_fxnum&) + DECL_CTOR_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTOR_T(int64) + DECL_CTOR_T(uint64) + DECL_CTOR_T(const sc_int_base&) + DECL_CTOR_T(const sc_uint_base&) + DECL_CTOR_T(const sc_signed&) + DECL_CTOR_T(const sc_unsigned&) +#endif + +#undef DECL_CTOR_T + + ~sc_fxnum(); + + + // internal use only; + const scfx_rep* get_rep() const; + +public: + + // unary operators + + const sc_fxval operator - () const; + const sc_fxval operator + () const; + + + // unary functions + + friend void neg( sc_fxval&, const sc_fxnum& ); + friend void neg( sc_fxnum&, const sc_fxnum& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval operator op ( const sc_fxnum&, tp ); \ + friend const sc_fxval operator op ( tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval operator op ( const sc_fxnum&, const sc_fxnum& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval&) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_T(op,const sc_fxnum_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// don't use macros +// DECL_BIN_OP(/,div) + friend const sc_fxval operator / ( const sc_fxnum&, const sc_fxnum& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval&) + DECL_BIN_OP_T(/,const sc_fxval_fast&) + DECL_BIN_OP_T(/,const sc_fxnum_fast&) +// DECL_BIN_OP_OTHER(op) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) + DECL_BIN_OP_T(/,uint64) + DECL_BIN_OP_T(/,const sc_int_base&) + DECL_BIN_OP_T(/,const sc_uint_base&) + DECL_BIN_OP_T(/,const sc_signed&) + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval operator << ( const sc_fxnum&, int ); + friend const sc_fxval operator >> ( const sc_fxnum&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval&, const sc_fxnum&, tp ); \ + friend void fnc ( sc_fxval&, tp, const sc_fxnum& ); \ + friend void fnc ( sc_fxnum&, const sc_fxnum&, tp ); \ + friend void fnc ( sc_fxnum&, tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval&, const sc_fxnum&, const sc_fxnum& ); \ + friend void fnc ( sc_fxnum&, const sc_fxnum&, const sc_fxnum& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval&, const sc_fxnum&, int ); + friend void rshift( sc_fxval&, const sc_fxnum&, int ); + friend void lshift( sc_fxnum&, const sc_fxnum&, int ); + friend void rshift( sc_fxnum&, const sc_fxnum&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum&, tp ); \ + friend bool operator op ( tp, const sc_fxnum& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum&, const sc_fxnum& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval&) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_T(op,const sc_fxnum_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fxnum& operator ++ (); + sc_fxnum& operator -- (); + + + // bit selection + + const sc_fxnum_bitref operator [] ( int ) const; + sc_fxnum_bitref operator [] ( int ); + + const sc_fxnum_bitref bit( int ) const; + sc_fxnum_bitref bit( int ); + + + // part selection + + const sc_fxnum_subref operator () ( int, int ) const; + sc_fxnum_subref operator () ( int, int ); + + const sc_fxnum_subref range( int, int ) const; + sc_fxnum_subref range( int, int ); + + + const sc_fxnum_subref operator () () const; + sc_fxnum_subref operator () (); + + const sc_fxnum_subref range() const; + sc_fxnum_subref range(); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + + // internal use only; + bool is_normal() const; + + bool quantization_flag() const; + bool overflow_flag() const; + + const sc_fxval value() const; + + + // query parameters + + int wl() const; + int iwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + const sc_fxtype_params& type_params() const; + + const sc_fxcast_switch& cast_switch() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + void observer_read() const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + bool set_bit( int, bool ); + + + bool get_slice( int, int, sc_bv_base& ) const; + bool set_slice( int, int, const sc_bv_base& ); + + + sc_fxnum_observer* lock_observer() const; + void unlock_observer( sc_fxnum_observer* ) const; + +private: + + scfx_rep* m_rep; + + scfx_params m_params; + bool m_q_flag; + bool m_o_flag; + + mutable sc_fxnum_observer* m_observer; + +private: + + // disabled + sc_fxnum(); + sc_fxnum( const sc_fxnum& ); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast +{ + friend class sc_fxval_fast; + + friend class sc_fxnum_bitref; + friend class sc_fxnum_subref; + friend class sc_fxnum_fast_bitref; + friend class sc_fxnum_fast_subref; + + friend class sc_core::vcd_sc_fxnum_fast_trace; + friend class sc_core::wif_sc_fxnum_fast_trace; + +protected: + + sc_fxnum_fast_observer* observer() const; + + + void cast(); + + + // constructors + + sc_fxnum_fast( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* ); + +#define DECL_CTOR_T(tp) \ + sc_fxnum_fast( tp, \ + const sc_fxtype_params&, \ + sc_enc, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* ); + + DECL_CTOR_T(int) + DECL_CTOR_T(unsigned int) + DECL_CTOR_T(long) + DECL_CTOR_T(unsigned long) + DECL_CTOR_T(float) + DECL_CTOR_T(double) + DECL_CTOR_T(const char*) + DECL_CTOR_T(const sc_fxval&) + DECL_CTOR_T(const sc_fxval_fast&) + DECL_CTOR_T(const sc_fxnum&) + DECL_CTOR_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTOR_T(int64) + DECL_CTOR_T(uint64) + DECL_CTOR_T(const sc_int_base&) + DECL_CTOR_T(const sc_uint_base&) + DECL_CTOR_T(const sc_signed&) + DECL_CTOR_T(const sc_unsigned&) +#endif + +#undef DECL_CTOR_T + + ~sc_fxnum_fast(); + + + // internal use only; + double get_val() const; + +public: + + // unary operators + + const sc_fxval_fast operator - () const; + const sc_fxval_fast operator + () const; + + + // unary functions + + friend void neg( sc_fxval_fast&, const sc_fxnum_fast& ); + friend void neg( sc_fxnum_fast&, const sc_fxnum_fast& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, tp ); \ + friend const sc_fxval_fast operator op ( tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval_fast operator op ( const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// DECL_BIN_OP(/,div) + friend const sc_fxval_fast operator / ( const sc_fxnum_fast&, + const sc_fxnum_fast& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval_fast&) +// DECL_BIN_OP_OTHER(op) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval_fast operator << ( const sc_fxnum_fast&, int ); + friend const sc_fxval_fast operator >> ( const sc_fxnum_fast&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, tp ); \ + friend void fnc ( sc_fxval_fast&, tp, const sc_fxnum_fast& ); \ + friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, tp ); \ + friend void fnc ( sc_fxnum_fast&, tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval_fast&, const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + friend void fnc ( sc_fxnum_fast&, const sc_fxnum_fast&, \ + const sc_fxnum_fast& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval_fast&, const sc_fxnum_fast&, int ); + friend void rshift( sc_fxval_fast&, const sc_fxnum_fast&, int ); + friend void lshift( sc_fxnum_fast&, const sc_fxnum_fast&, int ); + friend void rshift( sc_fxnum_fast&, const sc_fxnum_fast&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxnum_fast&, tp ); \ + friend bool operator op ( tp, const sc_fxnum_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxnum_fast&, const sc_fxnum_fast& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxnum_fast& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fxnum_fast& operator ++ (); + sc_fxnum_fast& operator -- (); + + + // bit selection + + const sc_fxnum_fast_bitref operator [] ( int ) const; + sc_fxnum_fast_bitref operator [] ( int ); + + const sc_fxnum_fast_bitref bit( int ) const; + sc_fxnum_fast_bitref bit( int ); + + + // part selection + + const sc_fxnum_fast_subref operator () ( int, int ) const; + sc_fxnum_fast_subref operator () ( int, int ); + + const sc_fxnum_fast_subref range( int, int ) const; + sc_fxnum_fast_subref range( int, int ); + + + const sc_fxnum_fast_subref operator () () const; + sc_fxnum_fast_subref operator () (); + + const sc_fxnum_fast_subref range() const; + sc_fxnum_fast_subref range(); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + + // internal use only; + bool is_normal() const; + + bool quantization_flag() const; + bool overflow_flag() const; + + const sc_fxval_fast value() const; + + + // query parameters + + int wl() const; + int iwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + const sc_fxtype_params& type_params() const; + + const sc_fxcast_switch& cast_switch() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + void observer_read() const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + bool set_bit( int, bool ); + + + bool get_slice( int, int, sc_bv_base& ) const; + bool set_slice( int, int, const sc_bv_base& ); + + + sc_fxnum_fast_observer* lock_observer() const; + void unlock_observer( sc_fxnum_fast_observer* ) const; + +private: + + double m_val; + + scfx_params m_params; + bool m_q_flag; + bool m_o_flag; + + mutable sc_fxnum_fast_observer* m_observer; + +private: + + // disabled + sc_fxnum_fast(); + sc_fxnum_fast( const sc_fxnum_fast& ); +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_bitref +// +// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_bitref::sc_fxnum_bitref( sc_fxnum& num_, int idx_ ) + : m_num( num_ ), m_idx( idx_ ) +{} + + +// copy constructor + +inline +sc_fxnum_bitref::sc_fxnum_bitref( const sc_fxnum_bitref& a ) + : m_num( a.m_num ), m_idx( a.m_idx ) +{} + + +// assignment operators + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_fxnum_bitref& a ) +{ + if( &a != this ) + { + SC_FXNUM_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_fxnum_fast_bitref& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( const sc_bit& a ) +{ + set( static_cast<bool>( a ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator = ( bool a ) +{ + set( a ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() && static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator &= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() && b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() || static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator |= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() || b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( const sc_bit& b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() != static_cast<bool>( b ) ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_bitref& +sc_fxnum_bitref::operator ^= ( bool b ) +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + set( get() != b ); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + + +// implicit conversion + +inline +sc_fxnum_bitref::operator bool() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + return get(); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_bitref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_bitref +// +// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( sc_fxnum_fast& num_, int idx_ ) + : m_num( num_ ), m_idx( idx_ ) +{} + + +// copy constructor + +inline +sc_fxnum_fast_bitref::sc_fxnum_fast_bitref( const sc_fxnum_fast_bitref& a ) + : m_num( a.m_num ), m_idx( a.m_idx ) +{} + + +// assignment operators + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_fxnum_bitref& a ) +{ + SC_FXNUM_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_fxnum_fast_bitref& a ) +{ + if( &a != this ) + { + SC_FXNUM_FAST_OBSERVER_READ_( a.m_num ) + set( a.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( const sc_bit& a ) +{ + set( static_cast<bool>( a ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator = ( bool a ) +{ + set( a ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() && b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() && static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator &= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() && b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() || b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() || static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator |= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() || b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_fxnum_fast_bitref& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + SC_FXNUM_FAST_OBSERVER_READ_( b.m_num ) + set( get() != b.get() ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( const sc_bit& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() != static_cast<bool>( b ) ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_bitref& +sc_fxnum_fast_bitref::operator ^= ( bool b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + set( get() != b ); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + + +// implicit conversion + +inline +sc_fxnum_fast_bitref::operator bool() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + return get(); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast_bitref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast_bitref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_subref +// +// Proxy class for part-selection in class sc_fxnum, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_subref::sc_fxnum_subref( sc_fxnum& num_, int from_, int to_ ) + : m_num( num_ ), m_from( from_ ), m_to( to_ ), + m_bv( *new sc_bv_base( sc_max( m_from, m_to ) - + sc_min( m_from, m_to ) + 1 ) ) +{} + + +// copy constructor + +inline +sc_fxnum_subref::sc_fxnum_subref( const sc_fxnum_subref& a ) + : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ), + m_bv( *new sc_bv_base( a.m_bv ) ) +{} + + +// destructor + +inline +sc_fxnum_subref::~sc_fxnum_subref() +{ + delete &m_bv; +} + + +// assignment operators + +inline +sc_fxnum_subref& +sc_fxnum_subref::operator = ( const sc_fxnum_subref& a ) +{ + if( &a != this ) + { + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +inline +sc_fxnum_subref& +sc_fxnum_subref::operator = ( const sc_fxnum_fast_subref& a ) +{ + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_OBSERVER_WRITE_( m_num ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator = ( tp a ) \ +{ \ + m_bv = a; \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_bv_base&) +DEFN_ASN_OP_T(const sc_lv_base&) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const bool*) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(char) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( tp a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op a; \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( const sc_fxnum_subref& a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_subref& \ +sc_fxnum_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_bv_base&) \ +DEFN_ASN_OP_T(op,const sc_lv_base&) + +DEFN_ASN_OP(&) +DEFN_ASN_OP(|) +DEFN_ASN_OP(^) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// relational operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, tp b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op b ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( b ) op a ); \ +} + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_subref& a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +DEFN_REL_OP_T(op,const sc_bv_base&) \ +DEFN_REL_OP_T(op,const sc_lv_base&) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_T(op,const bool*) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) + +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// reduce functions + +#define DEFN_RED_FNC(fnc) \ +inline \ +bool \ +sc_fxnum_subref::fnc() const \ +{ \ + SC_FXNUM_OBSERVER_READ_( m_num ) \ + get(); \ + return static_cast<bool>( m_bv.fnc() ); \ +} + +DEFN_RED_FNC(and_reduce) +DEFN_RED_FNC(nand_reduce) +DEFN_RED_FNC(or_reduce) +DEFN_RED_FNC(nor_reduce) +DEFN_RED_FNC(xor_reduce) +DEFN_RED_FNC(xnor_reduce) + +#undef DEFN_RED_FNC + + +// query parameter + +inline +int +sc_fxnum_subref::length() const +{ + return m_bv.length(); +} + + +// explicit conversions + +inline +int +sc_fxnum_subref::to_int() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int(); +} + +inline +int64 +sc_fxnum_subref::to_int64() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int64(); +} + +inline +unsigned int +sc_fxnum_subref::to_uint() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint(); +} + +inline +uint64 +sc_fxnum_subref::to_uint64() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint64(); +} + +inline +long +sc_fxnum_subref::to_long() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_long(); +} + +inline +unsigned long +sc_fxnum_subref::to_ulong() const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_ulong(); +} + + +#ifdef SC_DT_DEPRECATED + +inline +int +sc_fxnum_subref::to_signed() const +{ + return to_int(); +} + +inline +unsigned int +sc_fxnum_subref::to_unsigned() const +{ + return to_uint(); +} + +#endif + + +inline +const std::string +sc_fxnum_subref::to_string() const +{ + get(); + return m_bv.to_string(); +} + +inline +const std::string +sc_fxnum_subref::to_string( sc_numrep numrep ) const +{ + get(); + return m_bv.to_string( numrep ); +} + +inline +const std::string +sc_fxnum_subref::to_string( sc_numrep numrep, bool w_prefix ) const +{ + get(); + return m_bv.to_string( numrep, w_prefix ); +} + + +// implicit conversion + +inline +sc_fxnum_subref::operator sc_bv_base () const +{ + SC_FXNUM_OBSERVER_READ_( m_num ) + get(); + return m_bv; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_subref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_subref +// +// Proxy class for part-selection in class sc_fxnum_fast, +// behaves like sc_bv_base. +// ---------------------------------------------------------------------------- + +// constructor + +inline +sc_fxnum_fast_subref::sc_fxnum_fast_subref( sc_fxnum_fast& num_, + int from_, int to_ ) + : m_num( num_ ), m_from( from_ ), m_to( to_ ), + m_bv( *new sc_bv_base( sc_max( m_from, m_to ) - + sc_min( m_from, m_to ) + 1 ) ) +{} + + +// copy constructor + +inline +sc_fxnum_fast_subref::sc_fxnum_fast_subref( const sc_fxnum_fast_subref& a ) + : m_num( a.m_num ), m_from( a.m_from ), m_to( a.m_to ), + m_bv( *new sc_bv_base( a.m_bv ) ) +{} + + +// destructor + +inline +sc_fxnum_fast_subref::~sc_fxnum_fast_subref() +{ + delete &m_bv; +} + + +// assignment operators + +inline +sc_fxnum_fast_subref& +sc_fxnum_fast_subref::operator = ( const sc_fxnum_subref& a ) +{ + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + return *this; +} + +inline +sc_fxnum_fast_subref& +sc_fxnum_fast_subref::operator = ( const sc_fxnum_fast_subref& a ) +{ + if( &a != this ) + { + m_bv = static_cast<sc_bv_base>( a ); + set(); + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator = ( tp a ) \ +{ \ + m_bv = a; \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_bv_base&) +DEFN_ASN_OP_T(const sc_lv_base&) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const bool*) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(char) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( tp a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op a; \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_subref& a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_fast_subref& \ +sc_fxnum_fast_subref::operator op ## = ( const sc_fxnum_fast_subref& a ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + m_bv = m_bv op static_cast<sc_bv_base>( a ); \ + set(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( m_num ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_bv_base&) \ +DEFN_ASN_OP_T(op,const sc_lv_base&) + +DEFN_ASN_OP(&) +DEFN_ASN_OP(|) +DEFN_ASN_OP(^) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// relational operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, tp b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op b ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( b ) op a ); \ +} + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_fast_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_fast_subref& a, const sc_fxnum_subref& b ) \ +{ \ + return ( static_cast<sc_bv_base>( a ) op static_cast<sc_bv_base>( b ) ); \ +} \ + \ +DEFN_REL_OP_T(op,const sc_bv_base&) \ +DEFN_REL_OP_T(op,const sc_lv_base&) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_T(op,const bool*) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) + +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// reduce functions + +#define DEFN_RED_FNC(fnc) \ +inline \ +bool \ +sc_fxnum_fast_subref::fnc() const \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) \ + get(); \ + return static_cast<bool>( m_bv.fnc() ); \ +} + +DEFN_RED_FNC(and_reduce) +DEFN_RED_FNC(nand_reduce) +DEFN_RED_FNC(or_reduce) +DEFN_RED_FNC(nor_reduce) +DEFN_RED_FNC(xor_reduce) +DEFN_RED_FNC(xnor_reduce) + +#undef DEFN_RED_FNC + + +// query parameter + +inline +int +sc_fxnum_fast_subref::length() const +{ + return m_bv.length(); +} + + +// explicit conversions + +inline +int +sc_fxnum_fast_subref::to_int() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int(); +} + +inline +int64 +sc_fxnum_fast_subref::to_int64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_int64(); +} + +inline +unsigned int +sc_fxnum_fast_subref::to_uint() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint(); +} + +inline +uint64 +sc_fxnum_fast_subref::to_uint64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_uint64(); +} + +inline +long +sc_fxnum_fast_subref::to_long() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_long(); +} + +inline +unsigned long +sc_fxnum_fast_subref::to_ulong() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv.to_ulong(); +} + + +#ifdef SC_DT_DEPRECATED + +inline +int +sc_fxnum_fast_subref::to_signed() const +{ + return to_int(); +} + +inline +unsigned int +sc_fxnum_fast_subref::to_unsigned() const +{ + return to_uint(); +} + +#endif + + +inline +const std::string +sc_fxnum_fast_subref::to_string() const +{ + get(); + return m_bv.to_string(); +} + +inline +const std::string +sc_fxnum_fast_subref::to_string( sc_numrep numrep ) const +{ + get(); + return m_bv.to_string( numrep ); +} + +inline +const std::string +sc_fxnum_fast_subref::to_string( sc_numrep numrep, bool w_prefix ) const +{ + get(); + return m_bv.to_string( numrep, w_prefix ); +} + + +// implicit conversion + +inline +sc_fxnum_fast_subref::operator sc_bv_base () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( m_num ) + get(); + return m_bv; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast_subref& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast_subref& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum +// +// Base class for the fixed-point types; arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +sc_fxnum_observer* +sc_fxnum::observer() const +{ + return m_observer; +} + + +inline +void +sc_fxnum::cast() +{ + SC_ERROR_IF_( ! m_rep->is_normal(), sc_core::SC_ID_INVALID_FX_VALUE_ ); + + if( m_params.cast_switch() == SC_ON ) + m_rep->cast( m_params, m_q_flag, m_o_flag ); +} + + +// constructors + +inline +sc_fxnum::sc_fxnum( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: m_rep( new scfx_rep ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_OBSERVER_DEFAULT_ + SC_FXNUM_OBSERVER_CONSTRUCT_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxnum::sc_fxnum( tp a, \ + const sc_fxtype_params& type_params_, \ + sc_enc enc_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: m_rep( new scfx_rep( arg ) ), \ + m_params( type_params_, enc_, cast_sw ), \ + m_q_flag( false ), \ + m_o_flag( false ), \ + m_observer( observer_ ) \ +{ \ + SC_FXNUM_OBSERVER_DEFAULT_ \ + cast(); \ + SC_FXNUM_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,*a.m_rep) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) +#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp,a.value()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_A(const char*) +DEFN_CTOR_T_B(const sc_fxval&) +DEFN_CTOR_T_C(const sc_fxval_fast&) +DEFN_CTOR_T_B(const sc_fxnum&) +DEFN_CTOR_T_C(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_D(const sc_int_base&) +DEFN_CTOR_T_D(const sc_uint_base&) +DEFN_CTOR_T_A(const sc_signed&) +DEFN_CTOR_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D + + +inline +sc_fxnum::~sc_fxnum() +{ + SC_FXNUM_OBSERVER_DESTRUCT_( *this ) + delete m_rep; +} + + +// internal use only; +inline +const scfx_rep* +sc_fxnum::get_rep() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep; +} + + +// unary operators + +inline +const sc_fxval +sc_fxnum::operator - () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) ); +} + +inline +const sc_fxval +sc_fxnum::operator + () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( new scfx_rep( *m_rep ) ); +} + + +// unary functions + +inline +void +neg( sc_fxval& c, const sc_fxnum& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::neg_scfx_rep( *a.m_rep ) ); +} + +inline +void +neg( sc_fxnum& c, const sc_fxnum& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,int64) \ +DEFN_BIN_OP_T(op,fnc,uint64) \ +DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_signed&) \ +DEFN_BIN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op,fnc) +#endif + +#define DEFN_BIN_OP(op,fnc) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \ +} \ + \ +DEFN_BIN_OP_T(op,fnc,int) \ +DEFN_BIN_OP_T(op,fnc,unsigned int) \ +DEFN_BIN_OP_T(op,fnc,long) \ +DEFN_BIN_OP_T(op,fnc,unsigned long) \ +DEFN_BIN_OP_T(op,fnc,float) \ +DEFN_BIN_OP_T(op,fnc,double) \ +DEFN_BIN_OP_T(op,fnc,const char*) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&) \ +DEFN_BIN_OP_OTHER(op,fnc) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +// don't use macros +//DEFN_BIN_OP(/,div) +inline +const sc_fxval +operator / ( const sc_fxnum& a, const sc_fxnum& b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + SC_FXNUM_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) ); +} + +inline +const sc_fxval +operator / ( const sc_fxnum& a, const sc_fxval& b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.get_rep() ) ); +} + +inline +const sc_fxval +operator / ( const sc_fxval& a, const sc_fxnum& b ) +{ + SC_FXNUM_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.get_rep(), *b.m_rep ) ); +} + +DEFN_BIN_OP_T(/,div,int) +DEFN_BIN_OP_T(/,div,unsigned int) +DEFN_BIN_OP_T(/,div,long) +DEFN_BIN_OP_T(/,div,unsigned long) +DEFN_BIN_OP_T(/,div,float) +DEFN_BIN_OP_T(/,div,double) +DEFN_BIN_OP_T(/,div,const char*) +DEFN_BIN_OP_T(/,div,const sc_fxval_fast&) +DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&) +//DEFN_BIN_OP_OTHER(/,div) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,div,int64) +DEFN_BIN_OP_T(/,div,uint64) +DEFN_BIN_OP_T(/,div,const sc_int_base&) +DEFN_BIN_OP_T(/,div,const sc_uint_base&) +DEFN_BIN_OP_T(/,div,const sc_signed&) +DEFN_BIN_OP_T(/,div,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval +operator << ( const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +const sc_fxval +operator >> ( const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.get_rep() ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.get_rep(), *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc) \ +DEFN_BIN_FNC_T(fnc,int64) \ +DEFN_BIN_FNC_T(fnc,uint64) \ +DEFN_BIN_FNC_T(fnc,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc) +#endif + +#define DEFN_BIN_FNC(fnc) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + c.set_rep( sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ) ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.get_rep() ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum& c, const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.get_rep(), *b.m_rep ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,int) \ +DEFN_BIN_FNC_T(fnc,unsigned int) \ +DEFN_BIN_FNC_T(fnc,long) \ +DEFN_BIN_FNC_T(fnc,unsigned long) \ +DEFN_BIN_FNC_T(fnc,float) \ +DEFN_BIN_FNC_T(fnc,double) \ +DEFN_BIN_FNC_T(fnc,const char*) \ +DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \ +DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ +DEFN_BIN_FNC_OTHER(fnc) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +void +rshift( sc_fxval& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + c.set_rep( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +void +lshift( sc_fxnum& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxnum& c, const sc_fxnum& a, int b ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum& a, tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.get_rep() ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.get_rep(), *b.m_rep ); \ + return ( ret ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op,ret) \ +DEFN_REL_OP_T(op,ret,int64) \ +DEFN_REL_OP_T(op,ret,uint64) \ +DEFN_REL_OP_T(op,ret,const sc_int_base&) \ +DEFN_REL_OP_T(op,ret,const sc_uint_base&) \ +DEFN_REL_OP_T(op,ret,const sc_signed&) \ +DEFN_REL_OP_T(op,ret,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op,ret) +#endif + +#define DEFN_REL_OP(op,ret) \ +inline \ +bool \ +operator op ( const sc_fxnum& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum& a, const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( a ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.get_rep() ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxval& a, const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.get_rep(), *b.m_rep ); \ + return ( ret ); \ +} \ + \ +DEFN_REL_OP_T(op,ret,int) \ +DEFN_REL_OP_T(op,ret,unsigned int) \ +DEFN_REL_OP_T(op,ret,long) \ +DEFN_REL_OP_T(op,ret,unsigned long) \ +DEFN_REL_OP_T(op,ret,float) \ +DEFN_REL_OP_T(op,ret,double) \ +DEFN_REL_OP_T(op,ret,const char*) \ +DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \ +DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&) \ +DEFN_REL_OP_OTHER(op,ret) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxnum& +sc_fxnum::operator = ( const sc_fxnum& a ) +{ + if( &a != this ) + { + SC_FXNUM_OBSERVER_READ_( a ) + *m_rep = *a.m_rep; + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + } + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator = ( const sc_fxval& a ) +{ + *m_rep = *a.get_rep(); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator = ( tp a ) \ +{ \ + sc_fxval tmp( a ); \ + *m_rep = *tmp.get_rep(); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval_fast&) +DEFN_ASN_OP_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( tp b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op,fnc) \ +DEFN_ASN_OP_T(op,fnc,int64) \ +DEFN_ASN_OP_T(op,fnc,uint64) \ +DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_signed&) \ +DEFN_ASN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op,fnc) +#endif + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( const sc_fxnum& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + SC_FXNUM_OBSERVER_READ_( b ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum& \ +sc_fxnum::operator op ( const sc_fxval& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,int) \ +DEFN_ASN_OP_T(op,fnc,unsigned int) \ +DEFN_ASN_OP_T(op,fnc,long) \ +DEFN_ASN_OP_T(op,fnc,unsigned long) \ +DEFN_ASN_OP_T(op,fnc,float) \ +DEFN_ASN_OP_T(op,fnc,double) \ +DEFN_ASN_OP_T(op,fnc,const char*) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op,fnc) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxnum& +sc_fxnum::operator <<= ( int b ) +{ + SC_FXNUM_OBSERVER_READ_( *this ) + m_rep->lshift( b ); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator >>= ( int b ) +{ + SC_FXNUM_OBSERVER_READ_( *this ) + m_rep->rshift( b ); + cast(); + SC_FXNUM_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fxnum::operator ++ ( int ) +{ + sc_fxval c( *this ); + (*this) += 1; + return c; +} + +inline +const sc_fxval +sc_fxnum::operator -- ( int ) +{ + sc_fxval c( *this ); + (*this) -= 1; + return c; +} + +inline +sc_fxnum& +sc_fxnum::operator ++ () +{ + (*this) += 1; + return *this; +} + +inline +sc_fxnum& +sc_fxnum::operator -- () +{ + (*this) -= 1; + return *this; +} + + +// bit selection + +inline +const sc_fxnum_bitref +sc_fxnum::operator [] ( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_bitref +sc_fxnum::operator [] ( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( *this, i - m_params.fwl() ); +} + +inline +const sc_fxnum_bitref +sc_fxnum::bit( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_bitref +sc_fxnum::bit( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_bitref( *this, i - m_params.fwl() ); +} + + +// part selection + +inline +const sc_fxnum_subref +sc_fxnum::operator () ( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_subref +sc_fxnum::operator () ( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_subref +sc_fxnum::range( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( const_cast<sc_fxnum&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_subref +sc_fxnum::range( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_subref( *this, i - m_params.fwl(), j - m_params.fwl() ); +} + + +inline +const sc_fxnum_subref +sc_fxnum::operator () () const +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_subref +sc_fxnum::operator () () +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +const sc_fxnum_subref +sc_fxnum::range() const +{ + return this->range( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_subref +sc_fxnum::range() +{ + return this->range( m_params.wl() - 1, 0 ); +} + + +// implicit conversion + +inline +sc_fxnum::operator double() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// explicit conversion to primitive types + +inline +short +sc_fxnum::to_short() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<short>( m_rep->to_double() ); +} + +inline +unsigned short +sc_fxnum::to_ushort() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_rep->to_double() ); +} + +inline +int +sc_fxnum::to_int() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<int>( m_rep->to_double() ); +} + +inline +int64 +sc_fxnum::to_int64() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<int64>( m_rep->to_double() ); +} + +inline +unsigned int +sc_fxnum::to_uint() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_rep->to_double() ); +} + +inline +uint64 +sc_fxnum::to_uint64() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_rep->to_double() ); +} + +inline +long +sc_fxnum::to_long() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<long>( m_rep->to_double() ); +} + +inline +unsigned long +sc_fxnum::to_ulong() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_rep->to_double() ); +} + +inline +float +sc_fxnum::to_float() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return static_cast<float>( m_rep->to_double() ); +} + +inline +double +sc_fxnum::to_double() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// query value + +inline +bool +sc_fxnum::is_neg() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_neg(); +} + +inline +bool +sc_fxnum::is_zero() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_zero(); +} + +// internal use only; +inline +bool +sc_fxnum::is_normal() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return m_rep->is_normal(); +} + +inline +bool +sc_fxnum::quantization_flag() const +{ + return m_q_flag; +} + +inline +bool +sc_fxnum::overflow_flag() const +{ + return m_o_flag; +} + + +inline +const sc_fxval +sc_fxnum::value() const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + return sc_fxval( new scfx_rep( *m_rep ) ); +} + + +// query parameters + +inline +int +sc_fxnum::wl() const +{ + return m_params.wl(); +} + +inline +int +sc_fxnum::iwl() const +{ + return m_params.iwl(); +} + +inline +sc_q_mode +sc_fxnum::q_mode() const +{ + return m_params.q_mode(); +} + +inline +sc_o_mode +sc_fxnum::o_mode() const +{ + return m_params.o_mode(); +} + +inline +int +sc_fxnum::n_bits() const +{ + return m_params.n_bits(); +} + + +inline +const sc_fxtype_params& +sc_fxnum::type_params() const +{ + return m_params.type_params(); +} + + +inline +const sc_fxcast_switch& +sc_fxnum::cast_switch() const +{ + return m_params.cast_switch(); +} + + +// internal use only; +inline +void +sc_fxnum::observer_read() const +{ + SC_FXNUM_OBSERVER_READ_( *this ); +} + + +// internal use only; +inline +bool +sc_fxnum::get_bit( int i ) const +{ + return m_rep->get_bit( i ); +} + + +// protected methods and friend functions + +inline +bool +sc_fxnum::set_bit( int i, bool high ) +{ + if( high ) + return m_rep->set( i, m_params ); + else + return m_rep->clear( i, m_params ); +} + + +inline +bool +sc_fxnum::get_slice( int i, int j, sc_bv_base& bv ) const +{ + return m_rep->get_slice( i, j, m_params, bv ); +} + +inline +bool +sc_fxnum::set_slice( int i, int j, const sc_bv_base& bv ) +{ + return m_rep->set_slice( i, j, m_params, bv ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast +// +// Base class for the fixed-point types; limited precision. +// ---------------------------------------------------------------------------- + +inline +sc_fxnum_fast_observer* +sc_fxnum_fast::observer() const +{ + return m_observer; +} + + +// constructors + +inline +sc_fxnum_fast::sc_fxnum_fast( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: m_val( 0.0 ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) +} + +inline +sc_fxnum_fast::sc_fxnum_fast( const sc_fxnum_fast& a, + const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: m_val( a.m_val ), + m_params( type_params_, enc_, cast_sw ), + m_q_flag( false ), + m_o_flag( false ), + m_observer( observer_ ) +{ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + cast(); + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxnum_fast::sc_fxnum_fast( tp a, \ + const sc_fxtype_params& type_params_, \ + sc_enc enc_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: m_val( arg ), \ + m_params( type_params_, enc_, cast_sw ), \ + m_q_flag( false ), \ + m_o_flag( false ), \ + m_observer( observer_ ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_DEFAULT_ \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a )) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,sc_fxval_fast::from_string( a )) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_B(const char*) +DEFN_CTOR_T_C(const sc_fxval&) +DEFN_CTOR_T_C(const sc_fxval_fast&) +DEFN_CTOR_T_C(const sc_fxnum&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_C(const sc_signed&) +DEFN_CTOR_T_C(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D +#undef DEFN_CTOR_T_E + + +inline +sc_fxnum_fast::~sc_fxnum_fast() +{ + SC_FXNUM_FAST_OBSERVER_DESTRUCT_( *this ) +} + + +// internal use only; +inline +double +sc_fxnum_fast::get_val() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// unary operators + +inline +const sc_fxval_fast +sc_fxnum_fast::operator - () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( - m_val ); +} + +inline +const sc_fxval_fast +sc_fxnum_fast::operator + () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( m_val ); +} + + +// unary functions + +inline +void +neg( sc_fxval_fast& c, const sc_fxnum_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( - a.m_val ); +} + +inline +void +neg( sc_fxnum_fast& c, const sc_fxnum_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = - a.m_val; + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,tp) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return sc_fxval_fast( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return sc_fxval_fast( tmp.get_val() op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op) \ +DEFN_BIN_OP_T(op,int64) \ +DEFN_BIN_OP_T(op,uint64) \ +DEFN_BIN_OP_T(op,const sc_int_base&) \ +DEFN_BIN_OP_T(op,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,const sc_signed&) \ +DEFN_BIN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op) +#endif + +#define DEFN_BIN_OP(op,dummy) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.m_val op b.m_val ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + return sc_fxval_fast( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.get_val() op b.m_val ); \ +} \ + \ +DEFN_BIN_OP_T(op,int) \ +DEFN_BIN_OP_T(op,unsigned int) \ +DEFN_BIN_OP_T(op,long) \ +DEFN_BIN_OP_T(op,unsigned long) \ +DEFN_BIN_OP_T(op,float) \ +DEFN_BIN_OP_T(op,double) \ +DEFN_BIN_OP_T(op,const char*) \ +DEFN_BIN_OP_OTHER(op) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +inline +const sc_fxval_fast +operator / ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + SC_FXNUM_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.m_val / b.m_val ); +} + +inline +const sc_fxval_fast +operator / ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val / b.get_val() ); +} + +inline +const sc_fxval_fast +operator / ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.get_val() / b.m_val ); +} + +DEFN_BIN_OP_T(/,int) +DEFN_BIN_OP_T(/,unsigned int) +DEFN_BIN_OP_T(/,long) +DEFN_BIN_OP_T(/,unsigned long) +DEFN_BIN_OP_T(/,float) +DEFN_BIN_OP_T(/,double) +DEFN_BIN_OP_T(/,const char*) +//DEFN_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,int64) +DEFN_BIN_OP_T(/,uint64) +DEFN_BIN_OP_T(/,const sc_int_base&) +DEFN_BIN_OP_T(/,const sc_uint_base&) +DEFN_BIN_OP_T(/,const sc_signed&) +DEFN_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval_fast +operator << ( const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( b ) ); +} + +inline +const sc_fxval_fast +operator >> ( const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( -b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.set_val( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.set_val( tmp.get_val() op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.get_val(); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.get_val() op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,int64) \ +DEFN_BIN_FNC_T(fnc,op,uint64) \ +DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc,op) +#endif + +#define DEFN_BIN_FNC(fnc,op) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.set_val( a.m_val op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.m_val op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + c.set_val( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.set_val( a.get_val() op b.m_val ); \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + c.m_val = a.m_val op b.get_val(); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxnum_fast& c, const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.get_val() op b.m_val; \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,op,int) \ +DEFN_BIN_FNC_T(fnc,op,unsigned int) \ +DEFN_BIN_FNC_T(fnc,op,long) \ +DEFN_BIN_FNC_T(fnc,op,unsigned long) \ +DEFN_BIN_FNC_T(fnc,op,float) \ +DEFN_BIN_FNC_T(fnc,op,double) \ +DEFN_BIN_FNC_T(fnc,op,const char*) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&) \ +DEFN_BIN_FNC_OTHER(fnc,op) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( a.m_val * scfx_pow2( b ) ); +} + +inline +void +rshift( sc_fxval_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.set_val( a.m_val * scfx_pow2( -b ) ); +} + +inline +void +lshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( b ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxnum_fast& c, const sc_fxnum_fast& a, int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( -b ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return ( a.m_val op tmp.get_val() ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return ( tmp.get_val() op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op) \ +DEFN_REL_OP_T(op,int64) \ +DEFN_REL_OP_T(op,uint64) \ +DEFN_REL_OP_T(op,const sc_int_base&) \ +DEFN_REL_OP_T(op,const sc_uint_base&) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op) +#endif + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return ( a.m_val op b.m_val ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxnum_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( a ) \ + return ( a.m_val op b.get_val() ); \ +} \ + \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + return ( a.get_val() op b.m_val ); \ +} \ + \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) \ +DEFN_REL_OP_T(op,float) \ +DEFN_REL_OP_T(op,double) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_OTHER(op) + +DEFN_REL_OP(<) +DEFN_REL_OP(<=) +DEFN_REL_OP(>) +DEFN_REL_OP(>=) +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator = ( const sc_fxnum_fast& a ) +{ + if( &a != this ) + { + SC_FXNUM_FAST_OBSERVER_READ_( a ) + m_val = a.m_val; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + } + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator = ( const sc_fxval_fast& a ) +{ + m_val = a.get_val(); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval&) +DEFN_ASN_OP_T(const sc_fxnum&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( tp b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( const sc_fxnum_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + SC_FXNUM_FAST_OBSERVER_READ_( b ) \ + m_val op b.m_val; \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +inline \ +sc_fxnum_fast& \ +sc_fxnum_fast::operator op ( const sc_fxval_fast& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + m_val op b.get_val(); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator <<= ( int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( b ); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator >>= ( int b ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( -b ); + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fxnum_fast::operator ++ ( int ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val + 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +const sc_fxval_fast +sc_fxnum_fast::operator -- ( int ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val - 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator ++ () +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val = m_val + 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxnum_fast& +sc_fxnum_fast::operator -- () +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + m_val = m_val - 1; + cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// bit selection + +inline +const sc_fxnum_fast_bitref +sc_fxnum_fast::operator [] ( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_fast_bitref +sc_fxnum_fast::operator [] ( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( *this, i - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_bitref +sc_fxnum_fast::bit( int i ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl() ); +} + +inline +sc_fxnum_fast_bitref +sc_fxnum_fast::bit( int i ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + return sc_fxnum_fast_bitref( *this, i - m_params.fwl() ); +} + + +// part selection + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::operator () ( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::operator () ( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( *this, + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::range( int i, int j ) const +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( const_cast<sc_fxnum_fast&>( *this ), + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::range( int i, int j ) +{ + SC_ERROR_IF_( i < 0 || i >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + SC_ERROR_IF_( j < 0 || j >= m_params.wl(), sc_core::SC_ID_OUT_OF_RANGE_ ); + + return sc_fxnum_fast_subref( *this, + i - m_params.fwl(), j - m_params.fwl() ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::operator () () const +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::operator () () +{ + return this->operator () ( m_params.wl() - 1, 0 ); +} + +inline +const sc_fxnum_fast_subref +sc_fxnum_fast::range() const +{ + return this->range( m_params.wl() - 1, 0 ); +} + +inline +sc_fxnum_fast_subref +sc_fxnum_fast::range() +{ + return this->range( m_params.wl() - 1, 0 ); +} + + +// implicit conversion + +inline +sc_fxnum_fast::operator double() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// explicit conversion to primitive types + +inline +short +sc_fxnum_fast::to_short() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<short>( m_val ); +} + +inline +unsigned short +sc_fxnum_fast::to_ushort() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_val ); +} + +inline +int +sc_fxnum_fast::to_int() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<int>( m_val ); +} + +inline +int64 +sc_fxnum_fast::to_int64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<int64>( m_val ); +} + +inline +unsigned int +sc_fxnum_fast::to_uint() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_val ); +} + +inline +uint64 +sc_fxnum_fast::to_uint64() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_val ); +} + +inline +long +sc_fxnum_fast::to_long() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<long>( m_val ); +} + +inline +unsigned long +sc_fxnum_fast::to_ulong() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_val ); +} + +inline +float +sc_fxnum_fast::to_float() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return static_cast<float>( m_val ); +} + +inline +double +sc_fxnum_fast::to_double() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// query value + +inline +bool +sc_fxnum_fast::is_neg() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.negative() != 0 ); +} + +inline +bool +sc_fxnum_fast::is_zero() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_zero(); +} + +// internal use only; +inline +bool +sc_fxnum_fast::is_normal() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.is_normal() || id.is_subnormal() || id.is_zero() ); +} + + +inline +bool +sc_fxnum_fast::quantization_flag() const +{ + return m_q_flag; +} + +inline +bool +sc_fxnum_fast::overflow_flag() const +{ + return m_o_flag; +} + + +inline +const sc_fxval_fast +sc_fxnum_fast::value() const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( m_val ); +} + + +// query parameters + +inline +int +sc_fxnum_fast::wl() const +{ + return m_params.wl(); +} + +inline +int +sc_fxnum_fast::iwl() const +{ + return m_params.iwl(); +} + +inline +sc_q_mode +sc_fxnum_fast::q_mode() const +{ + return m_params.q_mode(); +} + +inline +sc_o_mode +sc_fxnum_fast::o_mode() const +{ + return m_params.o_mode(); +} + +inline +int +sc_fxnum_fast::n_bits() const +{ + return m_params.n_bits(); +} + + +inline +const sc_fxtype_params& +sc_fxnum_fast::type_params() const +{ + return m_params.type_params(); +} + + +inline +const sc_fxcast_switch& +sc_fxnum_fast::cast_switch() const +{ + return m_params.cast_switch(); +} + + +// internal use only; +inline +void +sc_fxnum_fast::observer_read() const +{ + SC_FXNUM_OBSERVER_READ_( *this ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxnum_fast& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxnum_fast& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// public constructors + +inline +sc_fxval::sc_fxval( const sc_fxnum& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( *a.get_rep() ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + +inline +sc_fxval::sc_fxval( const sc_fxnum_fast& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( a.to_double() ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \ +} + +#define DEFN_BIN_OP(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxnum_fast&) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +DEFN_BIN_OP_T(/,div,const sc_fxnum_fast&) + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} + +#define DEFN_BIN_FNC(fnc) \ +DEFN_BIN_FNC_T(fnc,const sc_fxnum_fast&) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \ + return ( ret ); \ +} + + +#define DEFN_REL_OP(op,ret) \ +DEFN_REL_OP_T(op,ret,const sc_fxnum_fast&) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval& +sc_fxval::operator = ( const sc_fxnum& a ) +{ + *m_rep = *a.get_rep(); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator = ( tp b ) \ +{ \ + sc_fxval tmp( b ); \ + *m_rep = *tmp.m_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_fxnum_fast&) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( const sc_fxnum& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.get_rep() ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,const sc_fxnum_fast&) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value types; limited precision. +// ---------------------------------------------------------------------------- + +// public constructors + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxnum& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.to_double() ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxnum_fast& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.get_val() ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} + +#define DEFN_BIN_FNC(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxval&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_fxnum&) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC + + +// assignment operators + +inline +sc_fxval_fast& +sc_fxval_fast::operator = ( const sc_fxnum_fast& a ) +{ + m_val = a.get_val(); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(const sc_fxnum&) + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( const sc_fxnum_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + m_val op b.get_val(); \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,const sc_fxnum&) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp new file mode 100644 index 000000000..709a3c50b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.cpp @@ -0,0 +1,74 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum_observer.cpp - + + Original Author: 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: sc_fxnum_observer.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/sc_fxnum_observer.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +sc_fxnum_observer* (*sc_fxnum_observer::default_observer) () = 0; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +sc_fxnum_fast_observer* (*sc_fxnum_fast_observer::default_observer) () = 0; + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h new file mode 100644 index 000000000..2769df31b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxnum_observer.h @@ -0,0 +1,219 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxnum_observer.h - + + Original Author: 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: sc_fxnum_observer.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXNUM_OBSERVER_H +#define SC_FXNUM_OBSERVER_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxnum_observer; +class sc_fxnum_fast_observer; + +// forward class declarations +class sc_fxnum; +class sc_fxnum_fast; + + +#ifdef SC_ENABLE_OBSERVERS + +#define SC_FXNUM_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,construct) +#define SC_FXNUM_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,destruct) +#define SC_FXNUM_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,read) +#define SC_FXNUM_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxnum_observer*,write) +#define SC_FXNUM_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxnum_observer) + +#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,construct) +#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,destruct) +#define SC_FXNUM_FAST_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,read) +#define SC_FXNUM_FAST_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxnum_fast_observer*,write) +#define SC_FXNUM_FAST_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxnum_fast_observer) + +#else + +#define SC_FXNUM_OBSERVER_CONSTRUCT_(object) +#define SC_FXNUM_OBSERVER_DESTRUCT_(object) +#define SC_FXNUM_OBSERVER_READ_(object) +#define SC_FXNUM_OBSERVER_WRITE_(object) +#define SC_FXNUM_OBSERVER_DEFAULT_ + +#define SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(object) +#define SC_FXNUM_FAST_OBSERVER_DESTRUCT_(object) +#define SC_FXNUM_FAST_OBSERVER_READ_(object) +#define SC_FXNUM_FAST_OBSERVER_WRITE_(object) +#define SC_FXNUM_FAST_OBSERVER_DEFAULT_ + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_observer +{ + +protected: + + sc_fxnum_observer() {} + virtual ~sc_fxnum_observer() {} + +public: + + virtual void construct( const sc_fxnum& ); + virtual void destruct( const sc_fxnum& ); + virtual void read( const sc_fxnum& ); + virtual void write( const sc_fxnum& ); + + static sc_fxnum_observer* (*default_observer) (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxnum_fast_observer +{ + +protected: + + sc_fxnum_fast_observer() {} + virtual ~sc_fxnum_fast_observer() {} + +public: + + virtual void construct( const sc_fxnum_fast& ); + virtual void destruct( const sc_fxnum_fast& ); + virtual void read( const sc_fxnum_fast& ); + virtual void write( const sc_fxnum_fast& ); + + static sc_fxnum_fast_observer* (*default_observer) (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_observer +// +// Abstract base class for fixed-point types observers; arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxnum_observer::construct( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::destruct( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::read( const sc_fxnum& ) +{} + +inline +void +sc_fxnum_observer::write( const sc_fxnum& ) +{} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxnum_fast_observer +// +// Abstract base class for fixed-point types observers; limited precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxnum_fast_observer::construct( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::destruct( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::read( const sc_fxnum_fast& ) +{} + +inline +void +sc_fxnum_fast_observer::write( const sc_fxnum_fast& ) +{} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp new file mode 100644 index 000000000..60c18a2b5 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.cpp @@ -0,0 +1,108 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxtype_params.cpp - + + Original Author: 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: sc_fxtype_params.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/sc_fxtype_params.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxtype_params +// +// Fixed-point type parameters class. +// ---------------------------------------------------------------------------- + +const std::string +sc_fxtype_params::to_string() const +{ + std::string s; + + char buf[BUFSIZ]; + + s += "("; + std::sprintf( buf, "%d", m_wl ); + s += buf; + s += ","; + std::sprintf( buf, "%d", m_iwl ); + s += buf; + s += ","; + s += sc_dt::to_string( m_q_mode ); + s += ","; + s += sc_dt::to_string( m_o_mode ); + s += ","; + std::sprintf( buf, "%d", m_n_bits ); + s += buf; + s += ")"; + + return s; +} + + +void +sc_fxtype_params::print( ::std::ostream& os ) const +{ + os << to_string(); +} + +void +sc_fxtype_params::dump( ::std::ostream& os ) const +{ + os << "sc_fxtype_params" << ::std::endl; + os << "(" << ::std::endl; + os << "wl = " << m_wl << ::std::endl; + os << "iwl = " << m_iwl << ::std::endl; + os << "q_mode = " << m_q_mode << ::std::endl; + os << "o_mode = " << m_o_mode << ::std::endl; + os << "n_bits = " << m_n_bits << ::std::endl; + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h new file mode 100644 index 000000000..a59ba293b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxtype_params.h @@ -0,0 +1,342 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxtype_params.h - + + Original Author: 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: sc_fxtype_params.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXTYPE_PARAMS_H +#define SC_FXTYPE_PARAMS_H + + +#include "sysc/datatypes/fx/sc_context.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxtype_params; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxtype_params +// +// Fixed-point type parameters class. +// ---------------------------------------------------------------------------- + +class sc_fxtype_params +{ +public: + + sc_fxtype_params(); + sc_fxtype_params( int, int ); + sc_fxtype_params( sc_q_mode, sc_o_mode, int = 0 ); + sc_fxtype_params( int, int, sc_q_mode, sc_o_mode, int = 0 ); + sc_fxtype_params( const sc_fxtype_params& ); + sc_fxtype_params( const sc_fxtype_params&, + int, int ); + sc_fxtype_params( const sc_fxtype_params&, + sc_q_mode, sc_o_mode, int = 0 ); + explicit sc_fxtype_params( sc_without_context ); + + sc_fxtype_params& operator = ( const sc_fxtype_params& ); + + friend bool operator == ( const sc_fxtype_params&, + const sc_fxtype_params& ); + friend bool operator != ( const sc_fxtype_params&, + const sc_fxtype_params& ); + + int wl() const; + void wl( int ); + + int iwl() const; + void iwl( int ); + + sc_q_mode q_mode() const; + void q_mode( sc_q_mode ); + + sc_o_mode o_mode() const; + void o_mode( sc_o_mode ); + + int n_bits() const; + void n_bits( int ); + + const std::string to_string() const; + + void print( ::std::ostream& = ::std::cout ) const; + void dump( ::std::ostream& = ::std::cout ) const; + +private: + + int m_wl; + int m_iwl; + sc_q_mode m_q_mode; + sc_o_mode m_o_mode; + int m_n_bits; +}; + + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_fxtype_context +// +// Context type for the fixed-point type parameters. +// ---------------------------------------------------------------------------- + +typedef sc_context<sc_fxtype_params> sc_fxtype_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +sc_fxtype_params::sc_fxtype_params() +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); +} + +inline +sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); + + SC_CHECK_WL_( wl_ ); + m_wl = wl_; + m_iwl = iwl_; +} + +inline +sc_fxtype_params::sc_fxtype_params( sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + *this = sc_fxtype_context::default_value(); + + SC_CHECK_N_BITS_( n_bits_ ); + m_q_mode = q_mode_; + m_o_mode = o_mode_; + m_n_bits = n_bits_; +} + +inline +sc_fxtype_params::sc_fxtype_params( int wl_, int iwl_, + sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl(), m_iwl(), m_q_mode(), m_o_mode(), m_n_bits() +{ + SC_CHECK_WL_( wl_ ); + SC_CHECK_N_BITS_( n_bits_ ); + m_wl = wl_; + m_iwl = iwl_; + m_q_mode = q_mode_; + m_o_mode = o_mode_; + m_n_bits = n_bits_; +} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a ) +: m_wl( a.m_wl ), m_iwl( a.m_iwl ), + m_q_mode( a.m_q_mode ), + m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a, + int wl_, int iwl_ ) +: m_wl( wl_ ), m_iwl( iwl_ ), + m_q_mode( a.m_q_mode ), + m_o_mode( a.m_o_mode ), m_n_bits( a.m_n_bits ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( const sc_fxtype_params& a, + sc_q_mode q_mode_, + sc_o_mode o_mode_, int n_bits_ ) +: m_wl( a.m_wl ), m_iwl( a.m_iwl ), + m_q_mode( q_mode_ ), + m_o_mode( o_mode_ ), m_n_bits( n_bits_ ) +{} + +inline +sc_fxtype_params::sc_fxtype_params( sc_without_context ) +: m_wl ( SC_DEFAULT_WL_ ), + m_iwl ( SC_DEFAULT_IWL_ ), + m_q_mode( SC_DEFAULT_Q_MODE_ ), + m_o_mode( SC_DEFAULT_O_MODE_ ), + m_n_bits( SC_DEFAULT_N_BITS_ ) +{} + + +inline +sc_fxtype_params& +sc_fxtype_params::operator = ( const sc_fxtype_params& a ) +{ + if( &a != this ) + { + m_wl = a.m_wl; + m_iwl = a.m_iwl; + m_q_mode = a.m_q_mode; + m_o_mode = a.m_o_mode; + m_n_bits = a.m_n_bits; + } + return *this; +} + + +inline +bool +operator == ( const sc_fxtype_params& a, const sc_fxtype_params& b ) +{ + return ( a.m_wl == b.m_wl && + a.m_iwl == b.m_iwl && + a.m_q_mode == b.m_q_mode && + a.m_o_mode == b.m_o_mode && + a.m_n_bits == b.m_n_bits ); +} + +inline +bool +operator != ( const sc_fxtype_params& a, const sc_fxtype_params& b ) +{ + return ( a.m_wl != b.m_wl || + a.m_iwl != b.m_iwl || + a.m_q_mode != b.m_q_mode || + a.m_o_mode != b.m_o_mode || + a.m_n_bits != b.m_n_bits ); +} + + +inline +int +sc_fxtype_params::wl() const +{ + return m_wl; +} + +inline +void +sc_fxtype_params::wl( int wl_ ) +{ + SC_CHECK_WL_( wl_ ); + m_wl = wl_; +} + + +inline +int +sc_fxtype_params::iwl() const +{ + return m_iwl; +} + +inline +void +sc_fxtype_params::iwl( int iwl_ ) +{ + m_iwl = iwl_; +} + + +inline +sc_q_mode +sc_fxtype_params::q_mode() const +{ + return m_q_mode; +} + +inline +void +sc_fxtype_params::q_mode( sc_q_mode q_mode_ ) +{ + m_q_mode = q_mode_; +} + + +inline +sc_o_mode +sc_fxtype_params::o_mode() const +{ + return m_o_mode; +} + +inline +void +sc_fxtype_params::o_mode( sc_o_mode o_mode_ ) +{ + m_o_mode = o_mode_; +} + + +inline +int +sc_fxtype_params::n_bits() const +{ + return m_n_bits; +} + +inline +void +sc_fxtype_params::n_bits( int n_bits_ ) +{ + SC_CHECK_N_BITS_( n_bits_ ); + m_n_bits = n_bits_; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxtype_params& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp new file mode 100644 index 000000000..3ba5fbacd --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.cpp @@ -0,0 +1,884 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval.cpp - + + Original Author: 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: sc_fxval.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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 <ctype.h> +#include <stdlib.h> +#include <math.h> +#include <float.h> + +#include "sysc/datatypes/fx/sc_fxval.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// explicit conversion to character string + +const std::string +sc_fxval::to_string() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep ) const +{ + return std::string( m_rep->to_string( numrep, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), SC_E ) ); +} + +const std::string +sc_fxval::to_string( sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( SC_DEC, -1, fmt ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, -1, fmt ) ); +} + +const std::string +sc_fxval::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( m_rep->to_string( numrep, (w_prefix ? 1 : 0), fmt ) ); +} + + +const std::string +sc_fxval::to_dec() const +{ + return std::string( m_rep->to_string( SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_bin() const +{ + return std::string( m_rep->to_string( SC_BIN, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_oct() const +{ + return std::string( m_rep->to_string( SC_OCT, -1, SC_E ) ); +} + +const std::string +sc_fxval::to_hex() const +{ + return std::string( m_rep->to_string( SC_HEX, -1, SC_E ) ); +} + + +// print or dump content + +void +sc_fxval::print( ::std::ostream& os ) const +{ + m_rep->print( os ); +} + +void +sc_fxval::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxval::dump( ::std::ostream& os ) const +{ + os << "sc_fxval" << ::std::endl; + os << "(" << ::std::endl; + os << "rep = "; + m_rep->dump( os ); + // TO BE COMPLETED + // os << "r_flag = " << m_r_flag << ::std::endl; + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// protected methods and friend functions + +sc_fxval_observer* +sc_fxval::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxval_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxval::unlock_observer( sc_fxval_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value types; limited precision. +// ---------------------------------------------------------------------------- + +static +void +print_dec( scfx_string& s, scfx_ieee_double id, int w_prefix, sc_fmt fmt ) +{ + if( id.negative() != 0 ) + { + id.negative( 0 ); + s += '-'; + } + + if( w_prefix == 1 ) { + scfx_print_prefix( s, SC_DEC ); + } + + if( id.is_zero() ) + { + s += '0'; + return; + } + + // split 'id' into its integer and fractional part + + double int_part; + double frac_part = modf( static_cast<double>( id ), &int_part ); + + int i; + + // print integer part + + int int_digits = 0; + int int_zeros = 0; + + if( int_part != 0.0 ) + { + int_digits = (int) ceil( log10( int_part + 1.0 ) ); + + int len = s.length(); + s.append( int_digits ); + + bool zero_digits = ( frac_part == 0.0 && fmt != SC_F ); + + for( i = int_digits + len - 1; i >= len; i-- ) + { + unsigned int remainder = (unsigned int) fmod( int_part, 10.0 ); + s[i] = static_cast<char>( '0' + remainder ); + + if( zero_digits ) + { + if( remainder == 0 ) + int_zeros ++; + else + zero_digits = false; + } + + int_part /= 10.0; + } + + // discard trailing zeros from int_part + s.discard( int_zeros ); + + if( s[len] == '0' ) + { + // int_digits was overestimated by one + s.remove( len ); + -- int_digits; + } + } + + // print fractional part + + int frac_digits = 0; + int frac_zeros = 0; + + if( frac_part != 0.0 ) + { + s += '.'; + + bool zero_digits = ( int_digits == 0 && fmt != SC_F ); + + frac_zeros = (int) floor( - log10( frac_part + DBL_EPSILON ) ); + + frac_part *= pow( 10.0, frac_zeros ); + + frac_digits = frac_zeros; + if( ! zero_digits ) + { + for( i = 0; i < frac_zeros; i ++ ) + s += '0'; + frac_zeros = 0; + } + + while( frac_part != 0.0 ) + { + frac_part *= 10.0; + int n = static_cast<int>( frac_part ); + + if( zero_digits ) + { + if( n == 0 ) + frac_zeros ++; + else + zero_digits = false; + } + + if( ! zero_digits ) + s += static_cast<char>( '0' + n ); + + frac_part -= n; + frac_digits ++; + } + } + + // print exponent + + if( fmt != SC_F ) + { + if( frac_digits == 0 ) + scfx_print_exp( s, int_zeros ); + else if( int_digits == 0 ) + scfx_print_exp( s, - frac_zeros ); + } +} + + +static +void +print_other( scfx_string& s, const scfx_ieee_double& id, sc_numrep numrep, + int w_prefix, sc_fmt fmt, const scfx_params* params ) +{ + scfx_ieee_double id2 = id; + + sc_numrep numrep2 = numrep; + + bool numrep_is_sm = ( numrep == SC_BIN_SM || + numrep == SC_OCT_SM || + numrep == SC_HEX_SM ); + + if( numrep_is_sm ) + { + if( id2.negative() != 0 ) + { + s += '-'; + id2.negative( 0 ); + } + switch( numrep ) + { + case SC_BIN_SM: + numrep2 = SC_BIN_US; + break; + case SC_OCT_SM: + numrep2 = SC_OCT_US; + break; + case SC_HEX_SM: + numrep2 = SC_HEX_US; + break; + default: + ; + } + } + + if( w_prefix != 0 ) { + scfx_print_prefix( s, numrep ); + } + + numrep = numrep2; + + sc_fxval_fast a( id2 ); + + int msb, lsb; + + if( params != 0 ) + { + msb = params->iwl() - 1; + lsb = params->iwl() - params->wl(); + + if( params->enc() == SC_TC_ && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) && + ! numrep_is_sm && + params->wl() > 1 ) + -- msb; + else if( params->enc() == SC_US_ && + ( numrep == SC_BIN || + numrep == SC_OCT || + numrep == SC_HEX || + numrep == SC_CSD ) ) + ++ msb; + } + else + { + if( a.is_zero() ) + { + msb = 0; + lsb = 0; + } + else + { + msb = id2.exponent() + 1; + while( a.get_bit( msb ) == a.get_bit( msb - 1 ) ) + -- msb; + + if( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) + -- msb; + + lsb = id2.exponent() - 52; + while( ! a.get_bit( lsb ) ) + ++ lsb; + } + } + + int step; + + switch( numrep ) + { + case SC_BIN: + case SC_BIN_US: + case SC_CSD: + step = 1; + break; + case SC_OCT: + case SC_OCT_US: + step = 3; + break; + case SC_HEX: + case SC_HEX_US: + step = 4; + break; + default: + step = 0; + } + + msb = (int) ceil( double( msb + 1 ) / step ) * step - 1; + + lsb = (int) floor( double( lsb ) / step ) * step; + + if( msb < 0 ) + { + s += '.'; + if( fmt == SC_F ) + { + int sign = ( id2.negative() != 0 ) ? ( 1 << step ) - 1 : 0; + for( int i = ( msb + 1 ) / step; i < 0; i ++ ) + { + if( sign < 10 ) + s += static_cast<char>( sign + '0' ); + else + s += static_cast<char>( sign + 'a' - 10 ); + } + } + } + + int i = msb; + while( i >= lsb ) + { + int value = 0; + for( int j = step - 1; j >= 0; -- j ) + { + value += static_cast<int>( a.get_bit( i ) ) << j; + -- i; + } + if( value < 10 ) + s += static_cast<char>( value + '0' ); + else + s += static_cast<char>( value + 'a' - 10 ); + if( i == -1 ) + s += '.'; + } + + if( lsb > 0 && fmt == SC_F ) + { + for( int i = lsb / step; i > 0; i -- ) + s += '0'; + } + + if( s[s.length() - 1] == '.' ) + s.discard( 1 ); + + if( fmt != SC_F ) + { + if( msb < 0 ) + scfx_print_exp( s, ( msb + 1 ) / step ); + else if( lsb > 0 ) + scfx_print_exp( s, lsb / step ); + } + + if( numrep == SC_CSD ) + scfx_tc2csd( s, w_prefix ); +} + + +const char* +to_string( const scfx_ieee_double& id, sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params = 0 ) +{ + static scfx_string s; + + s.clear(); + + if( id.is_nan() ) + scfx_print_nan( s ); + else if( id.is_inf() ) + scfx_print_inf( s, static_cast<bool>( id.negative() ) ); + else if( id.negative() && ! id.is_zero() && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) ) + s += "negative"; + else if( numrep == SC_DEC ) + sc_dt::print_dec( s, id, w_prefix, fmt ); + else + sc_dt::print_other( s, id, numrep, w_prefix, fmt, params ); + + return s; +} + + +// explicit conversion to character string + +const std::string +sc_fxval_fast::to_string() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + SC_E ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, fmt ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, -1, fmt ) ); +} + +const std::string +sc_fxval_fast::to_string( sc_numrep numrep, bool w_prefix, sc_fmt fmt ) const +{ + return std::string( sc_dt::to_string( m_val, numrep, (w_prefix ? 1 : 0), + fmt ) ); +} + + +const std::string +sc_fxval_fast::to_dec() const +{ + return std::string( sc_dt::to_string( m_val, SC_DEC, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_bin() const +{ + return std::string( sc_dt::to_string( m_val, SC_BIN, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_oct() const +{ + return std::string( sc_dt::to_string( m_val, SC_OCT, -1, SC_E ) ); +} + +const std::string +sc_fxval_fast::to_hex() const +{ + return std::string( sc_dt::to_string( m_val, SC_HEX, -1, SC_E ) ); +} + + +// print or dump content + +void +sc_fxval_fast::print( ::std::ostream& os ) const +{ + os << sc_dt::to_string( m_val, SC_DEC, -1, SC_E ); +} + +void +sc_fxval_fast::scan( ::std::istream& is ) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +void +sc_fxval_fast::dump( ::std::ostream& os ) const +{ + os << "sc_fxval_fast" << ::std::endl; + os << "(" << ::std::endl; + os << "val = " << m_val << ::std::endl; + // TO BE COMPLETED + // os << "r_flag = " << m_r_flag << ::std::endl; + // os << "observer = "; + // if( m_observer != 0 ) + // m_observer->dump( os ); + // else + // os << "0" << ::std::endl; + os << ")" << ::std::endl; +} + + +// internal use only; +bool +sc_fxval_fast::get_bit( int i ) const +{ + scfx_ieee_double id( m_val ); + if( id.is_zero() || id.is_nan() || id.is_inf() ) + return false; + + // convert to two's complement + + unsigned int m0 = id.mantissa0(); + unsigned int m1 = id.mantissa1(); + + if( id.is_normal() ) + m0 += 1U << 20; + + if( id.negative() != 0 ) + { + m0 = ~ m0; + m1 = ~ m1; + unsigned int tmp = m1; + m1 += 1U; + if( m1 <= tmp ) + m0 += 1U; + } + + // get the right bit + + int j = i - id.exponent(); + if( ( j += 20 ) >= 32 ) + return ( ( m0 & 1U << 31 ) != 0 ); + else if( j >= 0 ) + return ( ( m0 & 1U << j ) != 0 ); + else if( ( j += 32 ) >= 0 ) + return ( ( m1 & 1U << j ) != 0 ); + else + return false; +} + + +// protected methods and friend functions + +sc_fxval_fast_observer* +sc_fxval_fast::lock_observer() const +{ + SC_ASSERT_( m_observer != 0, "lock observer failed" ); + sc_fxval_fast_observer* tmp = m_observer; + m_observer = 0; + return tmp; +} + +void +sc_fxval_fast::unlock_observer( sc_fxval_fast_observer* observer_ ) const +{ + SC_ASSERT_( observer_ != 0, "unlock observer failed" ); + m_observer = observer_; +} + + +#define SCFX_FAIL_IF_(cnd) \ +{ \ + if( ( cnd ) ) \ + return static_cast<double>( scfx_ieee_double::nan() ); \ +} + +double +sc_fxval_fast::from_string( const char* s ) +{ + SCFX_FAIL_IF_( s == 0 || *s == 0 ); + + scfx_string s2; + s2 += s; + s2 += '\0'; + + bool sign_char; + int 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 + return static_cast<double>( scfx_ieee_double::nan() ); + if( scfx_is_inf( s ) ) // special case: Infinity + return static_cast<double>( scfx_ieee_double::inf( sign ) ); + 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:;// Martin, what is 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 ); + } + + // + // convert the mantissa + // + + double integer = 0.0; + + if( int_digits != 0 ) + { + + bool first_digit = true; + + for( ; s < end; s ++ ) + { + if( *s == '.' ) + break; + + if( first_digit ) + { + integer = scfx_to_digit( *s, numrep ); + switch( numrep ) + { + case SC_BIN: + case SC_OCT: + case SC_HEX: + { + if( integer >= ( base >> 1 ) ) + integer -= base; // two's complement + break; + } + default: + ; + } + first_digit = false; + } + else + { + integer *= base; + integer += scfx_to_digit( *s, numrep ); + } + } + } + + // [ . fraction ] + + double fraction = 0.0; + + if( frac_digits != 0 ) + { + s ++; // skip '.' + + bool first_digit = ( int_digits == 0 ); + + double scale = 1.0; + + for( ; s < end; s ++ ) + { + scale /= base; + + if( first_digit ) + { + fraction = scfx_to_digit( *s, numrep ); + switch( numrep ) + { + case SC_BIN: + case SC_OCT: + case SC_HEX: + { + if( fraction >= ( base >> 1 ) ) + fraction -= base; // two's complement + break; + } + default: + ; + } + fraction *= scale; + first_digit = false; + } + else + fraction += scfx_to_digit( *s, numrep ) * scale; + } + } + + double exp = ( exponent != 0 ) ? pow( (double) base, (double) exponent ) + : 1; + + return ( sign * ( integer + fraction ) * exp ); +} + +#undef SCFX_FAIL_IF_ + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h new file mode 100644 index 000000000..1f199875c --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval.h @@ -0,0 +1,2269 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval.h - + + Original Author: 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: sc_fxval.h,v $ +// Revision 1.3 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.2 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXVAL_H +#define SC_FXVAL_H + + +#include "sysc/datatypes/fx/scfx_rep.h" +#ifndef SC_FX_EXCLUDE_OTHER +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#endif +#include "sysc/datatypes/fx/sc_fxval_observer.h" + +#ifdef SC_FXVAL_IMPLICIT_CONV +# define SCFX_EXPLICIT_ // nothing +#else +# define SCFX_EXPLICIT_ explicit +#endif +#ifdef SC_FXVAL_IMPLICIT_OTHER +# define SCFX_EXPLICIT_OTHER_ +#else +# define SCFX_EXPLICIT_OTHER_ explicit +#endif + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxval; +class sc_fxval_fast; + +// forward class declarations +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxval +{ + + friend class sc_fxnum; + +protected: + + sc_fxval_observer* observer() const; + +public: + + // internal use only; + explicit sc_fxval( scfx_rep* ); + + + explicit sc_fxval( sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( int, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( unsigned int, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( long, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( unsigned long, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( float, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( double, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval( const char*, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxval&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxval_fast&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxnum&, sc_fxval_observer* = 0 ); + sc_fxval( const sc_fxnum_fast&, sc_fxval_observer* = 0 ); +#ifndef SC_FX_EXCLUDE_OTHER + SCFX_EXPLICIT_OTHER_ sc_fxval( int64, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( uint64, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_int_base&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_uint_base&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_signed&, sc_fxval_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_unsigned&, sc_fxval_observer* = 0 ); +#endif + + ~sc_fxval(); + + + // internal use only; + const scfx_rep* get_rep() const; + void set_rep( scfx_rep* ); + + + // unary operators + + const sc_fxval operator - () const; + const sc_fxval& operator + () const; + + + // unary functions + + friend void neg( sc_fxval&, const sc_fxval& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval operator op ( const sc_fxval&, tp ); \ + friend const sc_fxval operator op ( tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval operator op ( const sc_fxval&, const sc_fxval& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_T(op,const sc_fxval_fast&) \ + DECL_BIN_OP_T(op,const sc_fxnum_fast&) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// declaration below doesn't compile with BCB5 (E2206) +// DECL_BIN_OP(/,div) +// previous macro expanded + friend const sc_fxval operator / ( const sc_fxval&, const sc_fxval& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) + DECL_BIN_OP_T(/,const sc_fxval_fast&) + DECL_BIN_OP_T(/,const sc_fxnum_fast&) +// DECL_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval operator << ( const sc_fxval&, int ); + friend const sc_fxval operator >> ( const sc_fxval&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval&, const sc_fxval&, tp ); \ + friend void fnc ( sc_fxval&, tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval&, const sc_fxval&, const sc_fxval& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval_fast&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval&, const sc_fxval&, int ); + friend void rshift( sc_fxval&, const sc_fxval&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxval&, tp ); \ + friend bool operator op ( tp, const sc_fxval& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxval&, const sc_fxval& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_T(op,const sc_fxval_fast&) \ + DECL_REL_OP_T(op,const sc_fxnum_fast&) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxval& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_fxval& operator ++ (); + sc_fxval& operator -- (); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + bool rounding_flag() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + sc_fxval_observer* lock_observer() const; + void unlock_observer( sc_fxval_observer* ) const; + + + void get_type( int&, int&, sc_enc& ) const; + + const sc_fxval quantization( const scfx_params&, bool& ) const; + const sc_fxval overflow( const scfx_params&, bool& ) const; + +private: + + scfx_rep* m_rep; + + mutable sc_fxval_observer* m_observer; + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value type; limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_fast +{ + + friend class sc_fxnum_fast; + +protected: + + sc_fxval_fast_observer* observer() const; + +public: + + explicit sc_fxval_fast( sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( int, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( unsigned int, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( long, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( unsigned long, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( float, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( double, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_ sc_fxval_fast( const char*, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxval&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxval_fast&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxnum&, sc_fxval_fast_observer* = 0 ); + sc_fxval_fast( const sc_fxnum_fast&, sc_fxval_fast_observer* = 0 ); +#ifndef SC_FX_EXCLUDE_OTHER + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( int64, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( uint64, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_int_base&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_uint_base&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_signed&, sc_fxval_fast_observer* = 0 ); + SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_unsigned&, sc_fxval_fast_observer* = 0 ); +#endif + + ~sc_fxval_fast(); + + // internal use only; + double get_val() const; + void set_val( double ); + + + // unary operators + + const sc_fxval_fast operator - () const; + const sc_fxval_fast& operator + () const; + + + // unary functions + + friend void neg( sc_fxval_fast&, const sc_fxval_fast& ); + + + // binary operators + +#define DECL_BIN_OP_T(op,tp) \ + friend const sc_fxval_fast operator op ( const sc_fxval_fast&, tp ); \ + friend const sc_fxval_fast operator op ( tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_OP_OTHER(op) \ + DECL_BIN_OP_T(op,int64) \ + DECL_BIN_OP_T(op,uint64) \ + DECL_BIN_OP_T(op,const sc_int_base&) \ + DECL_BIN_OP_T(op,const sc_uint_base&) \ + DECL_BIN_OP_T(op,const sc_signed&) \ + DECL_BIN_OP_T(op,const sc_unsigned&) +#else +#define DECL_BIN_OP_OTHER(op) +#endif + +#define DECL_BIN_OP(op,dummy) \ + friend const sc_fxval_fast operator op ( const sc_fxval_fast&, \ + const sc_fxval_fast& ); \ + DECL_BIN_OP_T(op,int) \ + DECL_BIN_OP_T(op,unsigned int) \ + DECL_BIN_OP_T(op,long) \ + DECL_BIN_OP_T(op,unsigned long) \ + DECL_BIN_OP_T(op,float) \ + DECL_BIN_OP_T(op,double) \ + DECL_BIN_OP_T(op,const char*) \ + DECL_BIN_OP_OTHER(op) + + DECL_BIN_OP(*,mult) + DECL_BIN_OP(+,add) + DECL_BIN_OP(-,sub) +// don't use macro +// DECL_BIN_OP(/,div) + friend const sc_fxval_fast operator / ( const sc_fxval_fast&, + const sc_fxval_fast& ); + DECL_BIN_OP_T(/,int) + DECL_BIN_OP_T(/,unsigned int) + DECL_BIN_OP_T(/,long) + DECL_BIN_OP_T(/,unsigned long) + DECL_BIN_OP_T(/,float) + DECL_BIN_OP_T(/,double) + DECL_BIN_OP_T(/,const char*) +// DECL_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_BIN_OP_T(/,int64) \ + DECL_BIN_OP_T(/,uint64) \ + DECL_BIN_OP_T(/,const sc_int_base&) \ + DECL_BIN_OP_T(/,const sc_uint_base&) \ + DECL_BIN_OP_T(/,const sc_signed&) \ + DECL_BIN_OP_T(/,const sc_unsigned&) +#endif + +#undef DECL_BIN_OP_T +#undef DECL_BIN_OP_OTHER +#undef DECL_BIN_OP + + friend const sc_fxval_fast operator << ( const sc_fxval_fast&, int ); + friend const sc_fxval_fast operator >> ( const sc_fxval_fast&, int ); + + + // binary functions + +#define DECL_BIN_FNC_T(fnc,tp) \ + friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, tp ); \ + friend void fnc ( sc_fxval_fast&, tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_BIN_FNC_OTHER(fnc) \ + DECL_BIN_FNC_T(fnc,int64) \ + DECL_BIN_FNC_T(fnc,uint64) \ + DECL_BIN_FNC_T(fnc,const sc_int_base&) \ + DECL_BIN_FNC_T(fnc,const sc_uint_base&) \ + DECL_BIN_FNC_T(fnc,const sc_signed&) \ + DECL_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DECL_BIN_FNC_OTHER(fnc) +#endif + +#define DECL_BIN_FNC(fnc) \ + friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, \ + const sc_fxval_fast& ); \ + DECL_BIN_FNC_T(fnc,int) \ + DECL_BIN_FNC_T(fnc,unsigned int) \ + DECL_BIN_FNC_T(fnc,long) \ + DECL_BIN_FNC_T(fnc,unsigned long) \ + DECL_BIN_FNC_T(fnc,float) \ + DECL_BIN_FNC_T(fnc,double) \ + DECL_BIN_FNC_T(fnc,const char*) \ + DECL_BIN_FNC_T(fnc,const sc_fxval&) \ + DECL_BIN_FNC_T(fnc,const sc_fxnum&) \ + DECL_BIN_FNC_OTHER(fnc) + + DECL_BIN_FNC(mult) + DECL_BIN_FNC(div) + DECL_BIN_FNC(add) + DECL_BIN_FNC(sub) + +#undef DECL_BIN_FNC_T +#undef DECL_BIN_FNC_OTHER +#undef DECL_BIN_FNC + + friend void lshift( sc_fxval_fast&, const sc_fxval_fast&, int ); + friend void rshift( sc_fxval_fast&, const sc_fxval_fast&, int ); + + + // relational (including equality) operators + +#define DECL_REL_OP_T(op,tp) \ + friend bool operator op ( const sc_fxval_fast&, tp ); \ + friend bool operator op ( tp, const sc_fxval_fast& ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_REL_OP_OTHER(op) \ + DECL_REL_OP_T(op,int64) \ + DECL_REL_OP_T(op,uint64) \ + DECL_REL_OP_T(op,const sc_int_base&) \ + DECL_REL_OP_T(op,const sc_uint_base&) \ + DECL_REL_OP_T(op,const sc_signed&) \ + DECL_REL_OP_T(op,const sc_unsigned&) +#else +#define DECL_REL_OP_OTHER(op) +#endif + +#define DECL_REL_OP(op) \ + friend bool operator op ( const sc_fxval_fast&, const sc_fxval_fast& ); \ + DECL_REL_OP_T(op,int) \ + DECL_REL_OP_T(op,unsigned int) \ + DECL_REL_OP_T(op,long) \ + DECL_REL_OP_T(op,unsigned long) \ + DECL_REL_OP_T(op,float) \ + DECL_REL_OP_T(op,double) \ + DECL_REL_OP_T(op,const char*) \ + DECL_REL_OP_OTHER(op) + + DECL_REL_OP(<) + DECL_REL_OP(<=) + DECL_REL_OP(>) + DECL_REL_OP(>=) + DECL_REL_OP(==) + DECL_REL_OP(!=) + +#undef DECL_REL_OP_T +#undef DECL_REL_OP_OTHER +#undef DECL_REL_OP + + + // assignment operators + +#define DECL_ASN_OP_T(op,tp) \ + sc_fxval_fast& operator op( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_fxval_fast& operator ++ (); + sc_fxval_fast& operator -- (); + + + // implicit conversion + + operator double() const; // necessary evil! + + + // explicit conversion to primitive types + + short to_short() const; + unsigned short to_ushort() const; + int to_int() const; + unsigned int to_uint() const; + long to_long() const; + unsigned long to_ulong() const; + int64 to_int64() const; + uint64 to_uint64() const; + float to_float() const; + double to_double() const; + + + // explicit conversion to character string + + const std::string to_string() const; + const std::string to_string( sc_numrep ) const; + const std::string to_string( sc_numrep, bool ) const; + const std::string to_string( sc_fmt ) const; + const std::string to_string( sc_numrep, sc_fmt ) const; + const std::string to_string( sc_numrep, bool, sc_fmt ) const; + + const std::string to_dec() const; + const std::string to_bin() const; + const std::string to_oct() const; + const std::string to_hex() const; + + + // query value + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + bool rounding_flag() const; + + + // print or dump content + + void print( ::std::ostream& = ::std::cout ) const; + void scan( ::std::istream& = ::std::cin ); + void dump( ::std::ostream& = ::std::cout ) const; + + + // internal use only; + bool get_bit( int ) const; + +protected: + + sc_fxval_fast_observer* lock_observer() const; + void unlock_observer( sc_fxval_fast_observer* ) const; + + + static double from_string( const char* ); + +private: + + double m_val; + + mutable sc_fxval_fast_observer* m_observer; + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval +// +// Fixed-point value type; arbitrary precision. +// ---------------------------------------------------------------------------- + +// protected method + +inline +sc_fxval_observer* +sc_fxval::observer() const +{ + return m_observer; +} + + +// internal use only; +inline +sc_fxval::sc_fxval( scfx_rep* a ) +: m_rep( a != 0 ? a : new scfx_rep ), + m_observer( 0 ) +{} + + +// public constructors + +inline +sc_fxval::sc_fxval( sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) +} + +inline +sc_fxval::sc_fxval( const sc_fxval& a, + sc_fxval_observer* observer_ ) +: m_rep( new scfx_rep( *a.m_rep ) ), + m_observer( observer_ ) +{ + SC_FXVAL_OBSERVER_DEFAULT_ + SC_FXVAL_OBSERVER_READ_( a ) + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxval::sc_fxval( tp a, \ + sc_fxval_observer* observer_ ) \ +: m_rep( new scfx_rep( arg ) ), \ + m_observer( observer_ ) \ +{ \ + SC_FXVAL_OBSERVER_DEFAULT_ \ + SC_FXVAL_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,a.to_double()) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.value()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_A(const char*) +DEFN_CTOR_T_B(const sc_fxval_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_A(const sc_signed&) +DEFN_CTOR_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C + + +inline +sc_fxval::~sc_fxval() +{ + SC_FXVAL_OBSERVER_DESTRUCT_( *this ) + delete m_rep; +} + + +// internal use only; +inline +const scfx_rep* +sc_fxval::get_rep() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep; +} + +// internal use only; +inline +void +sc_fxval::set_rep( scfx_rep* rep_ ) +{ + delete m_rep; + m_rep = rep_; + SC_FXVAL_OBSERVER_WRITE_( *this ) +} + + +// unary operators + +inline +const sc_fxval +sc_fxval::operator - () const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) ); +} + +inline +const sc_fxval& +sc_fxval::operator + () const +{ + // SC_FXVAL_OBSERVER_READ_( *this ) + return *this; +} + + +// unary functions + +inline +void +neg( sc_fxval& c, const sc_fxval& a ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,fnc,tp) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) ); \ +} \ + \ +inline \ +const sc_fxval \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op,fnc) \ +DEFN_BIN_OP_T(op,fnc,int64) \ +DEFN_BIN_OP_T(op,fnc,uint64) \ +DEFN_BIN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,fnc,const sc_signed&) \ +DEFN_BIN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op,fnc) +#endif + +#define DEFN_BIN_OP(op,fnc) \ +inline \ +const sc_fxval \ +operator op ( const sc_fxval& a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) ); \ +} \ + \ +DEFN_BIN_OP_T(op,fnc,int) \ +DEFN_BIN_OP_T(op,fnc,unsigned int) \ +DEFN_BIN_OP_T(op,fnc,long) \ +DEFN_BIN_OP_T(op,fnc,unsigned long) \ +DEFN_BIN_OP_T(op,fnc,float) \ +DEFN_BIN_OP_T(op,fnc,double) \ +DEFN_BIN_OP_T(op,fnc,const char*) \ +DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_BIN_OP_OTHER(op,fnc) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +// don't use macro +//DEFN_BIN_OP(/,div) +inline +const sc_fxval +operator / ( const sc_fxval& a, const sc_fxval& b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + SC_FXVAL_OBSERVER_READ_( b ) + return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) ); +} + +DEFN_BIN_OP_T(/,div,int) +DEFN_BIN_OP_T(/,div,unsigned int) +DEFN_BIN_OP_T(/,div,long) +DEFN_BIN_OP_T(/,div,unsigned long) +DEFN_BIN_OP_T(/,div,float) +DEFN_BIN_OP_T(/,div,double) +DEFN_BIN_OP_T(/,div,const char*) +DEFN_BIN_OP_T(/,div,const sc_fxval_fast&) +//DEFN_BIN_OP_OTHER(/,div) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,div,int64) \ +DEFN_BIN_OP_T(/,div,uint64) \ +DEFN_BIN_OP_T(/,div,const sc_int_base&) \ +DEFN_BIN_OP_T(/,div,const sc_uint_base&) \ +DEFN_BIN_OP_T(/,div,const sc_signed&) \ +DEFN_BIN_OP_T(/,div,const sc_unsigned&) +#endif + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval +operator << ( const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) ); +} + +inline +const sc_fxval +operator >> ( const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,tp) \ +inline \ +void \ +fnc ( sc_fxval& c, const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval& c, tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc) \ +DEFN_BIN_FNC_T(fnc,int64) \ +DEFN_BIN_FNC_T(fnc,uint64) \ +DEFN_BIN_FNC_T(fnc,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc) +#endif + +#define DEFN_BIN_FNC(fnc) \ +inline \ +void \ +fnc( sc_fxval& c, const sc_fxval& a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + delete c.m_rep; \ + c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ); \ + SC_FXVAL_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,int) \ +DEFN_BIN_FNC_T(fnc,unsigned int) \ +DEFN_BIN_FNC_T(fnc,long) \ +DEFN_BIN_FNC_T(fnc,unsigned long) \ +DEFN_BIN_FNC_T(fnc,float) \ +DEFN_BIN_FNC_T(fnc,double) \ +DEFN_BIN_FNC_T(fnc,const char*) \ +DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&) \ +DEFN_BIN_FNC_OTHER(fnc) + +DEFN_BIN_FNC(mult) +DEFN_BIN_FNC(div) +DEFN_BIN_FNC(add) +DEFN_BIN_FNC(sub) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval& c, const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxval& c, const sc_fxval& a, int b ) +{ + SC_FXVAL_OBSERVER_READ_( a ) + delete c.m_rep; + c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b ); + SC_FXVAL_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,ret,tp) \ +inline \ +bool \ +operator op ( const sc_fxval& a, tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + sc_fxval tmp( b ); \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep ); \ + return ( ret ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( b ) \ + sc_fxval tmp( a ); \ + int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep ); \ + return ( ret ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op,ret) \ +DEFN_REL_OP_T(op,ret,int64) \ +DEFN_REL_OP_T(op,ret,uint64) \ +DEFN_REL_OP_T(op,ret,const sc_int_base&) \ +DEFN_REL_OP_T(op,ret,const sc_uint_base&) \ +DEFN_REL_OP_T(op,ret,const sc_signed&) \ +DEFN_REL_OP_T(op,ret,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op,ret) +#endif + +#define DEFN_REL_OP(op,ret) \ +inline \ +bool \ +operator op ( const sc_fxval& a, const sc_fxval& b) \ +{ \ + SC_FXVAL_OBSERVER_READ_( a ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep ); \ + return ( ret ); \ +} \ + \ +DEFN_REL_OP_T(op,ret,int) \ +DEFN_REL_OP_T(op,ret,unsigned int) \ +DEFN_REL_OP_T(op,ret,long) \ +DEFN_REL_OP_T(op,ret,unsigned long) \ +DEFN_REL_OP_T(op,ret,float) \ +DEFN_REL_OP_T(op,ret,double) \ +DEFN_REL_OP_T(op,ret,const char*) \ +DEFN_REL_OP_T(op,ret,const sc_fxval_fast&) \ +DEFN_REL_OP_OTHER(op,ret) + +DEFN_REL_OP(<,result < 0) +DEFN_REL_OP(<=,result <= 0) +DEFN_REL_OP(>,result > 0 && result != 2) +DEFN_REL_OP(>=,result >= 0 && result != 2) +DEFN_REL_OP(==,result == 0) +DEFN_REL_OP(!=,result != 0) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval& +sc_fxval::operator = ( const sc_fxval& a ) +{ + if( &a != this ) + { + SC_FXVAL_OBSERVER_READ_( a ) + *m_rep = *a.m_rep; + SC_FXVAL_OBSERVER_WRITE_( *this ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator = ( tp b ) \ +{ \ + sc_fxval tmp( b ); \ + *m_rep = *tmp.m_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,fnc,tp) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( tp b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + sc_fxval tmp( b ); \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op,fnc) \ +DEFN_ASN_OP_T(op,fnc,int64) \ +DEFN_ASN_OP_T(op,fnc,uint64) \ +DEFN_ASN_OP_T(op,fnc,const sc_int_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,fnc,const sc_signed&) \ +DEFN_ASN_OP_T(op,fnc,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op,fnc) +#endif + +#define DEFN_ASN_OP(op,fnc) \ +inline \ +sc_fxval& \ +sc_fxval::operator op ( const sc_fxval& b ) \ +{ \ + SC_FXVAL_OBSERVER_READ_( *this ) \ + SC_FXVAL_OBSERVER_READ_( b ) \ + scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep ); \ + delete m_rep; \ + m_rep = new_rep; \ + SC_FXVAL_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,fnc,int) \ +DEFN_ASN_OP_T(op,fnc,unsigned int) \ +DEFN_ASN_OP_T(op,fnc,long) \ +DEFN_ASN_OP_T(op,fnc,unsigned long) \ +DEFN_ASN_OP_T(op,fnc,float) \ +DEFN_ASN_OP_T(op,fnc,double) \ +DEFN_ASN_OP_T(op,fnc,const char*) \ +DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&) \ +DEFN_ASN_OP_OTHER(op,fnc) + +DEFN_ASN_OP(*=,mult) +DEFN_ASN_OP(/=,div) +DEFN_ASN_OP(+=,add) +DEFN_ASN_OP(-=,sub) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxval& +sc_fxval::operator <<= ( int b ) +{ + SC_FXVAL_OBSERVER_READ_( *this ) + m_rep->lshift( b ); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval& +sc_fxval::operator >>= ( int b ) +{ + SC_FXVAL_OBSERVER_READ_( *this ) + m_rep->rshift( b ); + SC_FXVAL_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_fxval::operator ++ ( int ) +{ + sc_fxval c = *this; + (*this) += 1; + return c; +} + +inline +const sc_fxval +sc_fxval::operator -- ( int ) +{ + sc_fxval c = *this; + (*this) -= 1; + return c; +} + +inline +sc_fxval& +sc_fxval::operator ++ () +{ + (*this) += 1; + return *this; +} + +inline +sc_fxval& +sc_fxval::operator -- () +{ + (*this) -= 1; + return *this; +} + + +// implicit conversion + +inline +sc_fxval::operator double() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// explicit conversion to primitive types + +inline +short +sc_fxval::to_short() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<short>( m_rep->to_double() ); +} + +inline +unsigned short +sc_fxval::to_ushort() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_rep->to_double() ); +} + +inline +int +sc_fxval::to_int() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<int>( m_rep->to_double() ); +} + +inline +int64 +sc_fxval::to_int64() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<int64>( m_rep->to_double() ); +} + +inline +uint64 +sc_fxval::to_uint64() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_rep->to_double() ); +} + +inline +long +sc_fxval::to_long() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<long>( m_rep->to_double() ); +} + +inline +unsigned int +sc_fxval::to_uint() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_rep->to_double() ); +} + +inline +unsigned long +sc_fxval::to_ulong() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_rep->to_double() ); +} + +inline +float +sc_fxval::to_float() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return static_cast<float>( m_rep->to_double() ); +} + +inline +double +sc_fxval::to_double() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->to_double(); +} + + +// query value + +inline +bool +sc_fxval::is_neg() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_neg(); +} + +inline +bool +sc_fxval::is_zero() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_zero(); +} + +inline +bool +sc_fxval::is_nan() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_nan(); +} + +inline +bool +sc_fxval::is_inf() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_inf(); +} + +inline +bool +sc_fxval::is_normal() const +{ + SC_FXVAL_OBSERVER_READ_( *this ) + return m_rep->is_normal(); +} + + +inline +bool +sc_fxval::rounding_flag() const +{ + return m_rep->rounding_flag(); +} + + +// internal use only; +inline +bool +sc_fxval::get_bit( int i ) const +{ + return m_rep->get_bit( i ); +} + + +// protected methods and friend functions + +inline +void +sc_fxval::get_type( int& wl, int& iwl, sc_enc& enc ) const +{ + m_rep->get_type( wl, iwl, enc ); +} + + +inline +const sc_fxval +sc_fxval::quantization( const scfx_params& params, bool& q_flag ) const +{ + return sc_fxval( sc_dt::quantization_scfx_rep( *m_rep, params, q_flag ) ); +} + +inline +const sc_fxval +sc_fxval::overflow( const scfx_params& params, bool& o_flag ) const +{ + return sc_fxval( sc_dt::overflow_scfx_rep( *m_rep, params, o_flag ) ); +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxval& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxval& a ) +{ + a.scan( is ); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast +// +// Fixed-point value type; limited precision. +// ---------------------------------------------------------------------------- + +// protected method + +inline +sc_fxval_fast_observer* +sc_fxval_fast::observer() const +{ + return m_observer; +} + + +// public constructors + +inline +sc_fxval_fast::sc_fxval_fast( sc_fxval_fast_observer* observer_ ) +: m_val( 0.0 ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) +} + +inline +sc_fxval_fast::sc_fxval_fast( const sc_fxval_fast& a, + sc_fxval_fast_observer* observer_ ) +: m_val( a.m_val ), + m_observer( observer_ ) +{ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + +#define DEFN_CTOR_T(tp,arg) \ +inline \ +sc_fxval_fast::sc_fxval_fast( tp a, \ + sc_fxval_fast_observer* observer_ ) \ +: m_val( arg ), \ + m_observer( observer_ ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_DEFAULT_ \ + SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this ) \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ +} + +#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a )) +#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,from_string( a )) +#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double()) + +DEFN_CTOR_T_A(int) +DEFN_CTOR_T_A(unsigned int) +DEFN_CTOR_T_A(long) +DEFN_CTOR_T_A(unsigned long) +DEFN_CTOR_T_A(float) +DEFN_CTOR_T_A(double) +DEFN_CTOR_T_B(const char*) +DEFN_CTOR_T_C(const sc_fxval&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTOR_T_A(int64) +DEFN_CTOR_T_A(uint64) +DEFN_CTOR_T_C(const sc_int_base&) +DEFN_CTOR_T_C(const sc_uint_base&) +DEFN_CTOR_T_C(const sc_signed&) +DEFN_CTOR_T_C(const sc_unsigned&) +#endif + +#undef DEFN_CTOR_T +#undef DEFN_CTOR_T_A +#undef DEFN_CTOR_T_B +#undef DEFN_CTOR_T_C +#undef DEFN_CTOR_T_D +#undef DEFN_CTOR_T_E + + +inline +sc_fxval_fast::~sc_fxval_fast() +{ + SC_FXVAL_FAST_OBSERVER_DESTRUCT_( *this ) +} + + +// internal use only; +inline +double +sc_fxval_fast::get_val() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + +// internal use only; +inline +void +sc_fxval_fast::set_val( double val_ ) +{ + m_val = val_; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) +} + + +// unary operators + +inline +const sc_fxval_fast +sc_fxval_fast::operator - () const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return sc_fxval_fast( - m_val ); +} + +inline +const sc_fxval_fast& +sc_fxval_fast::operator + () const +{ + // SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return *this; +} + + +// unary functions + +inline +void +neg( sc_fxval_fast& c, const sc_fxval_fast& a ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = - a.m_val; + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + + +// binary operators + +#define DEFN_BIN_OP_T(op,tp) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return sc_fxval_fast( a.m_val op tmp.m_val ); \ +} \ + \ +inline \ +const sc_fxval_fast \ +operator op ( tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return sc_fxval_fast( tmp.m_val op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_OP_OTHER(op) \ +DEFN_BIN_OP_T(op,int64) \ +DEFN_BIN_OP_T(op,uint64) \ +DEFN_BIN_OP_T(op,const sc_int_base&) \ +DEFN_BIN_OP_T(op,const sc_uint_base&) \ +DEFN_BIN_OP_T(op,const sc_signed&) \ +DEFN_BIN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_BIN_OP_OTHER(op) +#endif + +#define DEFN_BIN_OP(op,dummy) \ +inline \ +const sc_fxval_fast \ +operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + return sc_fxval_fast( a.m_val op b.m_val ); \ +} \ + \ +DEFN_BIN_OP_T(op,int) \ +DEFN_BIN_OP_T(op,unsigned int) \ +DEFN_BIN_OP_T(op,long) \ +DEFN_BIN_OP_T(op,unsigned long) \ +DEFN_BIN_OP_T(op,float) \ +DEFN_BIN_OP_T(op,double) \ +DEFN_BIN_OP_T(op,const char*) \ +DEFN_BIN_OP_OTHER(op) + +DEFN_BIN_OP(*,mult) +DEFN_BIN_OP(+,add) +DEFN_BIN_OP(-,sub) +//DEFN_BIN_OP(/,div) +inline +const sc_fxval_fast +operator / ( const sc_fxval_fast& a, const sc_fxval_fast& b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + SC_FXVAL_FAST_OBSERVER_READ_( b ) + return sc_fxval_fast( a.m_val / b.m_val ); +} + +DEFN_BIN_OP_T(/,int) +DEFN_BIN_OP_T(/,unsigned int) +DEFN_BIN_OP_T(/,long) +DEFN_BIN_OP_T(/,unsigned long) +DEFN_BIN_OP_T(/,float) +DEFN_BIN_OP_T(/,double) +DEFN_BIN_OP_T(/,const char*) +//DEFN_BIN_OP_OTHER(/) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_BIN_OP_T(/,int64) +DEFN_BIN_OP_T(/,uint64) +DEFN_BIN_OP_T(/,const sc_int_base&) +DEFN_BIN_OP_T(/,const sc_uint_base&) +DEFN_BIN_OP_T(/,const sc_signed&) +DEFN_BIN_OP_T(/,const sc_unsigned&) +#endif + + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP_OTHER +#undef DEFN_BIN_OP + + +inline +const sc_fxval_fast +operator << ( const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( b ) ); +} + +inline +const sc_fxval_fast +operator >> ( const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + return sc_fxval_fast( a.m_val * scfx_pow2( -b ) ); +} + + +// binary functions + +#define DEFN_BIN_FNC_T(fnc,op,tp) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + c.m_val = a.m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +inline \ +void \ +fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + c.m_val = tmp.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_BIN_FNC_OTHER(fnc,op) \ +DEFN_BIN_FNC_T(fnc,op,int64) \ +DEFN_BIN_FNC_T(fnc,op,uint64) \ +DEFN_BIN_FNC_T(fnc,op,const sc_int_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_signed&) \ +DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&) +#else +#define DEFN_BIN_FNC_OTHER(fnc,op) +#endif + +#define DEFN_BIN_FNC(fnc,op) \ +inline \ +void \ +fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + c.m_val = a.m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) \ +} \ + \ +DEFN_BIN_FNC_T(fnc,op,int) \ +DEFN_BIN_FNC_T(fnc,op,unsigned int) \ +DEFN_BIN_FNC_T(fnc,op,long) \ +DEFN_BIN_FNC_T(fnc,op,unsigned long) \ +DEFN_BIN_FNC_T(fnc,op,float) \ +DEFN_BIN_FNC_T(fnc,op,double) \ +DEFN_BIN_FNC_T(fnc,op,const char*) \ +DEFN_BIN_FNC_OTHER(fnc,op) + +DEFN_BIN_FNC(mult,*) +DEFN_BIN_FNC(div,/) +DEFN_BIN_FNC(add,+) +DEFN_BIN_FNC(sub,-) + +#undef DEFN_BIN_FNC_T +#undef DEFN_BIN_FNC_OTHER +#undef DEFN_BIN_FNC + + +inline +void +lshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + +inline +void +rshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( a ) + c.m_val = a.m_val * scfx_pow2( -b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( c ) +} + + +// relational (including equality) operators + +#define DEFN_REL_OP_T(op,tp) \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + sc_fxval_fast tmp( b ); \ + return ( a.m_val op tmp.m_val ); \ +} \ + \ +inline \ +bool \ +operator op ( tp a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + sc_fxval_fast tmp( a ); \ + return ( tmp.m_val op b.m_val ); \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_REL_OP_OTHER(op) \ +DEFN_REL_OP_T(op,int64) \ +DEFN_REL_OP_T(op,uint64) \ +DEFN_REL_OP_T(op,const sc_int_base&) \ +DEFN_REL_OP_T(op,const sc_uint_base&) \ +DEFN_REL_OP_T(op,const sc_signed&) \ +DEFN_REL_OP_T(op,const sc_unsigned&) +#else +#define DEFN_REL_OP_OTHER(op) +#endif + +#define DEFN_REL_OP(op) \ +inline \ +bool \ +operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( a ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + return ( a.m_val op b.m_val ); \ +} \ + \ +DEFN_REL_OP_T(op,int) \ +DEFN_REL_OP_T(op,unsigned int) \ +DEFN_REL_OP_T(op,long) \ +DEFN_REL_OP_T(op,unsigned long) \ +DEFN_REL_OP_T(op,float) \ +DEFN_REL_OP_T(op,double) \ +DEFN_REL_OP_T(op,const char*) \ +DEFN_REL_OP_OTHER(op) + +DEFN_REL_OP(<) +DEFN_REL_OP(<=) +DEFN_REL_OP(>) +DEFN_REL_OP(>=) +DEFN_REL_OP(==) +DEFN_REL_OP(!=) + +#undef DEFN_REL_OP_T +#undef DEFN_REL_OP_OTHER +#undef DEFN_REL_OP + + +// assignment operators + +inline +sc_fxval_fast& +sc_fxval_fast::operator = ( const sc_fxval_fast& a ) +{ + if( &a != this ) + { + SC_FXVAL_FAST_OBSERVER_READ_( a ) + m_val = a.m_val; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + } + return *this; +} + +#define DEFN_ASN_OP_T(tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator = ( tp a ) \ +{ \ + sc_fxval_fast tmp( a ); \ + m_val = tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(int) +DEFN_ASN_OP_T(unsigned int) +DEFN_ASN_OP_T(long) +DEFN_ASN_OP_T(unsigned long) +DEFN_ASN_OP_T(float) +DEFN_ASN_OP_T(double) +DEFN_ASN_OP_T(const char*) +DEFN_ASN_OP_T(const sc_fxval&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_ASN_OP_T(int64) +DEFN_ASN_OP_T(uint64) +DEFN_ASN_OP_T(const sc_int_base&) +DEFN_ASN_OP_T(const sc_uint_base&) +DEFN_ASN_OP_T(const sc_signed&) +DEFN_ASN_OP_T(const sc_unsigned&) +#endif + +#undef DEFN_ASN_OP_T + + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( tp b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + sc_fxval_fast tmp( b ); \ + m_val op tmp.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +inline \ +sc_fxval_fast& \ +sc_fxval_fast::operator op ( const sc_fxval_fast& b ) \ +{ \ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) \ + SC_FXVAL_FAST_OBSERVER_READ_( b ) \ + m_val op b.m_val; \ + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} \ + \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +inline +sc_fxval_fast& +sc_fxval_fast::operator <<= ( int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator >>= ( int b ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val *= scfx_pow2( -b ); + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_fxval_fast::operator ++ ( int ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val + 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +const sc_fxval_fast +sc_fxval_fast::operator -- ( int ) +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + double c = m_val; + m_val = m_val - 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return sc_fxval_fast( c ); +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator ++ () +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val = m_val + 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + +inline +sc_fxval_fast& +sc_fxval_fast::operator -- () +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + m_val = m_val - 1; + SC_FXVAL_FAST_OBSERVER_WRITE_( *this ) + return *this; +} + + +// implicit conversion + +inline +sc_fxval_fast::operator double() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// explicit conversion to primitive types + +inline +short +sc_fxval_fast::to_short() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<short>( m_val ); +} + +inline +unsigned short +sc_fxval_fast::to_ushort() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned short>( m_val ); +} + +inline +int64 +sc_fxval_fast::to_int64() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<int64>( m_val ); +} + +inline +int +sc_fxval_fast::to_int() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<int>( m_val ); +} + +inline +unsigned int +sc_fxval_fast::to_uint() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned int>( m_val ); +} + +inline +uint64 +sc_fxval_fast::to_uint64() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<uint64>( m_val ); +} + +inline +long +sc_fxval_fast::to_long() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<long>( m_val ); +} + +inline +unsigned long +sc_fxval_fast::to_ulong() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<unsigned long>( m_val ); +} + +inline +float +sc_fxval_fast::to_float() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return static_cast<float>( m_val ); +} + +inline +double +sc_fxval_fast::to_double() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + return m_val; +} + + +// query value + +inline +bool +sc_fxval_fast::is_neg() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.negative() != 0 ); +} + +inline +bool +sc_fxval_fast::is_zero() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_zero(); +} + +inline +bool +sc_fxval_fast::is_nan() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_nan(); +} + +inline +bool +sc_fxval_fast::is_inf() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return id.is_inf(); +} + +inline +bool +sc_fxval_fast::is_normal() const +{ + SC_FXVAL_FAST_OBSERVER_READ_( *this ) + scfx_ieee_double id( m_val ); + return ( id.is_normal() || id.is_subnormal() || id.is_zero() ); +} + + +inline +bool +sc_fxval_fast::rounding_flag() const +{ + // does not apply to sc_fxval_fast; included for API compatibility + return false; +} + + +inline +::std::ostream& +operator << ( ::std::ostream& os, const sc_fxval_fast& a ) +{ + a.print( os ); + return os; +} + +inline +::std::istream& +operator >> ( ::std::istream& is, sc_fxval_fast& a ) +{ + a.scan( is ); + return is; +} + +} // namespace sc_dt + +#undef SCFX_EXPLICIT_ +#undef SCFX_EXPLICIT_OTHER_ + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp new file mode 100644 index 000000000..ae651cc14 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.cpp @@ -0,0 +1,76 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval_observer.cpp - + + Original Author: 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: sc_fxval_observer.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/sc_fxval_observer.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +sc_fxval_observer* (*sc_fxval_observer::default_observer) () = 0; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +sc_fxval_fast_observer* (*sc_fxval_fast_observer::default_observer) () = 0; + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h new file mode 100644 index 000000000..e34d85c1b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_fxval_observer.h @@ -0,0 +1,223 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_fxval_observer.h - + + Original Author: 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: sc_fxval_observer.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_FXVAL_OBSERVER_H +#define SC_FXVAL_OBSERVER_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_fxval_observer; +class sc_fxval_fast_observer; + +// forward class declarations +class sc_fxval; +class sc_fxval_fast; + + +#ifdef SC_ENABLE_OBSERVERS + +#define SC_FXVAL_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,construct) +#define SC_FXVAL_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,destruct) +#define SC_FXVAL_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,read) +#define SC_FXVAL_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxval_observer*,write) +#define SC_FXVAL_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxval_observer) + +#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,construct) +#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,destruct) +#define SC_FXVAL_FAST_OBSERVER_READ_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,read) +#define SC_FXVAL_FAST_OBSERVER_WRITE_(object) \ + SC_OBSERVER_(object,sc_fxval_fast_observer*,write) +#define SC_FXVAL_FAST_OBSERVER_DEFAULT_ \ + SC_OBSERVER_DEFAULT_(sc_fxval_fast_observer) + +#else + +#define SC_FXVAL_OBSERVER_CONSTRUCT_(object) +#define SC_FXVAL_OBSERVER_DESTRUCT_(object) +#define SC_FXVAL_OBSERVER_READ_(object) +#define SC_FXVAL_OBSERVER_WRITE_(object) +#define SC_FXVAL_OBSERVER_DEFAULT_ + +#define SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(object) +#define SC_FXVAL_FAST_OBSERVER_DESTRUCT_(object) +#define SC_FXVAL_FAST_OBSERVER_READ_(object) +#define SC_FXVAL_FAST_OBSERVER_WRITE_(object) +#define SC_FXVAL_FAST_OBSERVER_DEFAULT_ + +#endif + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_observer +{ + +protected: + + sc_fxval_observer() {} + virtual ~sc_fxval_observer() {} + +public: + + virtual void construct( const sc_fxval& ); + virtual void destruct( const sc_fxval& ); + virtual void read( const sc_fxval& ); + virtual void write( const sc_fxval& ); + + static sc_fxval_observer* (*default_observer) (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +class sc_fxval_fast_observer +{ + +protected: + + sc_fxval_fast_observer() {} + virtual ~sc_fxval_fast_observer() {} + +public: + + virtual void construct( const sc_fxval_fast& ); + virtual void destruct( const sc_fxval_fast& ); + virtual void read( const sc_fxval_fast& ); + virtual void write( const sc_fxval_fast& ); + + static sc_fxval_fast_observer* (*default_observer) (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_observer +// +// Abstract base class for fixed-point value type observers; +// arbitrary precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxval_observer::construct( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::destruct( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::read( const sc_fxval& ) +{} + +inline +void +sc_fxval_observer::write( const sc_fxval& ) +{} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_fxval_fast_observer +// +// Abstract base class for fixed-point value type observers; +// limited precision. +// ---------------------------------------------------------------------------- + +inline +void +sc_fxval_fast_observer::construct( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::destruct( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::read( const sc_fxval_fast& ) +{} + +inline +void +sc_fxval_fast_observer::write( const sc_fxval_fast& ) +{} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h new file mode 100644 index 000000000..b8d9acaa1 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufix.h @@ -0,0 +1,1941 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_ufix.h - + + Original Author: 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: sc_ufix.h,v $ +// Revision 1.2 2011/01/20 22:52:30 acg +// Andy Goodrich: Add float constructors. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_UFIX_H +#define SC_UFIX_H + + +#include "sysc/datatypes/fx/sc_fxnum.h" + + +namespace sc_dt +{ + +// classes defined in this module +class sc_ufix; +class sc_ufix_fast; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix +// +// "Unconstrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +class sc_ufix : public sc_fxnum +{ + +public: + + // constructors + + explicit sc_ufix( sc_fxnum_observer* = 0 ); + sc_ufix( int, int, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_observer* = 0 ); + explicit sc_ufix( const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + sc_ufix( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + explicit sc_ufix( const sc_fxtype_params&, + sc_fxnum_observer* = 0 ); + sc_ufix( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_ufix( tp, \ + int, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_observer* = 0 ); \ + sc_ufix( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufix( tp, \ + sc_fxnum_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufix( const sc_ufix& ); + + + // unary bitwise operators + + const sc_ufix operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_ufix&, const sc_ufix& ); + + + // binary bitwise operators + + friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator & ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator & ( const sc_ufix_fast&, const sc_ufix& ); + friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator | ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator | ( const sc_ufix_fast&, const sc_ufix& ); + friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix& ); + friend const sc_ufix operator ^ ( const sc_ufix&, const sc_ufix_fast& ); + friend const sc_ufix operator ^ ( const sc_ufix_fast&, const sc_ufix& ); + + + // binary bitwise functions + + friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_and( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_and( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_or ( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_or ( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix& ); + friend void b_xor( sc_ufix&, const sc_ufix&, const sc_ufix_fast& ); + friend void b_xor( sc_ufix&, const sc_ufix_fast&, const sc_ufix& ); + + + // assignment operators + + sc_ufix& operator = ( const sc_ufix& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufix& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_ufix& operator ++ (); + sc_ufix& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix_fast +// +// "Unconstrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +class sc_ufix_fast : public sc_fxnum_fast +{ + +public: + + // constructors + + explicit sc_ufix_fast( sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int, + sc_fxnum_fast_observer* = 0 ); + explicit sc_ufix_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( int, int, sc_q_mode, sc_o_mode, int, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + explicit sc_ufix_fast( const sc_fxtype_params&, + sc_fxnum_fast_observer* = 0 ); + sc_ufix_fast( const sc_fxtype_params&, + const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T(tp) \ + sc_ufix_fast( tp, \ + int, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + int, int, sc_q_mode, sc_o_mode, int, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxtype_params&, \ + sc_fxnum_fast_observer* = 0 ); \ + sc_ufix_fast( tp, \ + const sc_fxtype_params&, \ + const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufix_fast( tp, \ + sc_fxnum_fast_observer* = 0 ); \ + DECL_CTORS_T(tp) + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufix_fast( const sc_ufix_fast& ); + + + // unary bitwise operators + + const sc_ufix_fast operator ~ () const; + + + // unary bitwise functions + + friend void b_not( sc_ufix_fast&, const sc_ufix_fast& ); + + + // binary bitwise operators + + friend const sc_ufix_fast operator & ( const sc_ufix_fast&, + const sc_ufix_fast& ); + friend const sc_ufix_fast operator ^ ( const sc_ufix_fast&, + const sc_ufix_fast& ); + friend const sc_ufix_fast operator | ( const sc_ufix_fast&, + const sc_ufix_fast& ); + + + // binary bitwise functions + + friend void b_and( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + friend void b_or ( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + friend void b_xor( sc_ufix_fast&, const sc_ufix_fast&, + const sc_ufix_fast& ); + + + // assignment operators + + sc_ufix_fast& operator = ( const sc_ufix_fast& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufix_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_ufix_fast& operator ++ (); + sc_ufix_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix +// +// "Unconstrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_ufix::sc_ufix( sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params(), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxtype_params& type_params, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix::sc_ufix( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_fxnum( type_params, + SC_US_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + a.type_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix::sc_ufix( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_fxnum( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_ufix::sc_ufix( const sc_ufix& a ) +: sc_fxnum( a, + a.type_params(), + SC_US_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_ufix +sc_ufix::operator ~ () const +{ + SC_FXNUM_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_ufix c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_ufix( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_ufix& c, const sc_ufix& a ) +{ + SC_FXNUM_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_ufix \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_ufix c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_ufix( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(&,&&,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix) + +DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(|,||,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix) + +DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix) +DEFN_BIN_OP_T(^,!=,sc_ufix,sc_ufix_fast) +DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_ufix& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_and,&&,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix) + +DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_or,||,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix) + +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix,sc_ufix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_ufix& +sc_ufix::operator = ( const sc_ufix& a ) +{ + sc_fxnum::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_ufix& \ +sc_ufix::operator op ( tp a ) \ +{ \ + sc_fxnum::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_ufix& \ +sc_ufix::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_ufix) +DEFN_ASN_OP_T(&=,&&,sc_ufix_fast) +DEFN_ASN_OP_T(|=,||,sc_ufix) +DEFN_ASN_OP_T(|=,||,sc_ufix_fast) +DEFN_ASN_OP_T(^=,!=,sc_ufix) +DEFN_ASN_OP_T(^=,!=,sc_ufix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval +sc_ufix::operator ++ ( int ) +{ + return sc_fxval( sc_fxnum::operator ++ ( 0 ) ); +} + +inline +const sc_fxval +sc_ufix::operator -- ( int ) +{ + return sc_fxval( sc_fxnum::operator -- ( 0 ) ); +} + +inline +sc_ufix& +sc_ufix::operator ++ () +{ + sc_fxnum::operator ++ (); + return *this; +} + +inline +sc_ufix& +sc_ufix::operator -- () +{ + sc_fxnum::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_ufix_fast +// +// "Unconstrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +// constructors + +inline +sc_ufix_fast::sc_ufix_fast( sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params(), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_ ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( int wl_, int iwl_, + sc_q_mode qm, sc_o_mode om, int nb, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( sc_fxtype_params( wl_, iwl_, qm, om, nb ), + SC_US_, + cast_sw, + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_US_, + sc_fxcast_switch(), + observer_ ) +{} + +inline +sc_ufix_fast::sc_ufix_fast( const sc_fxtype_params& type_params, + const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_fxnum_fast( type_params, + SC_US_, + cast_sw, + observer_ ) +{} + +#define DEFN_CTORS_T_A(tp) \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +#define DEFN_CTORS_T_B(tp) \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + a.type_params(), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), wl_, iwl_ ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( a.type_params(), qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, sc_q_mode qm, sc_o_mode om, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + int wl_, int iwl_, \ + sc_q_mode qm, sc_o_mode om, int nb, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + sc_fxtype_params( wl_, iwl_, qm, om, nb ), \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + sc_fxcast_switch(), \ + observer_ ) \ +{} \ + \ +inline \ +sc_ufix_fast::sc_ufix_fast( tp a, \ + const sc_fxtype_params& type_params, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ ) \ +: sc_fxnum_fast( a, \ + type_params, \ + SC_US_, \ + cast_sw, \ + observer_ ) \ +{} + +DEFN_CTORS_T_A(int) +DEFN_CTORS_T_A(unsigned int) +DEFN_CTORS_T_A(long) +DEFN_CTORS_T_A(unsigned long) +DEFN_CTORS_T_A(float) +DEFN_CTORS_T_A(double) +DEFN_CTORS_T_A(const char*) +DEFN_CTORS_T_A(const sc_fxval&) +DEFN_CTORS_T_A(const sc_fxval_fast&) +DEFN_CTORS_T_B(const sc_fxnum&) +DEFN_CTORS_T_B(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T_A(int64) +DEFN_CTORS_T_A(uint64) +DEFN_CTORS_T_A(const sc_int_base&) +DEFN_CTORS_T_A(const sc_uint_base&) +DEFN_CTORS_T_A(const sc_signed&) +DEFN_CTORS_T_A(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T_A +#undef DEFN_CTORS_T_B + +// copy constructor + +inline +sc_ufix_fast::sc_ufix_fast( const sc_ufix_fast& a ) +: sc_fxnum_fast( a, + a.type_params(), + SC_US_, + sc_fxcast_switch(), + 0 ) +{} + + +// unary bitwise operators + +inline +const sc_ufix_fast +sc_ufix_fast::operator ~ () const +{ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) + int iwl_c = iwl(); + int wl_c = wl(); + sc_ufix_fast c( wl_c, iwl_c ); + for( int i = iwl_c - wl_c; i < iwl_c; ++ i ) + c.set_bit( i, ! get_bit( i ) ); + return sc_ufix_fast( c, wl_c, iwl_c ); +} + + +// unary bitwise functions + +inline +void +b_not( sc_ufix_fast& c, const sc_ufix_fast& a ) +{ + SC_FXNUM_FAST_OBSERVER_READ_( a ) + int iwl_c = c.iwl(); + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) + c.set_bit( i, ! a.get_bit( i ) ); + c.cast(); + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) +} + + +// binary bitwise operators + +#define DEFN_BIN_OP_T(op,op2,tp1,tp2) \ +inline \ +const sc_ufix_fast \ +operator op ( const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_a = a.iwl(); \ + int iwl_b = b.iwl(); \ + int iwl_c = sc_max( iwl_a, iwl_b ); \ + int fwl_c = sc_max( a.wl() - iwl_a, b.wl() - iwl_b ); \ + sc_ufix_fast c( iwl_c + fwl_c, iwl_c ); \ + for( int i = -fwl_c; i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + return sc_ufix_fast( c, iwl_c + fwl_c, iwl_c ); \ +} + +DEFN_BIN_OP_T(&,&&,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_OP_T(|,||,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_OP_T(^,!=,sc_ufix_fast,sc_ufix_fast) + +#undef DEFN_BIN_OP_T + + +// binary bitwise functions + +#define DEFN_BIN_FNC_T(fnc,op2,tp1,tp2) \ +inline \ +void \ +fnc ( sc_ufix_fast& c, const tp1& a, const tp2& b ) \ +{ \ + a.observer_read(); \ + b.observer_read(); \ + int iwl_c = c.iwl(); \ + for( int i = iwl_c - c.wl(); i < iwl_c; ++ i ) \ + c.set_bit( i, a.get_bit( i ) op2 b.get_bit( i ) ); \ + c.cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( c ) \ +} + +DEFN_BIN_FNC_T(b_and,&&,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_FNC_T(b_or,||,sc_ufix_fast,sc_ufix_fast) +DEFN_BIN_FNC_T(b_xor,!=,sc_ufix_fast,sc_ufix_fast) + +#undef DEFN_BIN_FNC_T + + +// assignment operators + +inline +sc_ufix_fast& +sc_ufix_fast::operator = ( const sc_ufix_fast& a ) +{ + sc_fxnum_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +inline \ +sc_ufix_fast& \ +sc_ufix_fast::operator op ( tp a ) \ +{ \ + sc_fxnum_fast::operator op( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +#define DEFN_ASN_OP_T(op,op2,tp) \ +inline \ +sc_ufix_fast& \ +sc_ufix_fast::operator op ( const tp& b ) \ +{ \ + SC_FXNUM_FAST_OBSERVER_READ_( *this ) \ + b.observer_read(); \ + int iwl_c = iwl(); \ + for( int i = iwl_c - wl(); i < iwl_c; ++ i ) \ + set_bit( i, get_bit( i ) op2 b.get_bit( i ) ); \ + cast(); \ + SC_FXNUM_FAST_OBSERVER_WRITE_( *this ) \ + return *this; \ +} + +DEFN_ASN_OP_T(&=,&&,sc_ufix) +DEFN_ASN_OP_T(&=,&&,sc_ufix_fast) +DEFN_ASN_OP_T(|=,||,sc_ufix) +DEFN_ASN_OP_T(|=,||,sc_ufix_fast) +DEFN_ASN_OP_T(^=,!=,sc_ufix) +DEFN_ASN_OP_T(^=,!=,sc_ufix_fast) + +#undef DEFN_ASN_OP_T + + +// auto-increment and auto-decrement + +inline +const sc_fxval_fast +sc_ufix_fast::operator ++ ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator ++ ( 0 ) ); +} + +inline +const sc_fxval_fast +sc_ufix_fast::operator -- ( int ) +{ + return sc_fxval_fast( sc_fxnum_fast::operator -- ( 0 ) ); +} + +inline +sc_ufix_fast& +sc_ufix_fast::operator ++ () +{ + sc_fxnum_fast::operator ++ (); + return *this; +} + +inline +sc_ufix_fast& +sc_ufix_fast::operator -- () +{ + sc_fxnum_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h new file mode 100644 index 000000000..266e4b7bb --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/sc_ufixed.h @@ -0,0 +1,660 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + sc_ufixed.h - + + Original Author: 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: sc_ufixed.h,v $ +// Revision 1.2 2011/01/19 18:57:40 acg +// Andy Goodrich: changes for IEEE_1666_2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SC_UFIXED_H +#define SC_UFIXED_H + + +#include "sysc/datatypes/fx/sc_ufix.h" + + +namespace sc_dt +{ + +// classes defined in this module +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed; +template <int W, int I, sc_q_mode Q, sc_o_mode O, int N> class sc_ufixed_fast; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed +// +// "Constrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_ufixed : public sc_ufix +{ + +public: + + // constructors + + explicit sc_ufixed( sc_fxnum_observer* = 0 ); + explicit sc_ufixed( const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufixed( tp, sc_fxnum_observer* = 0 ); \ + sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufixed( tp, sc_fxnum_observer* = 0 ); \ + sc_ufixed( tp, const sc_fxcast_switch&, sc_fxnum_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufixed( const sc_ufixed<W,I,Q,O,N>& ); + + + // assignment operators + + sc_ufixed& operator = ( const sc_ufixed<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufixed& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval operator ++ ( int ); + const sc_fxval operator -- ( int ); + + sc_ufixed& operator ++ (); + sc_ufixed& operator -- (); + +}; + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed_fast +// +// "Constrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template <int W, int I, + sc_q_mode Q = SC_DEFAULT_Q_MODE_, + sc_o_mode O = SC_DEFAULT_O_MODE_, int N = SC_DEFAULT_N_BITS_> +class sc_ufixed_fast : public sc_ufix_fast +{ + +public: + + // constructors + + explicit sc_ufixed_fast( sc_fxnum_fast_observer* = 0 ); + explicit sc_ufixed_fast( const sc_fxcast_switch&, + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_A(tp) \ + sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_ufixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + +#define DECL_CTORS_T_B(tp) \ + explicit sc_ufixed_fast( tp, sc_fxnum_fast_observer* = 0 ); \ + sc_ufixed_fast( tp, const sc_fxcast_switch&, \ + sc_fxnum_fast_observer* = 0 ); + + DECL_CTORS_T_A(int) + DECL_CTORS_T_A(unsigned int) + DECL_CTORS_T_A(long) + DECL_CTORS_T_A(unsigned long) + DECL_CTORS_T_A(float) + DECL_CTORS_T_A(double) + DECL_CTORS_T_A(const char*) + DECL_CTORS_T_A(const sc_fxval&) + DECL_CTORS_T_A(const sc_fxval_fast&) + DECL_CTORS_T_A(const sc_fxnum&) + DECL_CTORS_T_A(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER + DECL_CTORS_T_B(int64) + DECL_CTORS_T_B(uint64) + DECL_CTORS_T_B(const sc_int_base&) + DECL_CTORS_T_B(const sc_uint_base&) + DECL_CTORS_T_B(const sc_signed&) + DECL_CTORS_T_B(const sc_unsigned&) +#endif + +#undef DECL_CTORS_T_A +#undef DECL_CTORS_T_B + + // copy constructor + + sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& ); + + + // assignment operators + + sc_ufixed_fast& operator = ( const sc_ufixed_fast<W,I,Q,O,N>& ); + +#define DECL_ASN_OP_T(op,tp) \ + sc_ufixed_fast& operator op ( tp ); + +#ifndef SC_FX_EXCLUDE_OTHER +#define DECL_ASN_OP_OTHER(op) \ + DECL_ASN_OP_T(op,int64) \ + DECL_ASN_OP_T(op,uint64) \ + DECL_ASN_OP_T(op,const sc_int_base&) \ + DECL_ASN_OP_T(op,const sc_uint_base&) \ + DECL_ASN_OP_T(op,const sc_signed&) \ + DECL_ASN_OP_T(op,const sc_unsigned&) +#else +#define DECL_ASN_OP_OTHER(op) +#endif + +#define DECL_ASN_OP(op) \ + DECL_ASN_OP_T(op,int) \ + DECL_ASN_OP_T(op,unsigned int) \ + DECL_ASN_OP_T(op,long) \ + DECL_ASN_OP_T(op,unsigned long) \ + DECL_ASN_OP_T(op,float) \ + DECL_ASN_OP_T(op,double) \ + DECL_ASN_OP_T(op,const char*) \ + DECL_ASN_OP_T(op,const sc_fxval&) \ + DECL_ASN_OP_T(op,const sc_fxval_fast&) \ + DECL_ASN_OP_T(op,const sc_fxnum&) \ + DECL_ASN_OP_T(op,const sc_fxnum_fast&) \ + DECL_ASN_OP_OTHER(op) + + DECL_ASN_OP(=) + + DECL_ASN_OP(*=) + DECL_ASN_OP(/=) + DECL_ASN_OP(+=) + DECL_ASN_OP(-=) + + DECL_ASN_OP_T(<<=,int) + DECL_ASN_OP_T(>>=,int) + + DECL_ASN_OP_T(&=,const sc_ufix&) + DECL_ASN_OP_T(&=,const sc_ufix_fast&) + DECL_ASN_OP_T(|=,const sc_ufix&) + DECL_ASN_OP_T(|=,const sc_ufix_fast&) + DECL_ASN_OP_T(^=,const sc_ufix&) + DECL_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DECL_ASN_OP_T +#undef DECL_ASN_OP_OTHER +#undef DECL_ASN_OP + + + // auto-increment and auto-decrement + + const sc_fxval_fast operator ++ ( int ); + const sc_fxval_fast operator -- ( int ); + + sc_ufixed_fast& operator ++ (); + sc_ufixed_fast& operator -- (); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed +// +// "Constrained" unsigned fixed-point class; arbitrary precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( sc_fxnum_observer* observer_ ) +: sc_ufix( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_fxcast_switch& cast_sw, + sc_fxnum_observer* observer_ ) +: sc_ufix( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \ + sc_fxnum_observer* observer_ ) \ +: sc_ufix( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>::sc_ufixed( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_observer* observer_ ) \ +: sc_ufix( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>::sc_ufixed( const sc_ufixed<W,I,Q,O,N>& a ) +: sc_ufix( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator = ( const sc_ufixed<W,I,Q,O,N>& a ) +{ + sc_ufix::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed<W,I,Q,O,N>& \ +sc_ufixed<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_ufix::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_ufix&) +DEFN_ASN_OP_T(&=,const sc_ufix_fast&) +DEFN_ASN_OP_T(|=,const sc_ufix&) +DEFN_ASN_OP_T(|=,const sc_ufix_fast&) +DEFN_ASN_OP_T(^=,const sc_ufix&) +DEFN_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_ufixed<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval( sc_ufix::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval +sc_ufixed<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval( sc_ufix::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator ++ () +{ + sc_ufix::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed<W,I,Q,O,N>& +sc_ufixed<W,I,Q,O,N>::operator -- () +{ + sc_ufix::operator -- (); + return *this; +} + + +// ---------------------------------------------------------------------------- +// TEMPLATE CLASS : sc_ufixed_fast +// +// "Constrained" unsigned fixed-point class; limited precision. +// ---------------------------------------------------------------------------- + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( sc_fxnum_fast_observer* observer_ ) +: sc_ufix_fast( W, I, Q, O, N, observer_ ) +{} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_fxcast_switch& cast_sw, + sc_fxnum_fast_observer* observer_ ) +: sc_ufix_fast( W, I, Q, O, N, cast_sw, observer_ ) +{} + +#define DEFN_CTORS_T(tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \ + sc_fxnum_fast_observer* observer_ )\ +: sc_ufix_fast( a, W, I, Q, O, N, observer_ ) \ +{} \ + \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( tp a, \ + const sc_fxcast_switch& cast_sw, \ + sc_fxnum_fast_observer* observer_ )\ +: sc_ufix_fast( a, W, I, Q, O, N, cast_sw, observer_ ) \ +{} + +DEFN_CTORS_T(int) +DEFN_CTORS_T(unsigned int) +DEFN_CTORS_T(long) +DEFN_CTORS_T(unsigned long) +DEFN_CTORS_T(float) +DEFN_CTORS_T(double) +DEFN_CTORS_T(const char*) +DEFN_CTORS_T(const sc_fxval&) +DEFN_CTORS_T(const sc_fxval_fast&) +DEFN_CTORS_T(const sc_fxnum&) +DEFN_CTORS_T(const sc_fxnum_fast&) +#ifndef SC_FX_EXCLUDE_OTHER +DEFN_CTORS_T(int64) +DEFN_CTORS_T(uint64) +DEFN_CTORS_T(const sc_int_base&) +DEFN_CTORS_T(const sc_uint_base&) +DEFN_CTORS_T(const sc_signed&) +DEFN_CTORS_T(const sc_unsigned&) +#endif + +#undef DEFN_CTORS_T + +// copy constructor + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>::sc_ufixed_fast( const sc_ufixed_fast<W,I,Q,O,N>& a ) +: sc_ufix_fast( a, W, I, Q, O, N ) +{} + + +// assignment operators + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator = ( const sc_ufixed_fast<W,I,Q,O,N>& a ) +{ + sc_ufix_fast::operator = ( a ); + return *this; +} + +#define DEFN_ASN_OP_T(op,tp) \ +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> \ +inline \ +sc_ufixed_fast<W,I,Q,O,N>& \ +sc_ufixed_fast<W,I,Q,O,N>::operator op ( tp a ) \ +{ \ + sc_ufix_fast::operator op ( a ); \ + return *this; \ +} + +#ifndef SC_FX_EXCLUDE_OTHER +#define DEFN_ASN_OP_OTHER(op) \ +DEFN_ASN_OP_T(op,int64) \ +DEFN_ASN_OP_T(op,uint64) \ +DEFN_ASN_OP_T(op,const sc_int_base&) \ +DEFN_ASN_OP_T(op,const sc_uint_base&) \ +DEFN_ASN_OP_T(op,const sc_signed&) \ +DEFN_ASN_OP_T(op,const sc_unsigned&) +#else +#define DEFN_ASN_OP_OTHER(op) +#endif + +#define DEFN_ASN_OP(op) \ +DEFN_ASN_OP_T(op,int) \ +DEFN_ASN_OP_T(op,unsigned int) \ +DEFN_ASN_OP_T(op,long) \ +DEFN_ASN_OP_T(op,unsigned long) \ +DEFN_ASN_OP_T(op,float) \ +DEFN_ASN_OP_T(op,double) \ +DEFN_ASN_OP_T(op,const char*) \ +DEFN_ASN_OP_T(op,const sc_fxval&) \ +DEFN_ASN_OP_T(op,const sc_fxval_fast&) \ +DEFN_ASN_OP_T(op,const sc_fxnum&) \ +DEFN_ASN_OP_T(op,const sc_fxnum_fast&) \ +DEFN_ASN_OP_OTHER(op) + +DEFN_ASN_OP(=) + +DEFN_ASN_OP(*=) +DEFN_ASN_OP(/=) +DEFN_ASN_OP(+=) +DEFN_ASN_OP(-=) + +DEFN_ASN_OP_T(<<=,int) +DEFN_ASN_OP_T(>>=,int) + +DEFN_ASN_OP_T(&=,const sc_ufix&) +DEFN_ASN_OP_T(&=,const sc_ufix_fast&) +DEFN_ASN_OP_T(|=,const sc_ufix&) +DEFN_ASN_OP_T(|=,const sc_ufix_fast&) +DEFN_ASN_OP_T(^=,const sc_ufix&) +DEFN_ASN_OP_T(^=,const sc_ufix_fast&) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP_OTHER +#undef DEFN_ASN_OP + + +// auto-increment and auto-decrement + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_ufixed_fast<W,I,Q,O,N>::operator ++ ( int ) +{ + return sc_fxval_fast( sc_ufix_fast::operator ++ ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +const sc_fxval_fast +sc_ufixed_fast<W,I,Q,O,N>::operator -- ( int ) +{ + return sc_fxval_fast( sc_ufix_fast::operator -- ( 0 ) ); +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator ++ () +{ + sc_ufix_fast::operator ++ (); + return *this; +} + +template<int W, int I, sc_q_mode Q, sc_o_mode O, int N> +inline +sc_ufixed_fast<W,I,Q,O,N>& +sc_ufixed_fast<W,I,Q,O,N>::operator -- () +{ + sc_ufix_fast::operator -- (); + return *this; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h new file mode 100644 index 000000000..b2da95432 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_ieee.h @@ -0,0 +1,701 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_ieee.h - + + Original Author: 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_ieee.h,v $ +// Revision 1.3 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/08/07 18:55:24 acg +// Philipp A. Hartmann: added guard for __clang__ to get the clang platform +// working. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_IEEE_H +#define SCFX_IEEE_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" + + +namespace sc_dt +{ + +// classes defined in this module +union ieee_double; +class scfx_ieee_double; +union ieee_float; +class scfx_ieee_float; + +#define SCFX_MASK_(Size) \ + ((1u << (Size))-1u) + +// ---------------------------------------------------------------------------- +// UNION : ieee_double +// +// IEEE 754 double-precision format. +// ---------------------------------------------------------------------------- + +union ieee_double +{ + + double d; + + struct + { +#if defined( SC_BIG_ENDIAN ) + unsigned negative:1; + unsigned exponent:11; + unsigned mantissa0:20; + unsigned mantissa1:32; +#elif defined( SC_LITTLE_ENDIAN ) + unsigned mantissa1:32; + unsigned mantissa0:20; + unsigned exponent:11; + unsigned negative:1; +#endif + } s; + +}; + + +const unsigned int SCFX_IEEE_DOUBLE_BIAS = 1023U; + +const int SCFX_IEEE_DOUBLE_E_MAX = 1023; +const int SCFX_IEEE_DOUBLE_E_MIN = -1022; + +const unsigned int SCFX_IEEE_DOUBLE_M_SIZE = 52; +const unsigned int SCFX_IEEE_DOUBLE_M0_SIZE = 20; +const unsigned int SCFX_IEEE_DOUBLE_M1_SIZE = 32; +const unsigned int SCFX_IEEE_DOUBLE_E_SIZE = 11; + + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_ieee_double +// +// Convenient interface to union ieee_double. +// ---------------------------------------------------------------------------- + +class scfx_ieee_double +{ + + ieee_double m_id; + +public: + + scfx_ieee_double(); + scfx_ieee_double( double ); + scfx_ieee_double( const scfx_ieee_double& ); + + scfx_ieee_double& operator = ( double ); + scfx_ieee_double& operator = ( const scfx_ieee_double& ); + + operator double() const; + + unsigned int negative() const; + void negative( unsigned int ); + int exponent() const; + void exponent( int ); + unsigned int mantissa0() const; + void mantissa0( unsigned int ); + unsigned int mantissa1() const; + void mantissa1( unsigned int ); + + bool is_zero() const; + bool is_subnormal() const; + bool is_normal() const; + bool is_inf() const; + bool is_nan() const; + + void set_inf(); + void set_nan(); + + int msb() const; // most significant non-zero bit + int lsb() const; // least significant non-zero bit + + static const scfx_ieee_double nan(); + static const scfx_ieee_double inf( int ); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +scfx_ieee_double::scfx_ieee_double() : m_id() +{ + m_id.d = 0.0; +} + +inline +scfx_ieee_double::scfx_ieee_double( double d ) : m_id() +{ + m_id.d = d; +} + +inline +scfx_ieee_double::scfx_ieee_double( const scfx_ieee_double& a ) : m_id(a.m_id) +{ + // m_id.d = a.m_id.d; +} + + +inline +scfx_ieee_double& +scfx_ieee_double::operator = ( double d ) +{ + m_id.d = d; + return *this; +} + +inline +scfx_ieee_double& +scfx_ieee_double::operator = ( const scfx_ieee_double& a ) +{ + m_id.d = a.m_id.d; + return *this; +} + + +inline +scfx_ieee_double::operator double() const +{ + return m_id.d; +} + + +inline +unsigned int +scfx_ieee_double::negative() const +{ + return m_id.s.negative; +} + +inline +void +scfx_ieee_double::negative( unsigned int a ) +{ + m_id.s.negative = a & SCFX_MASK_(1); +} + +inline +int +scfx_ieee_double::exponent() const +{ + return m_id.s.exponent - SCFX_IEEE_DOUBLE_BIAS; +} + +inline +void +scfx_ieee_double::exponent( int a ) +{ + m_id.s.exponent = (SCFX_IEEE_DOUBLE_BIAS + a) + & SCFX_MASK_(SCFX_IEEE_DOUBLE_E_SIZE); +} + +inline +unsigned int +scfx_ieee_double::mantissa0() const +{ + return m_id.s.mantissa0; +} + +inline +void +scfx_ieee_double::mantissa0( unsigned int a ) +{ + m_id.s.mantissa0 = a & SCFX_MASK_(SCFX_IEEE_DOUBLE_M0_SIZE); +} + +inline +unsigned int +scfx_ieee_double::mantissa1() const +{ + return m_id.s.mantissa1; +} + +inline +void +scfx_ieee_double::mantissa1( unsigned int a ) +{ + m_id.s.mantissa1 = a; // & SCFX_MASK_(SCFX_IEEE_DOUBLE_M1_SIZE); +} + + +inline +bool +scfx_ieee_double::is_zero() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 && + mantissa0() == 0U && mantissa1() == 0U ); +} + +inline +bool +scfx_ieee_double::is_subnormal() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MIN - 1 && + ( mantissa0() != 0U || mantissa1() != 0U ) ); +} + +inline +bool +scfx_ieee_double::is_normal() const +{ + return ( exponent() >= SCFX_IEEE_DOUBLE_E_MIN && + exponent() <= SCFX_IEEE_DOUBLE_E_MAX ); +} + +inline +bool +scfx_ieee_double::is_inf() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 && + mantissa0() == 0U && mantissa1() == 0U ); +} + +inline +bool +scfx_ieee_double::is_nan() const +{ + return ( exponent() == SCFX_IEEE_DOUBLE_E_MAX + 1 && + ( mantissa0() != 0U || mantissa1() != 0U ) ); +} + + +inline +void +scfx_ieee_double::set_inf() +{ + exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 ); + mantissa0( 0U ); + mantissa1( 0U ); +} + +inline +void +scfx_ieee_double::set_nan() +{ + exponent( SCFX_IEEE_DOUBLE_E_MAX + 1 ); + mantissa0( (unsigned int) -1 ); + mantissa1( (unsigned int) -1 ); +} + + +#define MSB_STATEMENT(x,n) if( x >> n ) { x >>= n; i += n; } + +inline +int +scfx_ieee_double::msb() const +{ + unsigned int m0 = mantissa0(); + unsigned int m1 = mantissa1(); + if( m0 != 0 ) + { + int i = 0; + MSB_STATEMENT(m0,16); + MSB_STATEMENT(m0,8); + MSB_STATEMENT(m0,4); + MSB_STATEMENT(m0,2); + MSB_STATEMENT(m0,1); + return ( i - 20 ); + } + else if( m1 != 0 ) + { + int i = 0; + MSB_STATEMENT(m1,16); + MSB_STATEMENT(m1,8); + MSB_STATEMENT(m1,4); + MSB_STATEMENT(m1,2); + MSB_STATEMENT(m1,1); + return ( i - 52 ); + } + else + { + return 0; + } +} + +#undef MSB_STATEMENT + +#define LSB_STATEMENT(x,n) if( x << n ) { x <<= n; i -= n; } + +inline +int +scfx_ieee_double::lsb() const +{ + unsigned int m0 = mantissa0(); + unsigned int m1 = mantissa1(); + if( m1 != 0 ) + { + int i = 31; + LSB_STATEMENT(m1,16); + LSB_STATEMENT(m1,8); + LSB_STATEMENT(m1,4); + LSB_STATEMENT(m1,2); + LSB_STATEMENT(m1,1); + return ( i - 52 ); + } + else if( m0 != 0 ) + { + int i = 31; + LSB_STATEMENT(m0,16); + LSB_STATEMENT(m0,8); + LSB_STATEMENT(m0,4); + LSB_STATEMENT(m0,2); + LSB_STATEMENT(m0,1); + return ( i - 20 ); + } + else + { + return 0; + } +} + +#undef LSB_STATEMENT + + +inline +const scfx_ieee_double +scfx_ieee_double::nan() +{ + scfx_ieee_double id; + id.set_nan(); + return id; +} + +inline +const scfx_ieee_double +scfx_ieee_double::inf( int sign ) +{ + scfx_ieee_double id( sign ); + id.set_inf(); + return id; +} + + +// ---------------------------------------------------------------------------- +// UNION : ieee_float +// +// IEEE 754 single-precision format. +// ---------------------------------------------------------------------------- + +union ieee_float +{ + + float f; + + struct + { +#if defined( SC_BIG_ENDIAN ) + unsigned negative:1; + unsigned exponent:8; + unsigned mantissa:23; +#elif defined( SC_LITTLE_ENDIAN ) + unsigned mantissa:23; + unsigned exponent:8; + unsigned negative:1; +#endif + } s; + +}; + + +const unsigned int SCFX_IEEE_FLOAT_BIAS = 127U; + +const int SCFX_IEEE_FLOAT_E_MAX = 127; +const int SCFX_IEEE_FLOAT_E_MIN = -126; + +const unsigned int SCFX_IEEE_FLOAT_M_SIZE = 23; +const unsigned int SCFX_IEEE_FLOAT_E_SIZE = 8; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_ieee_float +// +// Convenient wrapper to union ieee_float. +// ---------------------------------------------------------------------------- + +class scfx_ieee_float +{ + + ieee_float m_if; + +public: + + scfx_ieee_float(); + scfx_ieee_float( float ); + scfx_ieee_float( const scfx_ieee_float& ); + + scfx_ieee_float& operator = ( float ); + scfx_ieee_float& operator = ( const scfx_ieee_float& ); + + operator float() const; + + unsigned int negative() const; + void negative( unsigned int ); + int exponent() const; + void exponent( int ); + unsigned int mantissa() const; + void mantissa( unsigned int ); + + bool is_zero() const; + bool is_subnormal() const; + bool is_normal() const; + bool is_inf() const; + bool is_nan() const; + + void set_inf(); + void set_nan(); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +scfx_ieee_float::scfx_ieee_float() : m_if() +{ + m_if.f = 0.0; +} + +inline +scfx_ieee_float::scfx_ieee_float( float f ) : m_if() +{ + m_if.f = f; +} + +inline +scfx_ieee_float::scfx_ieee_float( const scfx_ieee_float& a ) : m_if(a.m_if) +{ + // m_if.f = a.m_if.f; +} + + +inline +scfx_ieee_float& +scfx_ieee_float::operator = ( float f ) +{ + m_if.f = f; + return *this; +} + +inline +scfx_ieee_float& +scfx_ieee_float::operator = ( const scfx_ieee_float& a ) +{ + m_if.f = a.m_if.f; + return *this; +} + + +inline +scfx_ieee_float::operator float() const +{ + return m_if.f; +} + + +inline +unsigned int +scfx_ieee_float::negative() const +{ + return m_if.s.negative; +} + +inline +void +scfx_ieee_float::negative( unsigned int a ) +{ + m_if.s.negative = a & SCFX_MASK_(1); +} + +inline +int +scfx_ieee_float::exponent() const +{ + return m_if.s.exponent - SCFX_IEEE_FLOAT_BIAS; +} + +inline +void +scfx_ieee_float::exponent( int a ) +{ + m_if.s.exponent = (SCFX_IEEE_FLOAT_BIAS + a) + & SCFX_MASK_(SCFX_IEEE_FLOAT_E_SIZE); +} + +inline +unsigned int +scfx_ieee_float::mantissa() const +{ + return m_if.s.mantissa; +} + +inline +void +scfx_ieee_float::mantissa( unsigned int a ) +{ + m_if.s.mantissa = a & SCFX_MASK_(SCFX_IEEE_FLOAT_M_SIZE); +} + + +inline +bool +scfx_ieee_float::is_zero() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() == 0U ); +} + +inline +bool +scfx_ieee_float::is_subnormal() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MIN - 1 && mantissa() != 0U ); +} + +inline +bool +scfx_ieee_float::is_normal() const +{ + return ( exponent() >= SCFX_IEEE_FLOAT_E_MIN && + exponent() <= SCFX_IEEE_FLOAT_E_MAX ); +} + +inline +bool +scfx_ieee_float::is_inf() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() == 0U ); +} + +inline +bool +scfx_ieee_float::is_nan() const +{ + return ( exponent() == SCFX_IEEE_FLOAT_E_MAX + 1 && mantissa() != 0U ); +} + + +inline +void +scfx_ieee_float::set_inf() +{ + exponent( SCFX_IEEE_FLOAT_E_MAX + 1 ); + mantissa( 0U ); +} + +inline +void +scfx_ieee_float::set_nan() +{ + exponent( SCFX_IEEE_FLOAT_E_MAX + 1 ); + mantissa( (unsigned int) -1 ); +} + + +// ---------------------------------------------------------------------------- +// FUNCTION : scfx_pow2 +// +// Computes 2.0**exp in double-precision. +// ---------------------------------------------------------------------------- + +inline +double scfx_pow2( int exp ) +{ + scfx_ieee_double r; + if( exp < SCFX_IEEE_DOUBLE_E_MIN ) + { + r = 0.0; + // handle subnormal case + exp -= SCFX_IEEE_DOUBLE_E_MIN; + if( ( exp += 20 ) >= 0 ) + { + r.mantissa0( 1U << exp ); + } + else if( ( exp += 32 ) >= 0 ) + { + r.mantissa1( 1U << exp ); + } + } + else if( exp > SCFX_IEEE_DOUBLE_E_MAX ) + { + r.set_inf(); + } + else + { + r = 1.0; + r.exponent( exp ); + } + return r; +} + + +// ---------------------------------------------------------------------------- +// FUNCTION : uint64_to_double +// +// Platform independent conversion from double uint64 to double. +// Needed because VC++6 doesn't support this conversion. +// ---------------------------------------------------------------------------- + +inline +double +uint64_to_double( uint64 a ) +{ +#if defined( _MSC_VER ) || defined( __clang__ ) + // conversion from uint64 to double not implemented; use int64 + double tmp = static_cast<double>( static_cast<int64>( a ) ); + return ( tmp >= 0 ) ? tmp : tmp + sc_dt::scfx_pow2( 64 ); +#else + return static_cast<double>( a ); +#endif +} + +} // namespace sc_dt + +#undef SCFX_MASK_ + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp new file mode 100644 index 000000000..fc29764f6 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.cpp @@ -0,0 +1,125 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_mant.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_mant.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/scfx_mant.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// word memory management +// ---------------------------------------------------------------------------- + +class word_list { // Entry in free_words bucket. + public: + word_list* m_next_p; +}; + +static inline +int +next_pow2_index( std::size_t size ) +{ + int index = scfx_find_msb( size ); + // If this was a power of 2 we are one bucket too low. + if( ~ (1 << index) & size ) index ++; + // If this is a 64-bit machine and we are using 32-bit words go down + // one slot size, as all the slots are 2x in size. + if ( index != 0 && ( sizeof(word_list) != sizeof(word) ) ) + { + index -= 1; + } + return index; +} + +static word_list* free_words[32] = { 0 }; + +word* +scfx_mant::alloc_word( std::size_t size ) +{ + const int ALLOC_SIZE = 128; + + int slot_index = next_pow2_index( size ); + + int alloc_size = ( 1 << slot_index ); + + word_list*& slot = free_words[slot_index]; + + if( ! slot ) + { + slot = new word_list[ALLOC_SIZE * alloc_size]; + int i; + for( i = 0; i < alloc_size*(ALLOC_SIZE-1) ; i+=alloc_size ) + { + slot[i].m_next_p = &slot[i+alloc_size]; + } + slot[i].m_next_p = 0; + } + + word* result = (word*)slot; + free_words[slot_index] = slot[0].m_next_p; + return result; +} + +void +scfx_mant::free_word( word* array, std::size_t size ) +{ + if( array && size ) + { + int slot_index = next_pow2_index( size ); + word_list* wl_p = (word_list*)array; + + wl_p->m_next_p = free_words[slot_index]; + free_words[slot_index] = wl_p; + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h new file mode 100644 index 000000000..84d9b0bd8 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_mant.h @@ -0,0 +1,490 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_mant.h - + + 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_mant.h,v $ +// Revision 1.2 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_MANT_H +#define SCFX_MANT_H + + +#include "sysc/datatypes/fx/scfx_ieee.h" +#include "sysc/datatypes/fx/scfx_utils.h" +#include "sysc/kernel/sc_macros.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_mant; +class scfx_mant_ref; + + +typedef unsigned int word; // Using int because of 64-bit machines. +typedef unsigned short half_word; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant +// +// Mantissa class. +// ---------------------------------------------------------------------------- + +class scfx_mant +{ + + word* m_array; + int m_size; + +public: + + explicit scfx_mant( std::size_t ); + scfx_mant( const scfx_mant& ); + + scfx_mant& operator = ( const scfx_mant& ); + + ~scfx_mant(); + + void clear(); + + void resize_to( int, int = 0 ); + + int size() const; + + word operator [] ( int ) const; + word& operator [] ( int ); + + half_word half_at( int ) const; + half_word& half_at( int ); + + half_word* half_addr( int = 0 ) const; + +private: + + static word* alloc( std::size_t ); + static void free( word*, std::size_t ); + + static word* alloc_word( std::size_t size ); + static void free_word( word* array, std::size_t size ); + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +int +scfx_mant::size() const +{ + return m_size; +} + + +inline +word* +scfx_mant::alloc( std::size_t size ) +{ +#if defined( SC_BIG_ENDIAN ) + return alloc_word( size ) + ( size - 1 ); +#elif defined( SC_LITTLE_ENDIAN ) + return alloc_word( size ); +#endif +} + +inline +void +scfx_mant::free( word* mant, std::size_t size ) +{ +#if defined( SC_BIG_ENDIAN ) + free_word( mant - ( size - 1 ), size ); +#elif defined( SC_LITTLE_ENDIAN ) + free_word( mant, size ); +#endif +} + +inline +word +scfx_mant::operator[]( int i ) const +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return m_array[i]; +#endif +} + +inline +word& +scfx_mant::operator[]( int i ) +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return m_array[i]; +#endif +} + +inline +scfx_mant::scfx_mant( std::size_t size ) +: m_array(0), m_size(size) +{ + m_array = alloc( size ); +} + +inline +scfx_mant::scfx_mant( const scfx_mant& rhs ) +: m_array(0), m_size(rhs.m_size) +{ + m_array = alloc( m_size ); + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = rhs[i]; + } +} + +inline +scfx_mant& +scfx_mant::operator = ( const scfx_mant& rhs ) +{ + if( &rhs != this ) + { + if( m_size != rhs.m_size ) + { + free( m_array, m_size ); + m_array = alloc( m_size = rhs.m_size ); + } + + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = rhs[i]; + } + } + return *this; +} + +inline +scfx_mant::~scfx_mant() +{ + if( m_array != 0 ) + { + free( m_array, m_size ); + } +} + +inline +void +scfx_mant::clear() +{ + for( int i = 0; i < m_size; i ++ ) + { + (*this)[i] = 0; + } +} + +inline +void +scfx_mant::resize_to( int size, int restore ) +{ + if( size == m_size ) + { + return; + } + + if( ! m_array ) + { + m_array = alloc( m_size = size ); + } + else + { + word* p = alloc( size ); + + if( restore ) + { + int end = sc_min( size, m_size ); + if( restore == 1 ) // msb resized -> align at 0 + { + for( int i = 0; i < size; i ++ ) + { + if( i < end ) + { +#if defined( SC_BIG_ENDIAN ) + p[-i] = m_array[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + p[i] = m_array[i]; +#endif + } + else + { +#if defined( SC_BIG_ENDIAN ) + p[-i] = 0; +#elif defined( SC_LITTLE_ENDIAN ) + p[i] = 0; +#endif + } + } + } + else // lsb resized -> align at size-1 + { + for( int i = 0; i < size; i ++ ) + { + if( i < end ) + { +#if defined( SC_BIG_ENDIAN ) + p[-size+1+i] = m_array[-m_size+1+i]; +#elif defined( SC_LITTLE_ENDIAN ) + p[size-1-i] = m_array[m_size-1-i]; +#endif + } + else + { +#if defined( SC_BIG_ENDIAN ) + p[-size+1+i] = 0; +#elif defined( SC_LITTLE_ENDIAN ) + p[size-1-i] = 0; +#endif + } + } + } + } + + free( m_array, m_size ); + m_array = p; + m_size = size; + } +} + +inline +half_word +scfx_mant::half_at( int i ) const +{ + SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, + "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[i]; +#endif +} + +inline +half_word& +scfx_mant::half_at( int i ) +{ + SC_ASSERT_( ( i >> 1 ) >= 0 && ( i >> 1 ) < m_size, + "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[-i]; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array )[i]; +#endif +} + +inline +half_word* +scfx_mant::half_addr( int i ) const +{ + SC_ASSERT_( i >= 0 && i < m_size, "mantissa index out of range" ); +#if defined( SC_BIG_ENDIAN ) + return reinterpret_cast<half_word*>( m_array - i ) + 1; +#elif defined( SC_LITTLE_ENDIAN ) + return reinterpret_cast<half_word*>( m_array + i ); +#endif +} + + +// ---------------------------------------------------------------------------- +// one's complement of a mantissa +// ---------------------------------------------------------------------------- + +inline +void +complement( scfx_mant& target, const scfx_mant& source, int size ) +{ + for( int i = 0; i < size; i ++ ) + { + target[i] = ~source[i]; + } +} + + +// ---------------------------------------------------------------------------- +// increment mantissa +// ---------------------------------------------------------------------------- + +inline +void +inc( scfx_mant& mant ) +{ + for( int i = 0; i < mant.size(); i ++ ) + { + if( ++ mant[i] ) + { + break; + } + } +} + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_mant_ref +// +// Mantissa reference class. +// ---------------------------------------------------------------------------- + +class scfx_mant_ref +{ + + scfx_mant* m_mant; + bool m_not_const; + +public: + + scfx_mant_ref(); + scfx_mant_ref( const scfx_mant& ); + scfx_mant_ref( scfx_mant* ); + + scfx_mant_ref& operator = ( const scfx_mant& ); + scfx_mant_ref& operator = ( scfx_mant* ); + + ~scfx_mant_ref(); + + operator scfx_mant&(); + + word operator [] ( int ); + +private: + + void remove_it(); + + scfx_mant_ref( const scfx_mant_ref& ); + scfx_mant_ref& operator = ( const scfx_mant_ref& ); + + void* operator new( std::size_t sz ) { return ::operator new( sz ); } + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_mant_ref::remove_it() +{ + if( m_not_const ) + { + delete m_mant; + } +} + +inline +scfx_mant_ref::scfx_mant_ref() +: m_mant( 0 ), m_not_const( false ) +{} + +inline +scfx_mant_ref::scfx_mant_ref( const scfx_mant& mant ) +: m_mant( const_cast<scfx_mant*>( &mant ) ), m_not_const( false ) +{} + +inline +scfx_mant_ref::scfx_mant_ref( scfx_mant* mant ) +: m_mant( mant ), m_not_const( true ) +{} + +inline +scfx_mant_ref& +scfx_mant_ref::operator = ( const scfx_mant& mant ) +{ + remove_it(); + + m_mant = const_cast<scfx_mant*>( &mant ); + m_not_const = false; + + return *this; +} + +inline +scfx_mant_ref& +scfx_mant_ref::operator = ( scfx_mant* mant ) +{ + remove_it(); + + m_mant = mant; + m_not_const = true; + + return *this; +} + +inline +scfx_mant_ref::~scfx_mant_ref() +{ + remove_it(); +} + +inline +scfx_mant_ref::operator scfx_mant&() +{ + // SC_ASSERT_( m_not_const, "not allowed to modify mant" ); + return *m_mant; +} + +inline +word +scfx_mant_ref::operator [] ( int i ) +{ + return (*m_mant)[i]; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h new file mode 100644 index 000000000..a52d74b6b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_other_defs.h @@ -0,0 +1,433 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_other_defs.h - + + Original Author: 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_other_defs.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_OTHER_DEFS_H +#define SCFX_OTHER_DEFS_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/int/sc_signed.h" +#include "sysc/datatypes/int/sc_unsigned.h" +#include "sysc/datatypes/int/sc_int_base.h" +#include "sysc/datatypes/int/sc_uint_base.h" +#include "sysc/tracing/sc_trace.h" + + +namespace sc_dt +{ + +#ifdef SC_INCLUDE_FX + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxval& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxval_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxnum& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_signed& +sc_signed::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_signed::operator = ( const sc_fxnum_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxval& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxval_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxnum& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + +inline +const sc_unsigned& +sc_unsigned::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) /* also triggers OBSERVER_READ call */ + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_unsigned::operator = ( const sc_fxnum_fast& )" ); + } + + for( int i = 0; i < length(); ++ i ) + (*this)[i] = v.get_bit( i ); + + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// ---------------------------------------------------------------------------- + +#ifndef _32BIT_ +#define NUM_WIDTH LLWIDTH +#else +#define NUM_WIDTH INTWIDTH +#endif + + +// assignment operators + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxval& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxval_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxnum& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_int_base& +sc_int_base::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_int_base::operator = ( const sc_fxnum_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +#undef NUM_WIDTH + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// ---------------------------------------------------------------------------- + +// assignment operators + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxval& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxval& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxval_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxval_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxnum& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxnum& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + +inline +sc_uint_base& +sc_uint_base::operator = ( const sc_fxnum_fast& v ) +{ + if( ! v.is_normal() ) { /* also triggers OBSERVER_READ call */ + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_FX_VALUE_, + "sc_uint_base::operator = ( const sc_fxnum_fast& )" ); + } + for( int i = 0; i < m_len; ++ i ) { + set( i, v.get_bit( i ) ); + } + extend_sign(); + return *this; +} + + +#endif + + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_trace +// ---------------------------------------------------------------------------- + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval_fast& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxval_fast* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum_fast& object, const std::string& name ) +{ + if( tf ) + tf->trace( object, name ); +} + +inline +void +sc_trace( sc_core::sc_trace_file* tf, + const sc_fxnum_fast* object, const std::string& name ) +{ + if( tf ) + tf->trace( *object, name ); +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_params.h b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h new file mode 100644 index 000000000..8cd646651 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_params.h @@ -0,0 +1,222 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_params.h - + + Original Author: 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_params.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_PARAMS_H +#define SCFX_PARAMS_H + + +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/fx/sc_fxcast_switch.h" +#include "sysc/datatypes/fx/sc_fxtype_params.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_params; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_params +// +// ... +// ---------------------------------------------------------------------------- + +class scfx_params +{ + +public: + + // constructor + + scfx_params( const sc_fxtype_params&, + sc_enc, + const sc_fxcast_switch& ); + + + // query functions + + const sc_fxtype_params& type_params() const; + sc_enc enc() const; + const sc_fxcast_switch& cast_switch() const; + + + // shortcuts + + int wl() const; + int iwl() const; + int fwl() const; + sc_q_mode q_mode() const; + sc_o_mode o_mode() const; + int n_bits() const; + + + // dump content + + void dump( ::std::ostream& ) const; + +private: + + sc_fxtype_params m_type_params; + sc_enc m_enc; + sc_fxcast_switch m_cast_switch; + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// constructor + +inline +scfx_params::scfx_params( const sc_fxtype_params& type_params_, + sc_enc enc_, + const sc_fxcast_switch& cast_sw ) +: m_type_params( type_params_ ), + m_enc( enc_ ), + m_cast_switch( cast_sw ) +{ + if( m_enc == SC_US_ && m_type_params.o_mode() == SC_WRAP_SM ) + { + SC_REPORT_ERROR( sc_core::SC_ID_INVALID_O_MODE_, + "SC_WRAP_SM not defined for unsigned numbers" ); + } + +} + + +// query functions + +inline +const sc_fxtype_params& +scfx_params::type_params() const +{ + return m_type_params; +} + +inline +sc_enc +scfx_params::enc() const +{ + return m_enc; +} + +inline +const sc_fxcast_switch& +scfx_params::cast_switch() const +{ + return m_cast_switch; +} + + +// shortcuts + +inline +int +scfx_params::wl() const +{ + return m_type_params.wl(); +} + +inline +int +scfx_params::iwl() const +{ + return m_type_params.iwl(); +} + +inline +int +scfx_params::fwl() const +{ + return ( m_type_params.wl() - m_type_params.iwl() ); +} + +inline +sc_q_mode +scfx_params::q_mode() const +{ + return m_type_params.q_mode(); +} + +inline +sc_o_mode +scfx_params::o_mode() const +{ + return m_type_params.o_mode(); +} + +inline +int +scfx_params::n_bits() const +{ + return m_type_params.n_bits(); +} + + +// dump content + +inline +void +scfx_params::dump( ::std::ostream& os ) const +{ + os << "scfx_params" << ::std::endl; + os << "(" << ::std::endl; + os << "type_params = "; + m_type_params.dump( os ); + os << "enc = " << m_enc << ::std::endl; + os << "cast_switch = "; + m_cast_switch.dump( os ); + os << ")" << ::std::endl; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp new file mode 100644 index 000000000..ac931763b --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.cpp @@ -0,0 +1,147 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_pow10.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_pow10.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/scfx_pow10.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// CLASS : scfx_pow10 +// +// Class to compute (and cache) powers of 10 in arbitrary precision. +// ---------------------------------------------------------------------------- + +scfx_pow10::scfx_pow10() +{ + m_pos[0] = scfx_rep( 10.0 ); + m_neg[0] = scfx_rep( 0.1 ); + + for( int i = 1; i < SCFX_POW10_TABLE_SIZE; i ++ ) + { + m_pos[i].set_nan(); + m_neg[i].set_nan(); + } +} + +scfx_pow10::~scfx_pow10() +{} + + +const scfx_rep +scfx_pow10::operator() ( int i ) +{ + if( i == 0 ) { + return scfx_rep( 1.0 ); + } + + if( i > 0 ) + { + int bit = scfx_find_msb( i ); + scfx_rep result = *pos( bit ); + if( bit ) + { + while( -- bit >= 0 ) + { + if( ( 1 << bit ) & i ) + { + scfx_rep* tmp = mult_scfx_rep( result, *pos( bit ) ); + result = *tmp; + delete tmp; + } + } + } + return result; + } + else + { + i = -i; + int bit = scfx_find_msb( i ); + scfx_rep result = *neg( bit ); + if( bit ) + { + while( -- bit >= 0 ) + { + if( ( 1 << bit ) & i ) + { + scfx_rep* tmp = mult_scfx_rep( result, *neg( bit ) ); + result = *tmp; + delete tmp; + } + } + } + return result; + } +} + + +scfx_rep* +scfx_pow10::pos( int i ) +{ + if( ! m_pos[i].is_normal() ) + { + multiply( m_pos[i], *pos( i - 1 ), *pos( i - 1 ) ); + } + return &m_pos[i]; +} + +scfx_rep* +scfx_pow10::neg( int i ) +{ + if( ! m_neg[i].is_normal() ) + { + multiply( m_neg[i], *neg( i - 1 ), *neg( i - 1 ) ); + } + return &m_neg[i]; +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h new file mode 100644 index 000000000..c9b278561 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_pow10.h @@ -0,0 +1,95 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_pow10.h - + + 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_pow10.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_POW10_H +#define SCFX_POW10_H + + +#include "sysc/datatypes/fx/scfx_rep.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_pow10; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_pow10 +// +// Class to compute (and cache) powers of 10 in arbitrary precision. +// ---------------------------------------------------------------------------- + +const int SCFX_POW10_TABLE_SIZE = 32; + + +class scfx_pow10 +{ + +public: + + scfx_pow10(); + ~scfx_pow10(); + + const scfx_rep operator() ( int ); + +private: + + scfx_rep* pos( int ); + scfx_rep* neg( int ); + + scfx_rep m_pos[SCFX_POW10_TABLE_SIZE]; + scfx_rep m_neg[SCFX_POW10_TABLE_SIZE]; +}; + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp new file mode 100644 index 000000000..772835e6d --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.cpp @@ -0,0 +1,2926 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions 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.4 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.2 2009/02/28 00:26:20 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.2 2008/11/06 17:22:47 acg +// Andy Goodrich: bug fixes for 2.2.1. +// +// 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 <cstdio> +#include <stdlib.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 inline +int +n_word( int x ) +{ + return ( x + bits_in_word - 1 ) / bits_in_word; +} + + +// ---------------------------------------------------------------------------- +// CONSTRUCTORS +// ---------------------------------------------------------------------------- + +scfx_rep::scfx_rep() +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + m_r_flag( false ) +{ + set_zero(); +} + +scfx_rep::scfx_rep( int a ) +: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_sign(), 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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_wp(), m_sign(), m_state(), m_msw(), m_lsw(), + 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 constructor + +scfx_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; \ + } \ +} + + +void +scfx_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; + } + } + + m_state = normal; + find_sw(); + + // + // two's complement of mantissa if it is negative + // + + if( mant_is_neg ) + { + m_mant[m_msw] |= -1 << scfx_find_msb( m_mant[m_msw] ); + for( int i = m_msw + 1; i < m_mant.size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + complement( m_mant, m_mant, m_mant.size() ); + inc( m_mant ); + m_sign *= -1; + find_sw(); + } +} + + +#undef SCFX_FAIL_IF_ + + +// ---------------------------------------------------------------------------- +// METHOD : to_double +// +// Convert from scfx_rep to double. +// ---------------------------------------------------------------------------- + +double +scfx_rep::to_double() const +{ + scfx_ieee_double id; + + // handle special cases + + if( is_nan() ) + { + id.set_nan(); + return id; + } + + if( is_inf() ) + { + id.set_inf(); + id.negative( m_sign < 0 ); + return id; + } + + if( is_zero() ) + { + id = 0.; + id.negative( m_sign < 0 ); + return id; + } + + int msb = scfx_find_msb( m_mant[m_msw] ); + + int exp = (m_msw - m_wp) * bits_in_word + msb; + + if( exp > SCFX_IEEE_DOUBLE_E_MAX ) + { + id.set_inf(); + id.negative( m_sign < 0 ); + return id; + } + + if( exp < SCFX_IEEE_DOUBLE_E_MIN + - static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) ) + { + id = 0.; + return id; + } + + int shift = mantissa0_size - msb; + + unsigned int m0; + unsigned int m1 = 0; + unsigned int guard = 0; + + if( shift == 0 ) + { + m0 = m_mant[m_msw] & ~( 1 << mantissa0_size ); + if( m_msw > m_lsw ) + { + m1 = m_mant[m_msw - 1]; + if( m_msw - 1 > m_lsw ) + guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 ); + } + } + else if( shift < 0 ) + { + m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size ); + m1 = m_mant[m_msw] << ( bits_in_word + shift ); + if( m_msw > m_lsw ) + { + m1 |= m_mant[m_msw - 1] >> -shift; + guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1; + } + } + else + { + m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size ); + if( m_msw > m_lsw ) + { + m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift ); + m1 = m_mant[m_msw - 1] << shift; + if( m_msw - 1 > m_lsw ) + { + m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift ); + guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) ) + & 1; + } + } + } + + if( exp < SCFX_IEEE_DOUBLE_E_MIN ) + { + m0 |= ( 1 << mantissa0_size ); + + int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp; + + if( subnormal_shift < bits_in_word ) + { + m1 = m1 >> subnormal_shift + | m0 << ( bits_in_word - subnormal_shift ); + m0 = m0 >> subnormal_shift; + } + else + { + m1 = m0 >> ( subnormal_shift - bits_in_word ); + m0 = 0; + } + + guard = 0; + + exp = SCFX_IEEE_DOUBLE_E_MIN - 1; + } + + id.mantissa0( m0 ); + id.mantissa1( m1 ); + id.exponent( exp ); + id.negative( m_sign < 0 ); + + double result = id; + + if( guard != 0 ) + result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE ); + + return result; +} + + +// ---------------------------------------------------------------------------- +// METHOD : to_string +// +// Convert from scfx_rep to character string. +// ---------------------------------------------------------------------------- + +void +print_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt ) +{ + if( num.is_neg() ) + s += '-'; + + if( w_prefix == 1 ) { + scfx_print_prefix( s, SC_DEC ); + } + + if( num.is_zero() ) + { + s += '0'; + return; + } + + // split 'num' into its integer and fractional part + + scfx_rep int_part = num; + scfx_rep frac_part = num; + + int i; + + for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ ) + int_part.m_mant[i] = 0; + int_part.find_sw(); + if( int_part.m_wp < int_part.m_lsw ) + int_part.resize_to( int_part.size() - int_part.m_wp, -1 ); + + for( i = frac_part.m_msw; + i >= frac_part.m_lsw && i >= frac_part.m_wp; + i -- ) + frac_part.m_mant[i] = 0; + frac_part.find_sw(); + if( frac_part.m_msw == frac_part.size() - 1 ) + frac_part.resize_to( frac_part.size() + 1, 1 ); + + // print integer part + + int int_digits = 0; + int int_zeros = 0; + + if( ! int_part.is_zero() ) + { + double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word + + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1; + int_digits = (int) ceil( int_wl * log10( 2. ) ); + + int len = s.length(); + s.append( int_digits ); + + bool zero_digits = ( frac_part.is_zero() && fmt != SC_F ); + + for( i = int_digits + len - 1; i >= len; i-- ) + { + unsigned int remainder = int_part.divide_by_ten(); + s[i] = static_cast<char>( '0' + remainder ); + + if( zero_digits ) + { + if( remainder == 0 ) + int_zeros ++; + else + zero_digits = false; + } + } + + // discard trailing zeros from int_part + s.discard( int_zeros ); + + if( s[len] == '0' ) + { + // int_digits was overestimated by one + s.remove( len ); + -- int_digits; + } + } + + // print fractional part + + int frac_digits = 0; + int frac_zeros = 0; + + if( ! frac_part.is_zero() ) + { + s += '.'; + + bool zero_digits = ( int_digits == 0 && fmt != SC_F ); + + double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word + - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] ) + - 1; + frac_zeros = (int) floor( frac_wl * log10( 2. ) ); + + scfx_rep temp; + sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) ); + frac_part = temp; + if( frac_part.m_msw == frac_part.size() - 1 ) + frac_part.resize_to( frac_part.size() + 1, 1 ); + + frac_digits = frac_zeros; + if( ! zero_digits ) + { + for( i = 0; i < frac_zeros; i ++ ) + s += '0'; + frac_zeros = 0; + } + + while( ! frac_part.is_zero() ) + { + frac_part.multiply_by_ten(); + int n = frac_part.m_mant[frac_part.m_msw + 1]; + + if( zero_digits ) + { + if( n == 0 ) + frac_zeros ++; + else + zero_digits = false; + } + + if( ! zero_digits ) + s += static_cast<char>( '0' + n ); + + frac_part.m_mant[frac_part.m_msw + 1] = 0; + frac_digits ++; + } + } + + // print exponent + + if( fmt != SC_F ) + { + if( frac_digits == 0 ) + scfx_print_exp( s, int_zeros ); + else if( int_digits == 0 ) + scfx_print_exp( s, - frac_zeros ); + } +} + +void +print_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params ) +{ + scfx_rep b = a; + + sc_numrep numrep2 = numrep; + + bool numrep_is_sm = ( numrep == SC_BIN_SM || + numrep == SC_OCT_SM || + numrep == SC_HEX_SM ); + + if( numrep_is_sm ) + { + if( b.is_neg() ) + { + s += '-'; + b = *neg_scfx_rep( a ); + } + switch( numrep ) + { + case SC_BIN_SM: + numrep2 = SC_BIN_US; + break; + case SC_OCT_SM: + numrep2 = SC_OCT_US; + break; + case SC_HEX_SM: + numrep2 = SC_HEX_US; + break; + default: + ; + } + } + + if( w_prefix != 0 ) { + scfx_print_prefix( s, numrep ); + } + + numrep = numrep2; + + int msb, lsb; + + if( params != 0 ) + { + msb = params->iwl() - 1; + lsb = params->iwl() - params->wl(); + + if( params->enc() == SC_TC_ && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) && + ! numrep_is_sm && + params->wl() > 1 ) + -- msb; + else if( params->enc() == SC_US_ && + ( numrep == SC_BIN || + numrep == SC_OCT || + numrep == SC_HEX || + numrep == SC_CSD ) ) + ++ msb; + } + else + { + if( b.is_zero() ) + { + msb = 0; + lsb = 0; + } + else + { + msb = ( b.m_msw - b.m_wp ) * bits_in_word + + scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1; + while( b.get_bit( msb ) == b.get_bit( msb - 1 ) ) + -- msb; + + if( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) + -- msb; + + lsb = ( b.m_lsw - b.m_wp ) * bits_in_word + + scfx_find_lsb( b.m_mant[ b.m_lsw ] ); + } + } + + int step; + + switch( numrep ) + { + case SC_BIN: + case SC_BIN_US: + case SC_CSD: + step = 1; + break; + case SC_OCT: + case SC_OCT_US: + step = 3; + break; + case SC_HEX: + case SC_HEX_US: + step = 4; + break; + default: + step = 0; + } + + msb = (int) ceil( double( msb + 1 ) / step ) * step - 1; + + lsb = (int) floor( double( lsb ) / step ) * step; + + if( msb < 0 ) + { + s += '.'; + if( fmt == SC_F ) + { + int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0; + for( int i = ( msb + 1 ) / step; i < 0; i ++ ) + { + if( sign < 10 ) + s += static_cast<char>( sign + '0' ); + else + s += static_cast<char>( sign + 'a' - 10 ); + } + } + } + + int i = msb; + while( i >= lsb ) + { + int value = 0; + for( int j = step - 1; j >= 0; -- j ) + { + value += static_cast<int>( b.get_bit( i ) ) << j; + -- i; + } + if( value < 10 ) + s += static_cast<char>( value + '0' ); + else + s += static_cast<char>( value + 'a' - 10 ); + if( i == -1 ) + s += '.'; + } + + if( lsb > 0 && fmt == SC_F ) + { + for( int i = lsb / step; i > 0; i -- ) + s += '0'; + } + + if( s[s.length() - 1] == '.' ) + s.discard( 1 ); + + if( fmt != SC_F ) + { + if( msb < 0 ) + scfx_print_exp( s, ( msb + 1 ) / step ); + else if( lsb > 0 ) + scfx_print_exp( s, lsb / step ); + } + + if( numrep == SC_CSD ) + scfx_tc2csd( s, w_prefix ); +} + +const char* +scfx_rep::to_string( sc_numrep numrep, int w_prefix, + sc_fmt fmt, const scfx_params* params ) const +{ + static scfx_string s; + + s.clear(); + + if( is_nan() ) + scfx_print_nan( s ); + else if( is_inf() ) + scfx_print_inf( s, is_neg() ); + else if( is_neg() && ! is_zero() && + ( numrep == SC_BIN_US || + numrep == SC_OCT_US || + numrep == SC_HEX_US ) ) + s += "negative"; + else if( numrep == SC_DEC || numrep == SC_NOBASE ) + sc_dt::print_dec( s, *this, w_prefix, fmt ); + else + sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params ); + + return s; +} + + +// ---------------------------------------------------------------------------- +// ADD +// +// add two mantissas of the same size +// result has the same size +// returns carry of operation +// ---------------------------------------------------------------------------- + +static inline +int +add_mants( int size, scfx_mant& result, + const scfx_mant& a, const scfx_mant& b ) +{ + unsigned int carry = 0; + + int index = 0; + + do + { + word x = a[index]; + word y = b[index]; + + y += carry; + carry = y < carry; + y += x; + carry += y < x; + result[index] = y; + } + while( ++ index < size ); + + return ( carry ? 1 : 0 ); +} + + +static inline +int +sub_mants( int size, scfx_mant& result, + const scfx_mant& a, const scfx_mant& b ) +{ + unsigned carry = 0; + + int index = 0; + + do + { + word x = a[index]; + word y = b[index]; + + y += carry; + carry = y < carry; + y = x - y; + carry += y > x; + result[index] = y; + } + while( ++ index < size ); + + return ( carry ? 1 : 0 ); +} + + +scfx_rep* +add_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() ) + { + result.set_inf( lhs.m_sign ); + return &result; + } + + if( rhs.is_inf() ) + { + result.set_inf( rhs.m_sign ); + return &result; + } + + // + // align operands if needed + // + + scfx_mant_ref lhs_mant; + scfx_mant_ref rhs_mant; + + int len_mant = lhs.size(); + int new_wp = lhs.m_wp; + + align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant ); + + // + // size the result mantissa + // + + result.resize_to( len_mant ); + result.m_wp = new_wp; + + // + // do it + // + + if( lhs.m_sign == rhs.m_sign ) + { + add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else + { + int cmp = compare_abs( lhs, rhs ); + + if( cmp == 1 ) + { + sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else if ( cmp == -1 ) + { + sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant ); + result.m_sign = rhs.m_sign; + } + else + { + result.m_mant.clear(); + result.m_sign = 1; + } + } + + result.find_sw(); + result.round( max_wl ); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// SUB +// +// sub two word's of the same size +// result has the same size +// returns carry of operation +// ---------------------------------------------------------------------------- + +static inline +int +sub_with_index( scfx_mant& a, int a_msw, int /*a_lsw*/, + const scfx_mant& b, int b_msw, int b_lsw ) +{ + unsigned carry = 0; + + int size = b_msw - b_lsw; + int a_index = a_msw - size; + int b_index = b_msw - size; + + do + { + word x = a[a_index]; + word y = b[b_index]; + + y += carry; + carry = y < carry; + y = x - y; + carry += y > x; + a[a_index] = y; + + a_index ++; + b_index ++; + } + while( size -- ); + + if( carry ) + { + // special case: a[a_msw + 1 ] == 1 + a[a_msw + 1] = 0; + } + + return ( carry ? 1 : 0 ); +} + + +scfx_rep* +sub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() ) + { + result.set_inf( lhs.m_sign ); + return &result; + } + + if( rhs.is_inf() ) + { + result.set_inf( -1 * rhs.m_sign ); + return &result; + } + + // + // align operands if needed + // + + scfx_mant_ref lhs_mant; + scfx_mant_ref rhs_mant; + + int len_mant = lhs.size(); + int new_wp = lhs.m_wp; + + align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant ); + + // + // size the result mantissa + // + + result.resize_to( len_mant ); + result.m_wp = new_wp; + + // + // do it + // + + if( lhs.m_sign != rhs.m_sign ) + { + add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else + { + int cmp = compare_abs( lhs, rhs ); + + if( cmp == 1 ) + { + sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant ); + result.m_sign = lhs.m_sign; + } + else if ( cmp == -1 ) + { + sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant ); + result.m_sign = -rhs.m_sign; + } else { + result.m_mant.clear(); + result.m_sign = 1; + } + } + + result.find_sw(); + result.round( max_wl ); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// MUL +// ---------------------------------------------------------------------------- + +union word_short +{ + word l; + struct + { +#if defined( SC_BIG_ENDIAN ) + half_word u; + half_word l; +#elif defined( SC_LITTLE_ENDIAN ) + half_word l; + half_word u; +#endif + } s; +}; + + +#if defined( SC_BIG_ENDIAN ) +static const int half_word_incr = -1; +#elif defined( SC_LITTLE_ENDIAN ) +static const int half_word_incr = 1; +#endif + + +void +multiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs, + int max_wl ) +{ + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() + || (lhs.is_inf() && rhs.is_zero()) + || (lhs.is_zero() && rhs.is_inf()) ) + { + result.set_nan(); + return; + } + + if( lhs.is_inf() || rhs.is_inf() ) + { + result.set_inf( lhs.m_sign * rhs.m_sign ); + return; + } + + if( lhs.is_zero() || rhs.is_zero() ) { + result.set_zero( lhs.m_sign * rhs.m_sign ); + return; + } + + // + // do it + // + + int len_lhs = lhs.m_msw - lhs.m_lsw + 1; + int len_rhs = rhs.m_msw - rhs.m_lsw + 1; + + int new_size = sc_max( min_mant, len_lhs + len_rhs ); + int new_wp = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw ); + int new_sign = lhs.m_sign * rhs.m_sign; + + result.resize_to( new_size ); + result.m_mant.clear(); + result.m_wp = new_wp; + result.m_sign = new_sign; + result.m_state = scfx_rep::normal; + + half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw ); + half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw ); + + half_word *t = result.m_mant.half_addr(); + + len_lhs <<= 1; + len_rhs <<= 1; + + int i1, i2; + + for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr ) + { + word_short ls; + ls.l = 0; + + half_word v1 = s1[i1]; + + for( i2 = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr ) + { + ls.l += v1 * s2[i2]; + ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l ); + ls.s.u = 0; + } + + t[i2] = ls.s.l; + t += half_word_incr; + } + + result.find_sw(); + result.round( max_wl ); +} + + +// ---------------------------------------------------------------------------- +// DIV +// ---------------------------------------------------------------------------- + +scfx_rep* +div_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl ) +{ + scfx_rep& result = *new scfx_rep; + + // + // check for special cases + // + + if( lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) || + (lhs.is_zero() && rhs.is_zero()) ) + { + result.set_nan(); + return &result; + } + + if( lhs.is_inf() || rhs.is_zero() ) + { + result.set_inf( lhs.m_sign * rhs.m_sign ); + return &result; + } + + if( lhs.is_zero() || rhs.is_inf() ) + { + result.set_zero( lhs.m_sign * rhs.m_sign ); + return &result; + } + + // + // do it + // + + // compute one bit more for rounding + div_wl ++; + + result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) ); + result.m_mant.clear(); + result.m_sign = lhs.m_sign * rhs.m_sign; + + int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] ) + + ( lhs.m_msw - lhs.m_wp ) * bits_in_word; + int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] ) + + ( rhs.m_msw - rhs.m_wp ) * bits_in_word; + + int msb_res = msb_lhs - msb_rhs; + int to_shift = -msb_res % bits_in_word; + int result_index; + + int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0; + + result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word; + result.m_wp = (result.size() - c) - msb_res / bits_in_word; + + scfx_rep remainder = lhs; + + // align msb from remainder to msb from rhs + remainder.lshift( to_shift ); + + // make sure msw( remainder ) < size - 1 + if( remainder.m_msw == remainder.size() - 1 ) + remainder.resize_to( remainder.size() + 1, 1 ); + + // make sure msw( remainder ) >= msw( rhs )! + int msw_diff = rhs.m_msw - remainder.m_msw; + if (msw_diff > 0) + remainder.resize_to( remainder.size() + msw_diff, -1 ); + + int counter; + + for( counter = div_wl; counter && ! remainder.is_zero(); counter -- ) + { + if( compare_msw_ff( rhs, remainder ) <= 0 ) + { + result.set_bin( result_index ); + sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw, + rhs.m_mant, rhs.m_msw, rhs.m_lsw ); + } + result_index --; + remainder.shift_left( 1 ); + remainder.m_lsw = remainder.find_lsw(); + } + + // perform convergent rounding, if needed + if( counter == 0 ) + { + int index = result_index + 1 - result.m_wp * bits_in_word; + + scfx_index x = result.calc_indices( index ); + scfx_index x1 = result.calc_indices( index + 1 ); + + if( result.o_bit_at( x ) && result.o_bit_at( x1 ) ) + result.q_incr( x ); + + result.m_r_flag = true; + } + + result.find_sw(); + + return &result; +} + + +// ---------------------------------------------------------------------------- +// destructive shift mantissa to the left +// ---------------------------------------------------------------------------- + +void +scfx_rep::lshift( int n ) +{ + if( n == 0 ) + return; + + if( n < 0 ) + { + rshift( -n ); + return; + } + + if( is_normal() ) + { + int shift_bits = n % bits_in_word; + int shift_words = n / bits_in_word; + + // resize if needed + if( m_msw == size() - 1 && + scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits ) + resize_to( size() + 1, 1 ); + + // do it + m_wp -= shift_words; + shift_left( shift_bits ); + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// destructive shift mantissa to the right +// ---------------------------------------------------------------------------- + +void +scfx_rep::rshift( int n ) +{ + if( n == 0 ) + return; + + if( n < 0 ) + { + lshift( -n ); + return; + } + + if( is_normal() ) + { + int shift_bits = n % bits_in_word; + int shift_words = n / bits_in_word; + + // resize if needed + if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits ) + resize_to( size() + 1, -1 ); + + // do it + m_wp += shift_words; + shift_right( shift_bits ); + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// FRIEND FUNCTION : compare_abs +// +// Compares the absolute values of two scfx_reps, excluding the special cases. +// ---------------------------------------------------------------------------- + +int +compare_abs( const scfx_rep& a, const scfx_rep& b ) +{ + // check for zero + + word a_word = a.m_mant[a.m_msw]; + word b_word = b.m_mant[b.m_msw]; + + if( a_word == 0 || b_word == 0 ) + { + if( a_word != 0 ) + return 1; + if( b_word != 0 ) + return -1; + return 0; + } + + // compare msw index + + int a_msw = a.m_msw - a.m_wp; + int b_msw = b.m_msw - b.m_wp; + + if( a_msw > b_msw ) + return 1; + + if( a_msw < b_msw ) + return -1; + + // compare content + + int a_i = a.m_msw; + int b_i = b.m_msw; + + while( a_i >= a.m_lsw && b_i >= b.m_lsw ) + { + a_word = a.m_mant[a_i]; + b_word = b.m_mant[b_i]; + if( a_word > b_word ) + return 1; + if( a_word < b_word ) + return -1; + -- a_i; + -- b_i; + } + + bool a_zero = true; + while( a_i >= a.m_lsw ) + { + a_zero = a_zero && ( a.m_mant[a_i] == 0 ); + -- a_i; + } + + bool b_zero = true; + while( b_i >= b.m_lsw ) + { + b_zero = b_zero && ( b.m_mant[b_i] == 0 ); + -- b_i; + } + + // assertion: a_zero || b_zero == true + + if( ! a_zero && b_zero ) + return 1; + + if( a_zero && ! b_zero ) + return -1; + + return 0; +} + + +// ---------------------------------------------------------------------------- +// FRIEND FUNCTION : cmp_scfx_rep +// +// Compares the values of two scfx_reps, including the special cases. +// ---------------------------------------------------------------------------- + +int +cmp_scfx_rep( const scfx_rep& a, const scfx_rep& b ) +{ + // handle special cases + + if( a.is_nan() || b.is_nan() ) + { +#if 0 + if( a.is_nan() && b.is_nan() ) + { + return 0; + } +#endif + return 2; + } + + if( a.is_inf() || b.is_inf() ) + { + if( a.is_inf() ) + { + if( ! a.is_neg() ) + { + if( b.is_inf() && ! b.is_neg() ) + { + return 0; + } + else + { + return 1; + } + } + else + { + if( b.is_inf() && b.is_neg() ) + { + return 0; + } + else + { + return -1; + } + } + } + if( b.is_inf() ) + { + if( ! b.is_neg() ) + { + return -1; + } + else + { + return 1; + } + } + } + + if( a.is_zero() && b.is_zero() ) + { + return 0; + } + + // compare sign + + if( a.m_sign != b.m_sign ) + { + return a.m_sign; + } + + return ( a.m_sign * compare_abs( a, b ) ); +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : quantization +// +// Performs destructive quantization. +// ---------------------------------------------------------------------------- + +void +scfx_rep::quantization( const scfx_params& params, bool& q_flag ) +{ + scfx_index x = calc_indices( params.iwl() - params.wl() ); + + if( x.wi() < 0 ) + return; + + if( x.wi() >= size() ) + resize_to( x.wi() + 1, 1 ); + + bool qb = q_bit( x ); + bool qz = q_zero( x ); + + q_flag = ( qb || ! qz ); + + if( q_flag ) + { + switch( params.q_mode() ) + { + case SC_TRN: // truncation + { + if( is_neg() ) + q_incr( x ); + break; + } + case SC_RND: // rounding to plus infinity + { + if( ! is_neg() ) + { + if( qb ) + q_incr( x ); + } + else + { + if( qb && ! qz ) + q_incr( x ); + } + break; + } + case SC_TRN_ZERO: // truncation to zero + { + break; + } + case SC_RND_INF: // rounding to infinity + { + if( qb ) + q_incr( x ); + break; + } + case SC_RND_CONV: // convergent rounding + { + if( (qb && ! qz) || (qb && qz && q_odd( x )) ) + q_incr( x ); + break; + } + case SC_RND_ZERO: // rounding to zero + { + if( qb && ! qz ) + q_incr( x ); + break; + } + case SC_RND_MIN_INF: // rounding to minus infinity + { + if( ! is_neg() ) + { + if( qb && ! qz ) + q_incr( x ); + } + else + { + if( qb ) + q_incr( x ); + } + break; + } + default: + ; + } + q_clear( x ); + + find_sw(); + } +} + + +// ---------------------------------------------------------------------------- +// PRIVATE METHOD : overflow +// +// Performs destructive overflow handling. +// ---------------------------------------------------------------------------- + +void +scfx_rep::overflow( const scfx_params& params, bool& o_flag ) +{ + scfx_index x = calc_indices( params.iwl() - 1 ); + + if( x.wi() >= size() ) + resize_to( x.wi() + 1, 1 ); + + if( x.wi() < 0 ) + { + resize_to( size() - x.wi(), -1 ); + x.wi( 0 ); + } + + bool zero_left = o_zero_left( x ); + bool bit_at = o_bit_at( x ); + bool zero_right = o_zero_right( x ); + + bool under = false; + bool over = false; + + sc_enc enc = params.enc(); + + if( enc == SC_TC_ ) + { + if( is_neg() ) + { + if( params.o_mode() == SC_SAT_SYM ) + under = ( ! zero_left || bit_at ); + else + under = (! zero_left || (zero_left && bit_at && ! zero_right)); + } + else + over = ( ! zero_left || bit_at ); + } + else + { + if( is_neg() ) + under = ( ! is_zero() ); + else + over = ( ! zero_left ); + } + + o_flag = ( under || over ); + + if( o_flag ) + { + scfx_index x2 = calc_indices( params.iwl() - params.wl() ); + + if( x2.wi() < 0 ) + { + resize_to( size() - x2.wi(), -1 ); + x.wi( x.wi() - x2.wi() ); + x2.wi( 0 ); + } + + switch( params.o_mode() ) + { + case SC_WRAP: // wrap-around + { + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + // wrap-around all 'wl' bits + toggle_tc(); + o_extend( x, enc ); + toggle_tc(); + } + else if( n_bits < params.wl() ) + { + scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits; + // saturate most significant 'n_bits' bits + toggle_tc(); + o_set( x, x3, enc, under ); + o_extend( x, enc ); + toggle_tc(); + } + else + { + // saturate all 'wl' bits + if( under ) + o_set_low( x, enc ); + else + o_set_high( x, x2, enc ); + } + break; + } + case SC_SAT: // saturation + { + if( under ) + o_set_low( x, enc ); + else + o_set_high( x, x2, enc ); + break; + } + case SC_SAT_SYM: // symmetrical saturation + { + if( under ) + { + if( enc == SC_TC_ ) + o_set_high( x, x2, SC_TC_, -1 ); + else + o_set_low( x, SC_US_ ); + } + else + o_set_high( x, x2, enc ); + break; + } + case SC_SAT_ZERO: // saturation to zero + { + set_zero(); + break; + } + case SC_WRAP_SM: // sign magnitude wrap-around + { + SC_ERROR_IF_( enc == SC_US_, + sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ ); + + int n_bits = params.n_bits(); + + if( n_bits == 0 ) + { + scfx_index x4 = calc_indices( params.iwl() ); + + if( x4.wi() >= size() ) + resize_to( x4.wi() + 1, 1 ); + + toggle_tc(); + if( o_bit_at( x4 ) != o_bit_at( x ) ) + o_invert( x2 ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else if( n_bits == 1 ) + { + toggle_tc(); + if( is_neg() != o_bit_at( x ) ) + o_invert( x2 ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else if( n_bits < params.wl() ) + { + scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits ); + scfx_index x4 = calc_indices( params.iwl() - n_bits ); + + // wrap-around least significant 'wl - n_bits' bits; + // saturate most significant 'n_bits' bits + toggle_tc(); + if( is_neg() == o_bit_at( x4 ) ) + o_invert( x2 ); + o_set( x, x3, SC_TC_, under ); + o_extend( x, SC_TC_ ); + toggle_tc(); + } + else + { + 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. +// ---------------------------------------------------------------------------- + +void +scfx_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 +// ---------------------------------------------------------------------------- + +void +align( 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 +// ---------------------------------------------------------------------------- + +int +compare_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 int +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_rep::set_bin( int i ) +{ + m_mant[i >> 5] |= 1 << ( i & 31 ); +} + + +// ---------------------------------------------------------------------------- +// set three bits +// ---------------------------------------------------------------------------- + +void +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_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. +// ---------------------------------------------------------------------------- + +void +scfx_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. +// ---------------------------------------------------------------------------- + +void +scfx_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. +// ---------------------------------------------------------------------------- + +bool +scfx_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. +// ---------------------------------------------------------------------------- + +bool +scfx_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. +// ---------------------------------------------------------------------------- + +bool +scfx_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 +// ---------------------------------------------------------------------------- + +bool +scfx_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; +} + +bool +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_rep::print( ::std::ostream& os ) const +{ + os << to_string( SC_DEC, -1, SC_E ); +} + + +// ---------------------------------------------------------------------------- +// METHOD : dump +// ---------------------------------------------------------------------------- + +void +scfx_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 +// ---------------------------------------------------------------------------- + +void +scfx_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. +// ---------------------------------------------------------------------------- + +void +scfx_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! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h new file mode 100644 index 000000000..c5b76ce54 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_rep.h @@ -0,0 +1,842 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_rep.h - + + 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.h,v $ +// Revision 1.6 2011/08/24 22:05:43 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.5 2011/07/25 10:20:29 acg +// Andy Goodrich: check in aftermath of call to automake. +// +// Revision 1.4 2010/12/07 20:09:08 acg +// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix +// +// Revision 1.3 2010/08/03 15:54:52 acg +// Andy Goodrich: formatting. +// +// Revision 1.2 2010/03/15 18:29:01 acg +// Andy Goodrich: Moved default argument specifications from friend +// declarations to the actual function signatures. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.4 2006/03/13 20:24:27 acg +// Andy Goodrich: Addition of function declarations, e.g., neg_scfx_rep(), +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:53:58 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef SCFX_REP_H +#define SCFX_REP_H + + +#include <climits> + +#include "sysc/datatypes/fx/scfx_mant.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/scfx_string.h" + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_index; +class scfx_rep; + +// forward class declarations +class sc_bv_base; +class sc_signed; +class sc_unsigned; + +// function declarations +void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* neg_scfx_rep( const scfx_rep& ); +scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_DIV_WL_ ); +scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, + int max_wl = SC_DEFAULT_MAX_WL_ ); +scfx_rep* lsh_scfx_rep( const scfx_rep&, int ); +scfx_rep* rsh_scfx_rep( const scfx_rep&, int ); +int cmp_scfx_rep( const scfx_rep&, const scfx_rep& ); + + +const int min_mant = 4; + +const int bits_in_int = sizeof(int) * CHAR_BIT; +const int bits_in_word = sizeof(word) * CHAR_BIT; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_index +// ---------------------------------------------------------------------------- + +class scfx_index +{ + +public: + + scfx_index( int wi_, int bi_ ) : m_wi( wi_ ), m_bi( bi_ ) {} + + int wi() const { return m_wi; } + int bi() const { return m_bi; } + + void wi( int wi_ ) { m_wi = wi_; } + +private: + + int m_wi; + int m_bi; + +}; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_rep +// +// Arbitrary-precision fixed-point implementation class. +// ---------------------------------------------------------------------------- + +class scfx_rep +{ + enum state + { + normal, + infinity, + not_a_number + }; + +public: + + // constructors + + scfx_rep(); + explicit scfx_rep( int ); + explicit scfx_rep( unsigned int ); + explicit scfx_rep( long ); + explicit scfx_rep( unsigned long ); + explicit scfx_rep( double ); + explicit scfx_rep( const char* ); + explicit scfx_rep( int64 ); + explicit scfx_rep( uint64 ); + explicit scfx_rep( const sc_signed& ); + explicit scfx_rep( const sc_unsigned& ); + + + // copy constructor + + scfx_rep( const scfx_rep& ); + + + // destructor + + ~scfx_rep(); + + + void* operator new( std::size_t ); + void operator delete( void*, std::size_t ); + + + void from_string( const char*, int ); + + double to_double() const; + + const char* to_string( sc_numrep, + int, + sc_fmt, + const scfx_params* = 0 ) const; + + + // assignment operator + + void operator = ( const scfx_rep& ); + + friend void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int ); + + friend scfx_rep* neg_scfx_rep( const scfx_rep& ); + friend scfx_rep* mult_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* div_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* add_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* sub_scfx_rep( const scfx_rep&, const scfx_rep&, int ); + friend scfx_rep* lsh_scfx_rep( const scfx_rep&, int ); + friend scfx_rep* rsh_scfx_rep( const scfx_rep&, int ); + + void lshift( int ); + void rshift( int ); + + friend int cmp_scfx_rep( const scfx_rep&, const scfx_rep& ); + + void cast( const scfx_params&, bool&, bool& ); + + bool is_neg() const; + bool is_zero() const; + bool is_nan() const; + bool is_inf() const; + bool is_normal() const; + + void set_zero( int = 1 ); + void set_nan(); + void set_inf( int ); + + bool get_bit( int ) const; + bool set( int, const scfx_params& ); + bool clear( int, const scfx_params& ); + + bool get_slice( int, int, const scfx_params&, sc_bv_base& ) const; + bool set_slice( int, int, const scfx_params&, const sc_bv_base& ); + + void print( ::std::ostream& ) const; + void dump( ::std::ostream& ) const; + + void get_type( int&, int&, sc_enc& ) const; + + friend scfx_rep* quantization_scfx_rep( const scfx_rep&, + const scfx_params&, + bool& ); + friend scfx_rep* overflow_scfx_rep( const scfx_rep&, + const scfx_params&, + bool& ); + + bool rounding_flag() const; + +private: + + friend void align( const scfx_rep&, const scfx_rep&, int&, int&, + scfx_mant_ref&, scfx_mant_ref& ); + friend int compare_msw( const scfx_rep&, const scfx_rep& ); + friend int compare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs ); + unsigned int divide_by_ten(); + int find_lsw() const; + int find_msw() const; + void find_sw(); + void multiply_by_ten(); + void normalize( int ); + scfx_mant* resize( int, int ) const; + void set_bin( int ); + void set_oct( int, int ); + void set_hex( int, int ); + void shift_left( int ); + void shift_right( int ); + + const scfx_index calc_indices( int ) const; + + void o_extend( const scfx_index&, sc_enc ); + bool o_bit_at( const scfx_index& ) const; + bool o_zero_left( const scfx_index& ) const; + bool o_zero_right( const scfx_index& ) const; + void o_set_low( const scfx_index&, sc_enc ); + void o_set_high( const scfx_index&, const scfx_index&, sc_enc, int = 1 ); + void o_set( const scfx_index&, const scfx_index&, sc_enc, bool ); + void o_invert( const scfx_index& ); + bool q_bit( const scfx_index& ) const; + void q_clear( const scfx_index& ); + void q_incr( const scfx_index& ); + bool q_odd( const scfx_index& ) const; + bool q_zero( const scfx_index& ) const; + + void resize_to( int, int = 0 ); + int size() const; + void toggle_tc(); + + friend void print_dec( scfx_string&, const scfx_rep&, int, sc_fmt ); + friend void print_other( scfx_string&, const scfx_rep&, sc_numrep, int, + sc_fmt, const scfx_params* ); + + void quantization( const scfx_params&, bool& ); + void overflow( const scfx_params&, bool& ); + + friend int compare_abs( const scfx_rep&, const scfx_rep& ); + + void round( int ); + +private: + + scfx_mant m_mant; // mantissa (bits of the value). + int m_wp; // index of highest order word in value. + int m_sign; // sign of value. + state m_state; // value state, e.g., normal, inf, etc. + int m_msw; // index of most significant non-zero word. + int m_lsw; // index of least significant non-zero word. + bool m_r_flag; // true if founding occurred. + +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_rep::set_zero( int sign ) +{ + m_mant.clear(); + m_wp = m_msw = m_lsw = 0; + m_sign = sign; + m_state = normal; +} + +inline +void +scfx_rep::set_nan() +{ + m_mant.resize_to( min_mant ); + m_state = not_a_number; +} + +inline +void +scfx_rep::set_inf( int sign ) +{ + m_mant.resize_to( min_mant ); + m_state = infinity; + m_sign = sign; +} + + +// constructors + +inline +scfx_rep::scfx_rep( const char* s ) +: m_mant( min_mant ), m_wp( 2 ), m_sign( 1 ), m_state( normal ), + m_msw(0), m_lsw(0), m_r_flag( false ) +{ + from_string( s, SC_DEFAULT_CTE_WL_ ); +} + + +// destructor + +inline +scfx_rep::~scfx_rep() +{} + + +// assignment operator + +inline +void +scfx_rep::operator = ( const scfx_rep& f ) +{ + if( &f != this ) + { + m_mant = f.m_mant; + m_wp = f.m_wp; + m_sign = f.m_sign; + m_state = f.m_state; + m_msw = f.m_msw; + m_lsw = f.m_lsw; + round( SC_DEFAULT_MAX_WL_ ); + } +} + +inline +scfx_rep* +neg_scfx_rep( const scfx_rep& a ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.m_sign = - c.m_sign; + return &c; +} + +inline +scfx_rep* +mult_scfx_rep( const scfx_rep& a, const scfx_rep& b, int max_wl ) +{ + scfx_rep& c = *new scfx_rep; + sc_dt::multiply( c, a, b, max_wl ); + return &c; +} + +inline +scfx_rep* +lsh_scfx_rep( const scfx_rep& a, int b ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.lshift( b ); + return &c; +} + +inline +scfx_rep* +rsh_scfx_rep( const scfx_rep& a, int b ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.rshift( b ); + return &c; +} + +inline +int +scfx_rep::size() const +{ + return m_mant.size(); +} + +inline +bool +scfx_rep::is_neg() const +{ + return ( m_sign == -1 ); +} + +inline +bool +scfx_rep::is_zero() const +{ + if( m_state != normal ) + return false; + + for( int i = 0; i < size(); i ++ ) + { + if( m_mant[i] ) + return false; + } + + return true; +} + +inline +bool +scfx_rep::is_nan() const +{ + return ( m_state == not_a_number ); +} + +inline +bool +scfx_rep::is_inf() const +{ + return ( m_state == infinity ); +} + +inline +bool +scfx_rep::is_normal() const +{ + return ( m_state == normal ); +} + +inline +scfx_rep* +quantization_scfx_rep( const scfx_rep& a, + const scfx_params& params, + bool& q_flag ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.quantization( params, q_flag ); + return &c; +} + +inline +scfx_rep* +overflow_scfx_rep( const scfx_rep& a, + const scfx_params& params, + bool& o_flag ) +{ + scfx_rep& c = *new scfx_rep( a ); + c.overflow( params, o_flag ); + return &c; +} + +inline +bool +scfx_rep::rounding_flag() const +{ + return m_r_flag; +} + +inline +void +scfx_rep::resize_to( int new_size, int restore ) +{ + if( restore == -1 ) + { + int size_incr = new_size - size(); + m_wp += size_incr; + m_msw += size_incr; + m_lsw += size_incr; + } + m_mant.resize_to( new_size, restore ); +} + +inline +const scfx_index +scfx_rep::calc_indices( int n ) const +{ + int wi = n / bits_in_word + m_wp; + int bi = n % bits_in_word; + + if( bi < 0 ) + { + bi += bits_in_word; + -- wi; + } + + return scfx_index( wi, bi ); +} + +inline +void +scfx_rep::o_extend( const scfx_index& x, sc_enc enc ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + if( enc == SC_US_ || ( m_mant[wi] & ( ((word)1) << bi ) ) == 0 ) + { + if( bi != bits_in_word - 1 ) + m_mant[wi] &= ~( ((word)-1) << ( bi + 1 ) ); + for( int i = wi + 1; i < size(); ++ i ) + m_mant[i] = 0; + m_sign = 1; + } + else + { + if( bi != bits_in_word - 1 ) + m_mant[wi] |= ( ((word)-1) << ( bi + 1 ) ); + for( int i = wi + 1; i < size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + m_sign = -1; + } +} + +inline +bool +scfx_rep::o_bit_at( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0; +} + +inline +bool +scfx_rep::o_zero_left( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero = true; + if( bi != bits_in_word - 1 ) + zero = ( m_mant[wi] & ( ((word)-1) << ( bi + 1 ) ) ) == 0; + for( int i = wi + 1; i < size(); ++ i ) + zero = zero && m_mant[i] == 0; + + return zero; +} + +inline +bool +scfx_rep::o_zero_right( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero = ( m_mant[wi] & ~( ((word)-1) << bi ) ) == 0; + for( int i = wi - 1; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + + return zero; +} + +inline +void +scfx_rep::o_set_low( const scfx_index& x, sc_enc enc ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + m_mant.clear(); + + if( enc == SC_TC_ ) + { + m_mant[wi] |= ( ((word)1) << bi ); + m_sign = -1; + } + else + m_sign = 1; +} + +inline +void +scfx_rep::o_set_high( const scfx_index& x, const scfx_index& x2, + sc_enc enc, int sign ) +{ + int wi = x.wi(); + int bi = x.bi(); + int wi2 = x2.wi(); + int bi2 = x2.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + SC_ASSERT_( wi2 >= 0 && wi2 < size(), "word index out of range" ); + + int i; + + for( i = 0; i < size(); ++ i ) + m_mant[i] = static_cast<word>( -1 ); + + m_mant[wi] &= ~( ((word)-1) << bi ); + for( i = wi + 1; i < size(); ++ i ) + m_mant[i] = 0; + + m_mant[wi2] &= ( ((word)-1) << bi2 ); + for( i = wi2 - 1; i >= 0; -- i ) + m_mant[i] = 0; + + if( enc == SC_TC_ ) + m_sign = sign; + else + { + m_mant[wi] |= ( ((word)1) << bi ); + m_sign = 1; + } +} + +inline +void +scfx_rep::o_set( const scfx_index& x, const scfx_index& x3, + sc_enc enc, bool under ) +{ + int wi = x.wi(); + int bi = x.bi(); + int wi3 = x3.wi(); + int bi3 = x3.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + SC_ASSERT_( wi3 >= 0 && wi3 < size(), "word index out of range" ); + + if( bi3 != bits_in_word - 1 ) + { + if( under ) + m_mant[wi3] &= ~( ((word)-1) << ( bi3 + 1 ) ); + else + m_mant[wi3] |= ( ((word)-1) << ( bi3 + 1 ) ); + } + for( int i = wi3 + 1; i < size(); ++ i ) + { + if( under ) + m_mant[i] = 0; + else + m_mant[i] = static_cast<word>( -1 ); + } + + if( enc == SC_TC_ ) + { + if( under ) + m_mant[wi] |= ( ((word)1) << bi ); + else + m_mant[wi] &= ~( ((word)1) << bi ); + } +} + +inline +void +scfx_rep::o_invert( const scfx_index& x2 ) +{ + int wi2 = x2.wi(); + int bi2 = x2.bi(); + + m_mant[wi2] ^= ( ((word)-1) << bi2 ); + for( int i = wi2 + 1; i < size(); ++ i ) + m_mant[i] = ~ m_mant[i]; +} + +inline +bool +scfx_rep::q_bit( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + if( bi != 0 ) + return ( m_mant[wi] & ( ((word)1) << ( bi - 1 ) ) ) != 0; + else if( wi != 0 ) + return ( m_mant[wi - 1] & ( ((word)1) << ( bits_in_word - 1 ) ) ) != 0; + else + return false; +} + +inline +void +scfx_rep::q_clear( const scfx_index& x ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + m_mant[wi] &= ( ((word)-1) << bi ); + for( int i = wi - 1; i >= 0; -- i ) + m_mant[i] = 0; +} + +inline +void +scfx_rep::q_incr( const scfx_index& x ) +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + word old_val = m_mant[wi]; + m_mant[wi] += ( ((word)1) << bi ); + if( m_mant[wi] <= old_val ) + { + if( wi + 1 == size() ) + resize_to( size() + 1, 1 ); + + for( int i = wi + 1; i < size(); ++ i ) + { + if( ++ m_mant[i] != 0 ) + break; + } + } +} + +inline +bool +scfx_rep::q_odd( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + return ( m_mant[wi] & ( ((word)1) << bi ) ) != 0; +} + +inline +bool +scfx_rep::q_zero( const scfx_index& x ) const +{ + int wi = x.wi(); + int bi = x.bi(); + + SC_ASSERT_( wi >= 0 && wi < size(), "word index out of range" ); + + bool zero; + + if( bi != 0 ) + { + zero = ( m_mant[wi] & ~( ((word)-1) << (bi - 1) ) ) == 0; + for( int i = wi - 1; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + } + else if( wi != 0 ) + { + zero = ( m_mant[wi - 1] & ~( ((word)-1) << (bits_in_word - 1) ) ) == 0; + for( int i = wi - 2; i >= 0; -- i ) + zero = zero && m_mant[i] == 0; + } + else + zero = true; + + return zero; +} + +inline +int +scfx_rep::find_lsw() const +{ + for( int i = 0; i < size(); i ++ ) + { + if( m_mant[i] ) + return i; + } + return 0; +} + +inline +int +scfx_rep::find_msw() const +{ + for( int i = size() - 1; i >= 0; i -- ) + { + if( m_mant[i] ) + return i; + } + return 0; +} + +inline +void +scfx_rep::find_sw() +{ + m_lsw = find_lsw(); + m_msw = find_msw(); +} + +inline +void +scfx_rep::toggle_tc() +{ + if( is_neg() ) + { + complement( m_mant, m_mant, m_mant.size() ); + inc( m_mant ); + } +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_string.h b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h new file mode 100644 index 000000000..338031ccc --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_string.h @@ -0,0 +1,232 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_string.h - + + 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_string.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.2 2006/01/03 23:18:34 acg +// Changed copyright to include 2006. +// +// Revision 1.1.1.1 2005/12/19 23:16:43 acg +// First check in of SystemC 2.1 into its own archive. +// +// Revision 1.9 2005/09/15 23:02:03 acg +// Added std:: prefix to appropriate methods and types to get around +// issues with the Edison Front End. +// +// Revision 1.8 2005/06/07 17:27:02 acg +// Fixed bug in scfx_string::operator += where an array reference was used +// rather than the [] operator. This meant that the buffer may have been +// accessed beyond its allocated storage. +// + +#ifndef SCFX_STRING_H +#define SCFX_STRING_H + +#include <cstdio> + + +namespace sc_dt +{ + +// classes defined in this module +class scfx_string; + + +// ---------------------------------------------------------------------------- +// CLASS : scfx_string +// +// Simple string class for internal use. +// ---------------------------------------------------------------------------- + +class scfx_string +{ + void resize( std::size_t ); + +public: + + scfx_string(); + + ~scfx_string(); + + int length() const; + + void clear(); + + char& operator [] ( int ); + + void append( int ); + void discard( int ); + void remove( int ); + + void operator += ( char ); + void operator += ( const char* ); + + operator const char* (); + +private: + + std::size_t m_len; + std::size_t m_alloc; + char* m_buffer; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +void +scfx_string::resize( std::size_t i ) +{ + do { + m_alloc *= 2; + } while( i >= m_alloc ); + + char* temp = new char[m_alloc]; + + for( int j = 0; j < (int) m_len; ++ j ) { + temp[j] = m_buffer[j]; + } + temp[m_len] = 0; + + delete [] m_buffer; + m_buffer = temp; +} + + +inline +scfx_string::scfx_string() +: m_len( 0 ), m_alloc( BUFSIZ ), m_buffer( new char[m_alloc] ) +{ + m_buffer[m_len] = 0; +} + + +inline +scfx_string::~scfx_string() +{ + delete [] m_buffer; +} + + +inline +int +scfx_string::length() const +{ + return m_len; +} + + +inline +void +scfx_string::clear() +{ + m_len = 0; + m_buffer[m_len] = 0; +} + + +inline +char& +scfx_string::operator [] ( int i ) +{ + if( i >= (int) m_alloc ) { + resize( i ); + } + return m_buffer[i]; +} + + +inline +void +scfx_string::append( int n ) +{ + m_len += n; + m_buffer[m_len] = 0; +} + +inline +void +scfx_string::discard( int n ) +{ + m_len -= n; + m_buffer[m_len] = 0; +} + +inline +void +scfx_string::remove( int i ) +{ + for( int j = i + 1; j < (int) m_len; ++ j ) + m_buffer[j - 1] = m_buffer[j]; + -- m_len; + m_buffer[m_len] = 0; +} + + +inline +void +scfx_string::operator += ( char c ) +{ + this->operator [] ( m_len ) = c; + m_len ++; + this->operator [] ( m_len ) = 0; +} + +inline +void +scfx_string::operator += ( const char* s ) +{ + while( *s ) + (*this) += *s ++; +} + + +inline +scfx_string::operator const char*() +{ + m_buffer[m_len] = 0; + return m_buffer; +} + +} // namespace sc_dt + + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp new file mode 100644 index 000000000..0735a6c25 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.cpp @@ -0,0 +1,176 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_utils.cpp - + + Original Author: 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_utils.cpp,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// 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/datatypes/fx/scfx_utils.h" + + +namespace sc_dt +{ + +void +scfx_tc2csd( scfx_string& s, int w_prefix ) +{ + if( w_prefix != 0 ) { + SC_ASSERT_( s[0] == '0' && s[1] == 'c' && + s[2] == 's' && s[3] == 'd', "invalid prefix" ); + } + + scfx_string csd; + + // copy bits from 's' into 'csd'; skip prefix, point, and exponent + int i = 0; + int j = (w_prefix != 0 ? 4 : 0); + while( s[j] ) + { + if( s[j] == '0' || s[j] == '1' ) + csd[i ++] = s[j]; + else if( s[j] != '.' ) + break; + ++ j; + } + csd[i] = '\0'; + + // convert 'csd' from two's complement to csd + -- i; + while( i >= 0 ) + { + if( csd[i] == '0' ) + -- i; + else + { + if( i > 0 && csd[i - 1] == '0' ) + -- i; + else if( i == 0 ) + csd[i --] = '-'; + else + { // i > 0 && csd[i - 1] == '1' + csd[i --] = '-'; + while( i >= 0 && csd[i] == '1' ) + csd[i --] = '0'; + if( i > 0 ) + csd[i] = '1'; + else if( i == 0 ) + csd[i --] = '1'; + } + } + } + + // copy bits from 'csd' back into 's' + i = 0; + j = (w_prefix != 0 ? 4 : 0); + while( csd[i] ) + { + if( s[j] == '.' ) + ++ j; + s[j ++] = csd[i ++]; + } +} + + +void +scfx_csd2tc( scfx_string& csd ) +{ + SC_ASSERT_( csd[0] == '0' && csd[1] == 'c' && + csd[2] == 's' && csd[3] == 'd', "invalid prefix" ); + + scfx_string s; + + // copy bits from 'csd' into 's'; skip prefix, point, and exponent + int i = 0; + s[i ++] = '0'; + int j = 4; + while( csd[j] ) + { + if( csd[j] == '-' || csd[j] == '0' || csd[j] == '1' ) + s[i ++] = csd[j]; + else if( csd[j] != '.' ) + break; + ++ j; + } + s[i] = '\0'; + + // convert 's' from csd to two's complement + int len = i; + i = 1; + while( i < len ) + { + while( i < len && s[i] != '-' ) + i ++; + if( i < len ) + { + j = i ++; + s[j --] = '1'; + while( j >= 0 && s[j] == '0' ) + s[j --] = '1'; + if( j >= 0 ) + s[j] = '0'; + } + } + + // copy bits from 's' back into 'csd' + j = csd.length(); + csd[j + 1] = '\0'; + while( j > 4 ) + { + csd[j] = csd[j - 1]; + -- j; + } + + i = 0; + j = 4; + while( s[i] ) + { + if( csd[j] == '.' ) + ++ j; + csd[j ++] = s[i ++]; + } +} + +} // namespace sc_dt + + +// Taf! diff --git a/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h new file mode 100644 index 000000000..55fabe045 --- /dev/null +++ b/ext/systemc/src/sysc/datatypes/fx/scfx_utils.h @@ -0,0 +1,534 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +/***************************************************************************** + + scfx_utils.h - + + Original Author: 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_utils.h,v $ +// Revision 1.2 2009/02/28 00:26:20 acg +// Andy Goodrich: bug fixes. +// +// 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. +// + +#ifndef SCFX_UTILS_H +#define SCFX_UTILS_H + + +#include "sysc/datatypes/fx/sc_fxdefs.h" +#include "sysc/datatypes/fx/scfx_params.h" +#include "sysc/datatypes/fx/scfx_string.h" + + +namespace sc_dt +{ + +// ---------------------------------------------------------------------------- +// Find the most and least significant non-zero bits in a unsigned long +// ---------------------------------------------------------------------------- + +#define MSB_STATEMENT(n) if( x >> n ) { x >>= n; i += n; } + +inline +int +scfx_find_msb( unsigned long x ) +{ + int i = 0; +# if defined(SC_LONG_64) + MSB_STATEMENT( 32 ); +# endif // defined(SC_LONG_64) + MSB_STATEMENT( 16 ); + MSB_STATEMENT( 8 ); + MSB_STATEMENT( 4 ); + MSB_STATEMENT( 2 ); + MSB_STATEMENT( 1 ); + return i; +} + +#undef MSB_STATEMENT + +#define LSB_STATEMENT(n) if( x << n ) { x <<= n; i -= n; } + +inline +int +scfx_find_lsb( unsigned long x ) +{ + int i; +# if defined(SC_LONG_64) + i = 63; + LSB_STATEMENT( 32 ); +# else + i = 31; +# endif // defined(SC_LONG_64) + LSB_STATEMENT( 16 ); + LSB_STATEMENT( 8 ); + LSB_STATEMENT( 4 ); + LSB_STATEMENT( 2 ); + LSB_STATEMENT( 1 ); + return i; +} + +#undef LSB_STATEMENT + + +// ---------------------------------------------------------------------------- +// Utilities for parsing a character string number +// ---------------------------------------------------------------------------- + +inline +int +scfx_parse_sign( const char*& s, bool& sign_char ) +{ + int sign = 1; + + if( *s == '+' ) + { + ++ s; + sign_char = true; + } + else if( *s == '-' ) + { + sign = -1; + ++ s; + sign_char = true; + } + else + sign_char = false; + + return sign; +} + +inline +sc_numrep +scfx_parse_prefix( const char*& s ) +{ + if( s[0] == '0' ) { + switch( s[1] ) + { + case 'b': + case 'B': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_BIN_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_BIN_SM; + } + s += 2; + return SC_BIN; + } + case 'o': + case 'O': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_OCT_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_OCT_SM; + } + s += 2; + return SC_OCT; + } + case 'x': + case 'X': + { + if( (s[2] == 'u' || s[2] == 'U') && (s[3] == 's' || s[3] == 'S') ) { + s += 4; + return SC_HEX_US; + } + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'm' || s[3] == 'M') ) { + s += 4; + return SC_HEX_SM; + } + s += 2; + return SC_HEX; + } + case 'd': + case 'D': + { + s += 2; + return SC_DEC; + } + case 'c': + case 'C': + { + if( (s[2] == 's' || s[2] == 'S') && (s[3] == 'd' || s[3] == 'D') ) { + s += 4; + return SC_CSD; + } + break; + } + default: + break; + } + } + + return SC_DEC; +} + + +inline +int +scfx_parse_base( const char*& s ) +{ + const char* s1 = s + 1; + + int base = 10; + + if( *s == '0' ) + { + switch( *s1 ) + { + case 'b': + case 'B': base = 2; s += 2; break; + case 'o': + case 'O': base = 8; s += 2; break; + case 'd': + case 'D': base = 10; s += 2; break; + case 'x': + case 'X': base = 16; s += 2; break; + } + } + + return base; +} + +inline +bool +scfx_is_equal( const char* a, const char* b ) +{ + while( *a != 0 && *b != 0 && *a == *b ) + { + ++ a; + ++ b; + } + return ( *a == 0 && *b == 0 ); +} + +inline +bool +scfx_is_nan( const char* s ) +{ + return scfx_is_equal( s, "NaN" ); +} + +inline +bool +scfx_is_inf( const char* s ) +{ + return ( scfx_is_equal( s, "Inf" ) || scfx_is_equal( s, "Infinity" ) ); +} + +inline +bool +scfx_exp_start( const char* s ) +{ + if( *s == 'e' || *s == 'E' ) + { + ++ s; + if( *s == '+' || *s == '-' ) + return true; + } + return false; +} + +inline +bool +scfx_is_digit( char c, sc_numrep numrep ) +{ + bool is_digit; + + switch( numrep ) + { + case SC_DEC: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_BIN: + case SC_BIN_US: + case SC_BIN_SM: + { + switch( c ) + { + case '0': case '1': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_OCT: + case SC_OCT_US: + case SC_OCT_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_HEX: + case SC_HEX_US: + case SC_HEX_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + case SC_CSD: + { + switch( c ) + { + case '0': case '1': case '-': + { + is_digit = true; + break; + } + default: + is_digit = false; + } + break; + } + default: + is_digit = false; + } + + return is_digit; +} + +inline +int +scfx_to_digit( char c, sc_numrep numrep ) +{ + int to_digit; + + switch( numrep ) + { + case SC_DEC: + case SC_BIN: + case SC_BIN_US: + case SC_BIN_SM: + case SC_OCT: + case SC_OCT_US: + case SC_OCT_SM: + { + to_digit = c - '0'; + break; + } + case SC_HEX: + case SC_HEX_US: + case SC_HEX_SM: + { + switch( c ) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + to_digit = c - '0'; + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + to_digit = c - 'a' + 10; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + to_digit = c - 'A' + 10; + break; + default: + to_digit = -2; + } + break; + } + case SC_CSD: + { + if( c == '-' ) + to_digit = -1; + else + to_digit = c - '0'; + break; + } + default: + to_digit = -2; + } + + return to_digit; +} + + +// ---------------------------------------------------------------------------- +// Utilities for printing a character string number +// ---------------------------------------------------------------------------- + +inline +void +scfx_print_nan( scfx_string& s ) +{ + s += "NaN"; +} + +inline +void +scfx_print_inf( scfx_string& s, bool negative ) +{ + if( negative ) + s += "-Inf"; + else + s += "Inf"; +} + +inline +void +scfx_print_prefix( scfx_string& s, sc_numrep numrep ) +{ + switch( numrep ) + { + case SC_DEC: + s += "0d"; + break; + case SC_BIN: + s += "0b"; + break; + case SC_BIN_US: + s += "0bus"; + break; + case SC_BIN_SM: + s += "0bsm"; + break; + case SC_OCT: + s += "0o"; + break; + case SC_OCT_US: + s += "0ous"; + break; + case SC_OCT_SM: + s += "0osm"; + break; + case SC_HEX: + s += "0x"; + break; + case SC_HEX_US: + s += "0xus"; + break; + case SC_HEX_SM: + s += "0xsm"; + break; + case SC_CSD: + s += "0csd"; + break; + default: + s += "unknown"; + } +} + +inline +void +scfx_print_exp( scfx_string& s, int exp ) +{ + if( exp != 0 ) + { + s += 'e'; + + if( exp < 0 ) + { + exp = - exp; + s += '-'; + } + else + s += '+'; + + bool first = true; + int scale = 1000000000; + do + { + int digit = exp / scale; + exp = exp % scale; + if( digit != 0 || ! first ) + { + s += static_cast<char>( digit + '0' ); + first = false; + } + scale /= 10; + } + while( scale > 0 ); + } +} + + +void scfx_tc2csd( scfx_string&, int ); +void scfx_csd2tc( scfx_string& ); + +} // namespace sc_dt + + +#endif + +// Taf! |