diff options
Diffstat (limited to 'src/systemc/ext/dt/int')
-rw-r--r-- | src/systemc/ext/dt/int/_int.hh | 17 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/_using.hh | 41 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_bigint.hh | 284 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_biguint.hh | 284 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_int.hh | 381 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_int_base.hh | 1386 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_length_param.hh | 192 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_nbdefs.hh | 88 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_nbexterns.hh | 108 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_nbutils.hh | 832 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_signed.hh | 2504 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_uint.hh | 382 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_uint_base.hh | 1258 | ||||
-rw-r--r-- | src/systemc/ext/dt/int/sc_unsigned.hh | 2195 |
14 files changed, 9913 insertions, 39 deletions
diff --git a/src/systemc/ext/dt/int/_int.hh b/src/systemc/ext/dt/int/_int.hh index 11c2b4aba..dfbcf6ebd 100644 --- a/src/systemc/ext/dt/int/_int.hh +++ b/src/systemc/ext/dt/int/_int.hh @@ -27,9 +27,20 @@ * Authors: Gabe Black */ -#ifndef __SYSTEMC_EXT_CORE_DT__INT_HH__ -#define __SYSTEMC_EXT_CORE_DT__INT_HH__ +#ifndef __SYSTEMC_EXT_CORE_DT_INT__INT_HH__ +#define __SYSTEMC_EXT_CORE_DT_INT__INT_HH__ +#include "sc_bigint.hh" +#include "sc_biguint.hh" +#include "sc_int.hh" +#include "sc_int_base.hh" +#include "sc_length_param.hh" #include "sc_nbdefs.hh" +#include "sc_nbexterns.hh" +#include "sc_nbutils.hh" +#include "sc_signed.hh" +#include "sc_uint.hh" +#include "sc_uint_base.hh" +#include "sc_unsigned.hh" -#endif //__SYSTEMC_EXT_CORE_DT__INT_HH__ +#endif //__SYSTEMC_EXT_CORE_DT_INT__INT_HH__ diff --git a/src/systemc/ext/dt/int/_using.hh b/src/systemc/ext/dt/int/_using.hh index a53ac36ec..82f64dd25 100644 --- a/src/systemc/ext/dt/int/_using.hh +++ b/src/systemc/ext/dt/int/_using.hh @@ -27,27 +27,38 @@ * Authors: Gabe Black */ -#ifndef __SYSTEMC_EXT_CORE_INT__USING_HH__ -#define __SYSTEMC_EXT_CORE_INT__USING_HH__ +#ifndef __SYSTEMC_EXT_DT_INT__USING_HH__ +#define __SYSTEMC_EXT_DT_INT__USING_HH__ -#include "int.hh" +#include "_int.hh" -using sc_dt::SC_NOBASE; using sc_dt::SC_BIN; -using sc_dt::SC_OCT; +using sc_dt::SC_BIN_SM; +using sc_dt::SC_BIN_US; +using sc_dt::SC_CSD; using sc_dt::SC_DEC; using sc_dt::SC_HEX; -using sc_dt::SC_BIN_US; -using sc_dt::SC_BIN_SM; -using sc_dt::SC_OCT_US; -using sc_dt::SC_OCT_SM; -using sc_dt::SC_HEX_US; using sc_dt::SC_HEX_SM; -using sc_dt::SC_CSD; -using sc_dt::small_type +using sc_dt::SC_HEX_US; +using sc_dt::SC_NOBASE; +using sc_dt::SC_OCT; +using sc_dt::SC_OCT_SM; +using sc_dt::SC_OCT_US; using sc_dt::int64; +using sc_dt::sc_bigint; +using sc_dt::sc_biguint; +using sc_dt::sc_digit; +using sc_dt::sc_int; +using sc_dt::sc_int_base; +using sc_dt::sc_io_show_base; +using sc_dt::sc_length_context; +using sc_dt::sc_length_param; +using sc_dt::sc_logic; +using sc_dt::sc_numrep; +using sc_dt::sc_signed; +using sc_dt::sc_uint; +using sc_dt::sc_uint_base; +using sc_dt::sc_unsigned; using sc_dt::uint64; -using sc_dt::int_type; -using sc_dt::uint_type; -#endif //__SYSTEMC_EXT_CORE_INT__USING_HH__ +#endif //__SYSTEMC_EXT_DT_INT__USING_HH__ diff --git a/src/systemc/ext/dt/int/sc_bigint.hh b/src/systemc/ext/dt/int/sc_bigint.hh new file mode 100644 index 000000000..bcfbcaefc --- /dev/null +++ b/src/systemc/ext/dt/int/sc_bigint.hh @@ -0,0 +1,284 @@ +/***************************************************************************** + + 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_bigint.h -- Template version of sc_signed. This class enables + compile-time bit widths for sc_signed numbers. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc. + Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bigint.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_BIGINT_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_BIGINT_HH__ + +#include "sc_signed.hh" +#include "sc_unsigned.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_bigint; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bigint<W> +// +// Arbitrary size signed integer type. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS +template<int W=SC_MAX_NBITS> +#else +template<int W> +#endif +class sc_bigint : public sc_signed +{ + public: + // constructors + sc_bigint() : sc_signed(W) {} + sc_bigint(const sc_bigint<W> &v) : sc_signed(W) { *this = v; } + sc_bigint(const sc_signed &v) : sc_signed(W) { *this = v; } + sc_bigint(const sc_signed_subref &v) : sc_signed(W) { *this = v; } + + template< class T > + sc_bigint(const sc_generic_base<T> &a) : sc_signed(W) + { + a->to_sc_signed(*this); + } + + sc_bigint(const sc_unsigned &v) : sc_signed(W) { *this = v; } + sc_bigint(const sc_unsigned_subref &v) : sc_signed(W) { *this = v; } + sc_bigint(const char *v) : sc_signed(W) { *this = v; } + sc_bigint(int64 v) : sc_signed(W) { *this = v; } + sc_bigint(uint64 v) : sc_signed(W) { *this = v; } + sc_bigint(long v) : sc_signed(W) { *this = v; } + sc_bigint(unsigned long v) : sc_signed(W) { *this = v; } + sc_bigint(int v) : sc_signed(W) { *this = v; } + sc_bigint(unsigned int v) : sc_signed(W) { *this = v; } + sc_bigint(double v) : sc_signed(W) { *this = v; } + sc_bigint(const sc_bv_base &v) : sc_signed(W) { *this = v; } + sc_bigint(const sc_lv_base &v) : sc_signed(W) { *this = v; } + + explicit sc_bigint(const sc_fxval &v) : sc_signed(W) { *this = v; } + explicit sc_bigint(const sc_fxval_fast &v) : sc_signed(W) { *this = v; } + explicit sc_bigint(const sc_fxnum &v) : sc_signed(W) { *this = v; } + explicit sc_bigint(const sc_fxnum_fast &v) : sc_signed(W) { *this = v; } + +#ifndef SC_MAX_NBITS + // destructor + ~sc_bigint() {} +#endif + + // assignment operators + sc_bigint<W> & + operator = (const sc_bigint<W> &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_signed &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_signed_subref &v) + { + sc_signed::operator = (v); + return *this; + } + + template< class T > + sc_bigint<W> & + operator = (const sc_generic_base<T> &a) + { + a->to_sc_signed(*this); + return *this; + } + + sc_bigint<W> & + operator = (const sc_unsigned &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_unsigned_subref &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const char *v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (int64 v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (uint64 v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (long v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (unsigned long v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (int v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (unsigned int v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> &operator = (double v) + { + sc_signed::operator = (v); + return *this; + } + + + sc_bigint<W> & + operator = (const sc_bv_base &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_lv_base &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_int_base &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_uint_base &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_fxval &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_fxval_fast& v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_fxnum &v) + { + sc_signed::operator = (v); + return *this; + } + + sc_bigint<W> & + operator = (const sc_fxnum_fast &v) + { + sc_signed::operator = (v); + return *this; + } +}; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_BIGINT_HH__ diff --git a/src/systemc/ext/dt/int/sc_biguint.hh b/src/systemc/ext/dt/int/sc_biguint.hh new file mode 100644 index 000000000..7b6676971 --- /dev/null +++ b/src/systemc/ext/dt/int/sc_biguint.hh @@ -0,0 +1,284 @@ +/***************************************************************************** + + 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_biguint.h -- Template version of sc_unsigned. This class + enables compile-time bit widths for sc_unsigned numbers. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Gene Bushayev, Synopsys, Inc. + Description of Modification: - Interface between sc_bigint and sc_bv/sc_lv. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_biguint.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_BIGUINT_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_BIGUINT_HH__ + +#include "sc_signed.hh" +#include "sc_unsigned.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_biguint; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_biguint<W> +// +// Arbitrary size unsigned integer type. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS +template<int W=SC_MAX_NBITS> +#else +template<int W> +#endif +class sc_biguint : public sc_unsigned +{ + public: + // constructors + sc_biguint() : sc_unsigned(W) {} + sc_biguint(const sc_biguint<W> &v) : sc_unsigned(W) { *this = v; } + sc_biguint(const sc_unsigned &v) : sc_unsigned(W) { *this = v; } + sc_biguint(const sc_unsigned_subref &v) : sc_unsigned(W) { *this = v; } + + template<class T> + sc_biguint(const sc_generic_base<T> &a) : sc_unsigned(W) + { + a->to_sc_unsigned(*this); + } + + sc_biguint(const sc_signed &v) : sc_unsigned(W) { *this = v; } + sc_biguint(const sc_signed_subref &v) : sc_unsigned(W) { *this = v; } + sc_biguint(const char* v) : sc_unsigned(W) { *this = v; } + sc_biguint(int64 v) : sc_unsigned(W) { *this = v; } + sc_biguint(uint64 v) : sc_unsigned(W) { *this = v; } + sc_biguint(long v) : sc_unsigned(W) { *this = v; } + sc_biguint(unsigned long v) : sc_unsigned(W) { *this = v; } + sc_biguint(int v) : sc_unsigned(W) { *this = v; } + sc_biguint(unsigned int v) : sc_unsigned(W) { *this = v; } + sc_biguint(double v) : sc_unsigned(W) { *this = v; } + sc_biguint(const sc_bv_base &v) : sc_unsigned(W) { *this = v; } + sc_biguint(const sc_lv_base &v) : sc_unsigned(W) { *this = v; } + + explicit sc_biguint(const sc_fxval &v) : sc_unsigned(W) { *this = v; } + explicit sc_biguint(const sc_fxval_fast &v) : sc_unsigned(W) { *this = v; } + explicit sc_biguint(const sc_fxnum &v) : sc_unsigned(W) { *this = v; } + explicit sc_biguint(const sc_fxnum_fast &v) : sc_unsigned(W) { *this = v; } + +#ifndef SC_MAX_NBITS + // destructor + ~sc_biguint() {} +#endif + + // assignment operators + sc_biguint<W> & + operator = (const sc_biguint<W> &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_unsigned &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_unsigned_subref &v) + { + sc_unsigned::operator = (v); + return *this; + } + + template< class T > + sc_biguint<W> & + operator = (const sc_generic_base<T> &a) + { a->to_sc_unsigned(*this); + return *this; + } + + sc_biguint<W> & + operator = (const sc_signed &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_signed_subref &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const char* v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (int64 v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (uint64 v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (long v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (unsigned long v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (int v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (unsigned int v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (double v) + { + sc_unsigned::operator = (v); + return *this; + } + + + sc_biguint<W> & + operator = (const sc_bv_base &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_lv_base &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_int_base &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_uint_base &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_fxval &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_fxval_fast &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_fxnum &v) + { + sc_unsigned::operator = (v); + return *this; + } + + sc_biguint<W> & + operator = (const sc_fxnum_fast &v) + { + sc_unsigned::operator = (v); + return *this; + } +}; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_BIGUINT_HH__ diff --git a/src/systemc/ext/dt/int/sc_int.hh b/src/systemc/ext/dt/int/sc_int.hh new file mode 100644 index 000000000..d417321ef --- /dev/null +++ b/src/systemc/ext/dt/int/sc_int.hh @@ -0,0 +1,381 @@ +/***************************************************************************** + + 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_int.h -- A signed integer whose length is less than 64 bits. + + Unlike arbitrary precision, arithmetic and bitwise operations + are performed using the native types (hence capped at 64 bits). + The sc_int integer is useful when the user does not need + arbitrary precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_int.h,v $ +// Revision 1.2 2011/02/18 20:19:14 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_INT_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_INT_HH__ + +#include "sc_int_base.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_int; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_int<W> +// +// Template class sc_int<W> is the interface that the user sees. It is +// derived from sc_int_base and most of its methods are just wrappers +// that call the corresponding method in the parent class. Note that +// the length of sc_int datatype is specified as a template parameter. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_int : public sc_int_base +{ + public: + // constructors + sc_int() : sc_int_base(W) {} + sc_int(int_type v) : sc_int_base(v, W) {} + sc_int(const sc_int<W> &a) : sc_int_base(a) {} + + sc_int(const sc_int_base &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(const sc_int_subref_r &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + template< class T > + sc_int(const sc_generic_base<T> &a) : sc_int_base(W) + { + sc_int_base::operator = (a->to_int64()); + } + sc_int(const sc_signed &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(const sc_unsigned &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + explicit sc_int(const sc_fxval &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + explicit sc_int(const sc_fxval_fast &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + explicit sc_int(const sc_fxnum &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + explicit sc_int(const sc_fxnum_fast &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(const sc_bv_base &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(const sc_lv_base &a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(const char *a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(unsigned long a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(long a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(unsigned int a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(int a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(uint64 a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + sc_int(double a) : sc_int_base(W) + { + sc_int_base::operator = (a); + } + + // assignment operators + sc_int<W> & + operator = (int_type v) + { + sc_int_base::operator = (v); + return *this; + } + sc_int<W> & + operator = (const sc_int_base &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_int_subref_r &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_int<W> &a) + { + m_val = a.m_val; + return *this; + } + template< class T > + sc_int<W> & + operator = (const sc_generic_base<T> &a) + { + sc_int_base::operator = (a->to_int64()); + return *this; + } + sc_int<W> & + operator = (const sc_signed &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_unsigned &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_fxval &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_fxval_fast &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_fxnum &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> &operator = (const sc_fxnum_fast &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_bv_base &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const sc_lv_base &a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (const char *a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (unsigned long a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (long a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (unsigned int a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (int a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (uint64 a) + { + sc_int_base::operator = (a); + return *this; + } + sc_int<W> & + operator = (double a) + { + sc_int_base::operator = (a); + return *this; + } + + // arithmetic assignment operators + sc_int<W> & + operator += (int_type v) + { + sc_int_base::operator += (v); + return *this; + } + sc_int<W> & + operator -= (int_type v) + { + sc_int_base::operator -= (v); + return *this; + } + sc_int<W> & + operator *= (int_type v) + { + sc_int_base::operator *= (v); + return *this; + } + sc_int<W> & + operator /= (int_type v) + { + sc_int_base::operator /= (v); + return *this; + } + sc_int<W> & + operator %= (int_type v) + { + sc_int_base::operator %= (v); + return *this; + } + + // bitwise assignment operators + sc_int<W> & + operator &= (int_type v) + { + sc_int_base::operator &= (v); + return *this; + } + sc_int<W> & + operator |= (int_type v) + { + sc_int_base::operator |= (v); + return *this; + } + sc_int<W> & + operator ^= (int_type v) + { + sc_int_base::operator ^= (v); + return *this; + } + sc_int<W> & + operator <<= (int_type v) + { + sc_int_base::operator <<= (v); + return *this; + } + sc_int<W> & + operator >>= (int_type v) + { + sc_int_base::operator >>= (v); + return *this; + } + + // prefix and postfix increment and decrement operators + sc_int<W> & + operator ++ () // prefix + { + sc_int_base::operator ++ (); + return *this; + } + const sc_int<W> + operator ++ (int) // postfix + { + return sc_int<W>(sc_int_base::operator ++ (0)); + } + sc_int<W> & + operator -- () // prefix + { + sc_int_base::operator -- (); + return *this; + } + const sc_int<W> + operator -- (int) // postfix + { + return sc_int<W>(sc_int_base::operator -- (0)); + } +}; + +} // namespace sc_dt + + +#endif // __SYSTEMC_EXT_DT_INT_SC_INT_HH__ diff --git a/src/systemc/ext/dt/int/sc_int_base.hh b/src/systemc/ext/dt/int/sc_int_base.hh new file mode 100644 index 000000000..a8f602028 --- /dev/null +++ b/src/systemc/ext/dt/int/sc_int_base.hh @@ -0,0 +1,1386 @@ +/***************************************************************************** + + 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_int_base.h -- A signed integer whose length is less than 64 bit. + + Unlike arbitrary precision, arithmetic and bitwise operations + are performed using the native types (hence capped at 64 bits). + The sc_int integer is useful when the user does not need + arbitrary precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_int_base.h,v $ +// Revision 1.3 2011/08/24 22:05:45 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:31 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ + +#include <iostream> + +#include "../misc/sc_value_base.hh" +#include "../sc_temporary.hh" +#include "sc_length_param.hh" +#include "sc_nbdefs.hh" +#include "sc_uint_base.hh" + +namespace sc_dt +{ + +class sc_concatref; + +// classes defined in this module +class sc_int_bitref_r; +class sc_int_bitref; +class sc_int_subref_r; +class sc_int_subref; +class sc_int_base; +class sc_signed_subref_r; +class sc_unsigned_subref_r; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_signed; +class sc_unsigned; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + +} // namespace sc_dt + +// extern template instantiations +namespace sc_core +{ + +extern template class sc_vpool<sc_dt::sc_int_bitref>; +extern template class sc_vpool<sc_dt::sc_int_subref>; + +} // namespace sc_core + +namespace sc_dt +{ + +extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; + +// friend operator declarations + +// relational operators + +inline bool operator == (const sc_int_base &a, const sc_int_base &b); +inline bool operator != (const sc_int_base &a, const sc_int_base &b); +inline bool operator < (const sc_int_base &a, const sc_int_base &b); +inline bool operator <= (const sc_int_base &a, const sc_int_base &b); +inline bool operator > (const sc_int_base &a, const sc_int_base &b); +inline bool operator >= (const sc_int_base &a, const sc_int_base &b); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref_r +// +// Proxy class for sc_int bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_int_bitref_r : public sc_value_base +{ + friend class sc_int_base; + + protected: + // constructor + sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {} + + // initializer for sc_core::sc_vpool: + void initialize(const sc_int_base *obj_p, int index_) + { + m_obj_p = (sc_int_base *)obj_p; + m_index = index_; + } + + public: + // copy constructor + sc_int_bitref_r(const sc_int_bitref_r &a) : + sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) + {} + + // destructor + virtual ~sc_int_bitref_r() {} + + // capacity + int length() const { return 1; } + +#ifdef SC_DT_DEPRECATED + int bitwidth() const { return length(); } +#endif + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return 1; + } + virtual bool + concat_get_ctrl(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool + concat_get_data(sc_digit *dst_p, int low_i) const + { + bool non_zero; + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + if (operator uint64()) { + dst_p[word_i] |= bit_mask; + non_zero = true; + } else { + dst_p[word_i] &= ~bit_mask; + non_zero = false; + } + return non_zero; + } + virtual uint64 + concat_get_uint64() const + { + return operator uint64(); + } + + + // implicit conversions + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + uint64 value() const { return operator uint64(); } + + bool to_bool() const { return operator uint64(); } + + + // other methods + void print(::std::ostream& os=::std::cout) const { os << to_bool(); } + + protected: + int m_index; + sc_int_base *m_obj_p; + + private: + // Disabled + sc_int_bitref_r &operator = (const sc_int_bitref_r &); +}; + + +inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref +// +// Proxy class for sc_int bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_int_bitref : public sc_int_bitref_r +{ + friend class sc_int_base; + friend class sc_core::sc_vpool<sc_int_bitref>; + + // constructor + sc_int_bitref() : sc_int_bitref_r() {} + + public: + // copy constructor + sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {} + + // assignment operators + sc_int_bitref &operator = (const sc_int_bitref_r &b); + sc_int_bitref &operator = (const sc_int_bitref &b); + sc_int_bitref &operator = (bool b); + + sc_int_bitref &operator &= (bool b); + sc_int_bitref &operator |= (bool b); + sc_int_bitref &operator ^= (bool b); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + public: + static sc_core::sc_vpool<sc_int_bitref> m_pool; +}; + + + +inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref_r +// +// Proxy class for sc_int part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_int_subref_r : public sc_value_base +{ + friend class sc_int_base; + friend class sc_int_signal; + friend class sc_int_subref; + + protected: + // constructor + sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {} + + // initializer for sc_core::sc_vpool: + void initialize( const sc_int_base *obj_p, int left_i, int right_i) + { + m_obj_p = (sc_int_base *)obj_p; + m_left = left_i; + m_right = right_i; + } + + public: + // copy constructor + sc_int_subref_r(const sc_int_subref_r &a) : + sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p), + m_right(a.m_right) + {} + + // destructor + virtual ~sc_int_subref_r() {} + + // capacity + int length() const { return (m_left - m_right + 1); } + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return length(); + } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 + concat_get_uint64() const + { + int len = length(); + uint64 val = operator uint_type(); + if (len < 64) + return (uint64)(val & ~((uint_type)-1 << len)); + else + return (uint64)val; + } + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return xor_reduce(); } + + // implicit conversion to uint_type + operator uint_type () const; + + // explicit conversions + uint_type value() const { return operator uint_type(); } + + + 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; + double to_double() const; + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + protected: + int m_left; + sc_int_base *m_obj_p; + int m_right; + + private: + const sc_int_subref_r &operator = (const sc_int_subref_r &); +}; + +inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref +// +// Proxy class for sc_int part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_int_subref : public sc_int_subref_r +{ + friend class sc_int_base; + friend class sc_core::sc_vpool<sc_int_subref>; + + protected: + // constructor + sc_int_subref() : sc_int_subref_r() {} + + public: + // copy constructor + sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {} + + // assignment operators + sc_int_subref &operator = (int_type v); + sc_int_subref &operator = (const sc_int_base &a); + + sc_int_subref & + operator = (const sc_int_subref_r &a) + { + return operator = (a.operator uint_type()); + } + + sc_int_subref & + operator = (const sc_int_subref &a) + { + return operator = (a.operator uint_type()); + } + + template< class T > + sc_int_subref & + operator = (const sc_generic_base<T> &a) + { + return operator = (a->to_int64()); + } + + sc_int_subref &operator = (const char *a); + + sc_int_subref & + operator = (unsigned long a) + { + return operator = ((int_type)a); + } + + sc_int_subref & + operator = (long a) + { + return operator = ((int_type)a); + } + + sc_int_subref & + operator = (unsigned int a) + { + return operator = ((int_type)a); + } + + sc_int_subref & + operator = (int a) + { + return operator = ((int_type)a); + } + + sc_int_subref & + operator = (uint64 a) + { + return operator = ((int_type)a); + } + + sc_int_subref & + operator = (double a) + { + return operator = ((int_type)a); + } + + sc_int_subref &operator = (const sc_signed &); + sc_int_subref &operator = (const sc_unsigned &); + sc_int_subref &operator = (const sc_bv_base &); + sc_int_subref &operator = (const sc_lv_base &); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + public: + static sc_core::sc_vpool<sc_int_subref> m_pool; +}; + + +inline ::std::istream &operator >> (::std::istream &, sc_int_subref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// +// Base class for sc_int. +// ---------------------------------------------------------------------------- + +class sc_int_base : public sc_value_base +{ + friend class sc_int_bitref_r; + friend class sc_int_bitref; + friend class sc_int_subref_r; + friend class sc_int_subref; + + + // support methods + void invalid_length() const; + void invalid_index(int i) const; + void invalid_range(int l, int r) const; + + void + check_length() const + { + if (m_len <= 0 || m_len > SC_INTWIDTH) { + invalid_length(); + } + } + + void + check_index(int i) const + { + if (i < 0 || i >= m_len) { + invalid_index(i); + } + } + + void + check_range(int l, int r) const + { + if (r < 0 || l >= m_len || l < r) { + invalid_range(l, r); + } + } + + void check_value() const; + + void + extend_sign() + { +#ifdef DEBUG_SYSTEMC + check_value(); +#endif + m_val = (m_val << m_ulen >> m_ulen); + } + +public: + + // constructors + explicit sc_int_base(int w=sc_length_param().len()) : + m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + } + + sc_int_base(int_type v, int w) : + m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + extend_sign(); + } + + sc_int_base(const sc_int_base &a) : + sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) + {} + + explicit sc_int_base(const sc_int_subref_r &a) : + m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len) + { + extend_sign(); + } + + template< class T > + explicit sc_int_base(const sc_generic_base<T> &a) : + m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + extend_sign(); + } + + explicit sc_int_base(const sc_signed &a); + explicit sc_int_base(const sc_unsigned &a); + explicit sc_int_base(const sc_bv_base &v); + explicit sc_int_base(const sc_lv_base &v); + explicit sc_int_base(const sc_uint_subref_r &v); + explicit sc_int_base(const sc_signed_subref_r &v); + explicit sc_int_base(const sc_unsigned_subref_r &v); + + + // destructor + virtual ~sc_int_base() {} + + // assignment operators + sc_int_base & + operator = (int_type v) + { + m_val = v; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (const sc_int_base &a) + { + m_val = a.m_val; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (const sc_int_subref_r &a) + { + m_val = a; + extend_sign(); + return *this; + } + + template<class T> + sc_int_base & + operator = (const sc_generic_base<T> &a) + { + m_val = a->to_int64(); + extend_sign(); + return *this; + } + + sc_int_base &operator = (const sc_signed &a); + sc_int_base &operator = (const sc_unsigned &a); + + sc_int_base &operator = (const sc_fxval &a); + sc_int_base &operator = (const sc_fxval_fast &a); + sc_int_base &operator = (const sc_fxnum &a); + sc_int_base &operator = (const sc_fxnum_fast &a); + + sc_int_base &operator = (const sc_bv_base &a); + sc_int_base &operator = (const sc_lv_base &a); + + sc_int_base &operator = (const char *a); + + sc_int_base & + operator = (unsigned long a) + { + m_val = a; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (long a) + { + m_val = a; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (unsigned int a) + { + m_val = a; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (int a) + { + m_val = a; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (uint64 a) + { + m_val = a; + extend_sign(); + return *this; + } + + sc_int_base & + operator = (double a) + { + m_val = (int_type)a; + extend_sign(); + return *this; + } + + // arithmetic assignment operators + sc_int_base & + operator += (int_type v) + { + m_val += v; + extend_sign(); + return *this; + } + + sc_int_base & + operator -= (int_type v) + { + m_val -= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator *= (int_type v) + { + m_val *= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator /= (int_type v) + { + m_val /= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator %= (int_type v) + { + m_val %= v; + extend_sign(); + return *this; + } + + + // bitwise assignment operators + sc_int_base & + operator &= (int_type v) + { + m_val &= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator |= (int_type v) + { + m_val |= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator ^= (int_type v) + { + m_val ^= v; + extend_sign(); + return *this; + } + + + sc_int_base & + operator <<= (int_type v) + { + m_val <<= v; + extend_sign(); + return *this; + } + + sc_int_base & + operator >>= (int_type v) + { + m_val >>= v; + /* no sign extension needed */ + return *this; + } + + + // prefix and postfix increment and decrement operators + sc_int_base & + operator ++ () // prefix + { + ++m_val; + extend_sign(); + return *this; + } + + const sc_int_base + operator ++ (int) // postfix + { + sc_int_base tmp(*this); + ++m_val; + extend_sign(); + return tmp; + } + + sc_int_base & + operator -- () // prefix + { + --m_val; + extend_sign(); + return *this; + } + + const sc_int_base + operator -- ( int ) // postfix + { + sc_int_base tmp(*this); + --m_val; + extend_sign(); + return tmp; + } + + + // relational operators + friend bool + operator == (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val == b.m_val; + } + + friend bool + operator != (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val != b.m_val; + } + + friend bool + operator < (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val < b.m_val; + } + + friend bool + operator <= (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val <= b.m_val; + } + + friend bool + operator > (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val > b.m_val; + } + + friend bool + operator >= (const sc_int_base &a, const sc_int_base &b) + { + return a.m_val >= b.m_val; + } + + + // bit selection + sc_int_bitref &operator [] (int i); + const sc_int_bitref_r &operator [] (int i) const; + + sc_int_bitref &bit(int i); + const sc_int_bitref_r &bit(int i) const; + + + // part selection + sc_int_subref &operator () (int left, int right); + const sc_int_subref_r &operator () (int left, int right) const; + + sc_int_subref &range(int left, int right); + const sc_int_subref_r &range(int left, int right) const; + + + // bit access, without bounds checking or sign extension + bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); } + + void set(int i) { m_val |= (UINT_ONE << i); } + + void + set(int i, bool v) + { + v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); + } + + // capacity + int length() const { return m_len; } + + // concatenation support + virtual int + concat_length(bool* xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return length(); + } + virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const; + virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const; + virtual uint64 + concat_get_uint64() const + { + if (m_len < 64) + return (uint64)(m_val & ~((uint_type) - 1 << m_len)); + else + return (uint64)m_val; + } + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return !or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return !xor_reduce(); } + + + // implicit conversion to int_type + operator int_type() const { return m_val; } + + + // explicit conversions + int_type value() const { return operator int_type(); } + int to_int() const { return (int)m_val; } + unsigned int to_uint() const { return (unsigned int)m_val; } + long to_long() const { return (long)m_val; } + unsigned long to_ulong() const { return (unsigned long)m_val; } + int64 to_int64() const { return (int64)m_val; } + uint64 to_uint64() const { return (uint64)m_val; } + double to_double() const { return (double)m_val; } + long long_low() const { return (long)(m_val & UINT64_32ONES); } + long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); } + + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + void scan(::std::istream &is=::std::cin); + + protected: + int_type m_val; // value + int m_len; // length + int m_ulen; // unused length +}; + +inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &); +inline ::std::istream &operator >> (::std::istream &, sc_int_base &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref_r +// +// Proxy class for sc_int bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint64 + +inline sc_int_bitref_r::operator uint64 () const +{ + return m_obj_p->test(m_index); +} + +inline bool +sc_int_bitref_r::operator ! () const +{ + return ! m_obj_p->test(m_index); +} + +inline bool +sc_int_bitref_r::operator ~ () const +{ + return !m_obj_p->test(m_index); +} + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_int_bitref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_bitref +// +// Proxy class for sc_int bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline sc_int_bitref & +sc_int_bitref::operator = (const sc_int_bitref_r &b) +{ + m_obj_p->set(m_index, (bool)b); + m_obj_p->extend_sign(); + return *this; +} + +inline sc_int_bitref & +sc_int_bitref::operator = (const sc_int_bitref &b) +{ + m_obj_p->set(m_index, (bool)b); + m_obj_p->extend_sign(); + return *this; +} + +inline sc_int_bitref & +sc_int_bitref::operator = (bool b) +{ + m_obj_p->set(m_index, b); + m_obj_p->extend_sign(); + return *this; +} + + +inline sc_int_bitref & +sc_int_bitref::operator &= (bool b) +{ + if (!b) { + m_obj_p->set(m_index, b); + m_obj_p->extend_sign(); + } + return *this; +} + +inline sc_int_bitref & +sc_int_bitref::operator |= (bool b) +{ + if (b) { + m_obj_p->set(m_index, b); + m_obj_p->extend_sign(); + } + return *this; +} + +inline sc_int_bitref & +sc_int_bitref::operator ^= (bool b) +{ + if (b) { + m_obj_p->m_val ^= (UINT_ONE << m_index); + m_obj_p->extend_sign(); + } + return *this; +} + + + +inline ::std::istream & +operator >> (::std::istream &is, sc_int_bitref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref_r +// +// Proxy class for sc_int part selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to int_type + +inline sc_int_subref_r::operator uint_type() const +{ + uint_type /*int_type*/ val = m_obj_p->m_val; + int uleft = SC_INTWIDTH - (m_left + 1); + int uright = uleft + m_right; + return (val << uleft >> uright); +} + + +// reduce methods + +inline bool +sc_int_subref_r::and_reduce() const +{ + sc_int_base a(*this); + return a.and_reduce(); +} + +inline bool +sc_int_subref_r::or_reduce() const +{ + sc_int_base a(*this); + return a.or_reduce(); +} + +inline bool +sc_int_subref_r::xor_reduce() const +{ + sc_int_base a(*this); + return a.xor_reduce(); +} + + +// explicit conversions + +inline int +sc_int_subref_r::to_int() const +{ + int result = static_cast<int>(operator uint_type()); + return result; +} + +inline unsigned int +sc_int_subref_r::to_uint() const +{ + unsigned int result = static_cast<unsigned int>(operator uint_type()); + return result; +} + +inline long +sc_int_subref_r::to_long() const +{ + long result = static_cast<long>(operator uint_type()); + return result; +} + +inline unsigned long +sc_int_subref_r::to_ulong() const +{ + unsigned long result = static_cast<unsigned long>(operator uint_type()); + return result; +} + +inline int64 +sc_int_subref_r::to_int64() const +{ + int64 result = operator uint_type(); + return result; +} + +inline uint64 +sc_int_subref_r::to_uint64() const +{ + uint64 result = operator uint_type(); + return result; +} + +inline double +sc_int_subref_r::to_double() const +{ + double result = static_cast<double>(operator uint_type()); + return result; +} + + +// explicit conversion to character string + +inline const std::string +sc_int_subref_r::to_string(sc_numrep numrep) const +{ + sc_uint_base a(length()); + a = operator uint_type(); + return a.to_string(numrep); +} + +inline const std::string +sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const +{ + sc_uint_base a(length()); + a = operator uint_type(); + return a.to_string(numrep, w_prefix); +} + + +// functional notation for the reduce methods + +inline bool +and_reduce(const sc_int_subref_r &a) +{ + return a.and_reduce(); +} + +inline bool +nand_reduce(const sc_int_subref_r &a) +{ + return a.nand_reduce(); +} + +inline bool +or_reduce(const sc_int_subref_r &a) +{ + return a.or_reduce(); +} + +inline bool +nor_reduce(const sc_int_subref_r &a) +{ + return a.nor_reduce(); +} + +inline bool +xor_reduce(const sc_int_subref_r &a) +{ + return a.xor_reduce(); +} + +inline bool +xnor_reduce(const sc_int_subref_r &a) +{ + return a.xnor_reduce(); +} + + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_int_subref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_subref +// +// Proxy class for sc_int part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline sc_int_subref & +sc_int_subref::operator = (const sc_int_base &a) +{ + return operator = (a.operator int_type()); +} + +inline sc_int_subref & +sc_int_subref::operator = (const char *a) +{ + sc_int_base aa(length()); + return (*this = aa = a); +} + + + +inline ::std::istream & +operator >> (::std::istream &is, sc_int_subref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_int_base +// +// Base class for sc_int. +// ---------------------------------------------------------------------------- + +// bit selection + +inline sc_int_bitref & +sc_int_base::operator [] (int i) +{ + check_index(i); + sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline const sc_int_bitref_r & +sc_int_base::operator [] (int i) const +{ + check_index(i); + sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +inline sc_int_bitref & +sc_int_base::bit(int i) +{ + check_index(i); + sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline const sc_int_bitref_r & +sc_int_base::bit(int i) const +{ + check_index(i); + sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + + +// part selection + +inline sc_int_subref & +sc_int_base::operator () (int left, int right) +{ + check_range(left, right); + sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline const sc_int_subref_r & +sc_int_base::operator () (int left, int right) const +{ + check_range(left, right); + sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +inline sc_int_subref & +sc_int_base::range(int left, int right) +{ + check_range(left, right); + sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline const sc_int_subref_r & +sc_int_base::range(int left, int right) const +{ + check_range(left, right); + sc_int_subref *result_p = sc_int_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + + +// functional notation for the reduce methods + +inline bool +and_reduce(const sc_int_base &a) +{ + return a.and_reduce(); +} + +inline bool +nand_reduce(const sc_int_base &a) +{ + return a.nand_reduce(); +} + +inline bool +or_reduce(const sc_int_base &a) +{ + return a.or_reduce(); +} + +inline bool +nor_reduce(const sc_int_base &a) +{ + return a.nor_reduce(); +} + +inline bool +xor_reduce(const sc_int_base &a) +{ + return a.xor_reduce(); +} + +inline bool +xnor_reduce(const sc_int_base &a) +{ + return a.xnor_reduce(); +} + + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_int_base &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_int_base &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__ diff --git a/src/systemc/ext/dt/int/sc_length_param.hh b/src/systemc/ext/dt/int/sc_length_param.hh new file mode 100644 index 000000000..2321cbc78 --- /dev/null +++ b/src/systemc/ext/dt/int/sc_length_param.hh @@ -0,0 +1,192 @@ +/***************************************************************************** + + 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_length_param.h - + + Original Author: Martin Janssen, Synopsys, Inc., 2002-03-19 + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_length_param.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_LENGTH_PARAM_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_LENGTH_PARAM_HH__ + +#include <iostream> + +#include "../fx/sc_context.hh" +#include "../fx/sc_fxdefs.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_length_param; + +// friend operator declarations +bool operator == (const sc_length_param &, const sc_length_param &); +bool operator != (const sc_length_param &, const sc_length_param &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_length_param +// +// Length parameter type. +// ---------------------------------------------------------------------------- + +class sc_length_param +{ + public: + sc_length_param(); + sc_length_param(int); + sc_length_param(const sc_length_param &); + explicit sc_length_param(sc_without_context); + + sc_length_param &operator = (const sc_length_param &); + + friend bool operator == (const sc_length_param &, const sc_length_param &); + friend bool operator != (const sc_length_param &, const sc_length_param &); + + int len() const; + void len(int); + + const std::string to_string() const; + + void print(::std::ostream & =::std::cout) const; + void dump(::std::ostream & =::std::cout) const; + + private: + int m_len; +}; + +} // namespace sc_dt + +// ---------------------------------------------------------------------------- +// TYPEDEF : sc_length_context +// +// Context type for the length parameter type. +// ---------------------------------------------------------------------------- + +namespace sc_dt +{ + +extern template class sc_global<sc_length_param>; +extern template class sc_context<sc_length_param>; + +typedef sc_context<sc_length_param> sc_length_context; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline sc_length_param::sc_length_param() : m_len() +{ + *this = sc_length_context::default_value(); +} + +inline sc_length_param::sc_length_param(int len_) : m_len(len_) +{ + SC_CHECK_WL_(len_); +} + +inline sc_length_param::sc_length_param(const sc_length_param &a) : + m_len(a.m_len) +{} + +inline sc_length_param::sc_length_param(sc_without_context) : + m_len(SC_DEFAULT_WL_) +{} + + +inline sc_length_param & +sc_length_param::operator = (const sc_length_param &a) +{ + if (&a != this) { + m_len = a.m_len; + } + return *this; +} + + +inline bool +operator == (const sc_length_param &a, const sc_length_param &b) +{ + return (a.m_len == b.m_len); +} + +inline bool +operator != (const sc_length_param &a, const sc_length_param &b) +{ + return (a.m_len != b.m_len); +} + + +inline int +sc_length_param::len() const +{ + return m_len; +} + +inline void +sc_length_param::len(int len_) +{ + SC_CHECK_WL_(len_); + m_len = len_; +} + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_length_param &a) +{ + a.print(os); + return os; +} + +} // namespace sc_dt + + +#endif // __SYSTEMC_EXT_DT_INT_SC_LENGTH_PARAM_HH__ diff --git a/src/systemc/ext/dt/int/sc_nbdefs.hh b/src/systemc/ext/dt/int/sc_nbdefs.hh index 48d735adf..3854a9198 100644 --- a/src/systemc/ext/dt/int/sc_nbdefs.hh +++ b/src/systemc/ext/dt/int/sc_nbdefs.hh @@ -18,12 +18,52 @@ *****************************************************************************/ /***************************************************************************** + sc_nbdefs.h -- Top level header file for arbitrary precision signed/unsigned arithmetic. This file defines all the constants needed. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Torsten Maehne, Berner Fachhochschule, + 2016-09-24 + Description of Modification: Move constant definitions to the header so that + that their value is known at compile time. + *****************************************************************************/ -#ifndef __SYSTEMC_DT_SC_NBDEFS_H__ -#define __SYSTEMC_DT_SC_NBDEFS_H__ +// $Log: sc_nbdefs.h,v $ +// Revision 1.7 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.6 2011/02/18 20:09:34 acg +// Philipp A. Hartmann: added alternative #define for Windows to guard. +// +// Revision 1.5 2011/01/20 16:52:20 acg +// Andy Goodrich: changes for IEEE 1666 2011. +// +// Revision 1.4 2010/02/08 18:35:55 acg +// Andy Goodrich: Philipp Hartmann's changes for Solaris and Linux 64. +// +// Revision 1.2 2009/05/22 16:06:29 acg +// Andy Goodrich: process control updates. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_NBDEFS_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_NBDEFS_HH__ #include <stdint.h> @@ -77,8 +117,8 @@ typedef int small_type; #define LOG2_BITS_PER_BYTE 3 // Attributes of the unsigned long. These definitions are used mainly in -// the functions that are aware of the internal representation of digits, -// e.g., get/set_packed_rep(). +// the functions that are aware of the internal representation of +// digits, e.g., get/set_packed_rep(). #define BYTES_PER_DIGIT_TYPE 4 #define BITS_PER_DIGIT_TYPE 32 @@ -120,35 +160,41 @@ static const int MAX_NDIGITS = DIV_CEIL(SC_MAX_NBITS) + 2; // since the unsigned long data type varies in size between 32-bit and 64-bit // machines. -typedef unsigned int sc_digit; // 32-bit unsigned integer +typedef unsigned int sc_digit; // 32-bit unsigned integer // Support for the long long type. This type is not in the standard // but is usually supported by compilers. +#if defined(__x86_64__) || defined(__aarch64__) +typedef long long int64; +typedef unsigned long long uint64; +#else typedef int64_t int64; typedef uint64_t uint64; +#endif -static const uint64 UINT64_ZERO = 0ULL; -static const uint64 UINT64_ONE = 1ULL; +static const uint64 UINT64_ZERO = 0ULL; +static const uint64 UINT64_ONE = 1ULL; static const uint64 UINT64_32ONES = 0x00000000ffffffffULL; + // Bits per ... // will be deleted in the future. Use numeric_limits instead -#define BITS_PER_CHAR 8 -#define BITS_PER_INT (sizeof(int) * BITS_PER_CHAR) -#define BITS_PER_LONG (sizeof(long) * BITS_PER_CHAR) -#define BITS_PER_INT64 (sizeof(::sc_dt::int64) * BITS_PER_CHAR) -#define BITS_PER_UINT (sizeof(unsigned int) * BITS_PER_CHAR) -#define BITS_PER_ULONG (sizeof(unsigned long) * BITS_PER_CHAR) +#define BITS_PER_CHAR 8 +#define BITS_PER_INT (sizeof(int) * BITS_PER_CHAR) +#define BITS_PER_LONG (sizeof(long) * BITS_PER_CHAR) +#define BITS_PER_INT64 (sizeof(::sc_dt::int64) * BITS_PER_CHAR) +#define BITS_PER_UINT (sizeof(unsigned int) * BITS_PER_CHAR) +#define BITS_PER_ULONG (sizeof(unsigned long) * BITS_PER_CHAR) #define BITS_PER_UINT64 (sizeof(::sc_dt::uint64) * BITS_PER_CHAR) // Digits per ... -#define DIGITS_PER_CHAR 1 -#define DIGITS_PER_INT ((BITS_PER_INT+29)/30) -#define DIGITS_PER_LONG ((BITS_PER_LONG+29)/30) -#define DIGITS_PER_INT64 ((BITS_PER_INT64+29)/30) -#define DIGITS_PER_UINT ((BITS_PER_UINT+29)/30) -#define DIGITS_PER_ULONG ((BITS_PER_ULONG+29)/30) -#define DIGITS_PER_UINT64 ((BITS_PER_UINT64+29)/30) +#define DIGITS_PER_CHAR 1 +#define DIGITS_PER_INT ((BITS_PER_INT + 29) / 30) +#define DIGITS_PER_LONG ((BITS_PER_LONG + 29) / 30) +#define DIGITS_PER_INT64 ((BITS_PER_INT64 + 29) / 30) +#define DIGITS_PER_UINT ((BITS_PER_UINT + 29) / 30) +#define DIGITS_PER_ULONG ((BITS_PER_ULONG + 29) / 30) +#define DIGITS_PER_UINT64 ((BITS_PER_UINT64 + 29) / 30) // Above, BITS_PER_X is mainly used for sc_signed, and BITS_PER_UX is // mainly used for sc_unsigned. @@ -165,4 +211,4 @@ static const uint64 UINT_ONE = UINT64_ONE; } // namespace sc_dt -#endif +#endif // __SYSTEMC_EXT_DT_INT_SC_NBDEFS_HH__ diff --git a/src/systemc/ext/dt/int/sc_nbexterns.hh b/src/systemc/ext/dt/int/sc_nbexterns.hh new file mode 100644 index 000000000..942b52194 --- /dev/null +++ b/src/systemc/ext/dt/int/sc_nbexterns.hh @@ -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_nbexterns.h -- External functions for both sc_signed and sc_unsigned + classes. These functions work on two parameters u and + v, and copy the result to the first parameter u. This + is also the reason that they are suffixed with _on_help. + + The vec_* functions are called through either these + functions or those in sc_nbfriends.cpp. The functions in + sc_nbfriends.cpp perform their work on two inputs u and v, + and return the result object. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_nbexterns.h,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_NBEXTERNS_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_NBEXTERNS_HH__ + +#include "sc_nbutils.hh" + +namespace sc_dt +{ + +extern void add_on_help( + small_type &us, int unb, int und, sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +extern void mul_on_help_signed( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +void div_on_help_signed( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern void mod_on_help_signed( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern void mul_on_help_unsigned( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +void div_on_help_unsigned( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern void mod_on_help_unsigned( + small_type &us, int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +extern void and_on_help( + small_type us, int unb, int und, sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +extern void or_on_help( + small_type us, int unb, int und, sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +extern void xor_on_help( + small_type us, int unb, int und, sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_NBEXTERNS_HH__ diff --git a/src/systemc/ext/dt/int/sc_nbutils.hh b/src/systemc/ext/dt/int/sc_nbutils.hh new file mode 100644 index 000000000..9f7269e8c --- /dev/null +++ b/src/systemc/ext/dt/int/sc_nbutils.hh @@ -0,0 +1,832 @@ +/***************************************************************************** + + 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_nbutils.h -- External and friend functions for both sc_signed and + sc_unsigned classes. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_nbutils.h,v $ +// Revision 1.6 2011/09/08 16:12:15 acg +// Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries. +// +// Revision 1.5 2011/08/26 23:00:01 acg +// Torsten Maehne: remove use of ieeefp.h. +// +// Revision 1.4 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2010/09/06 16:35:48 acg +// Andy Goodrich: changed i386 to __i386__ in ifdef's. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ + +#include <cmath> +#include <ios> +#include <limits> +#include <ostream> + +#include "../../utils/sc_report_handler.hh" +#include "sc_nbdefs.hh" + +namespace sc_dt +{ + +//----------------------------------------------------------------------------- +//"sc_io_base" +// +// This inline function returns the type of an i/o stream's base as a SystemC +// base designator. +// stream_object = reference to the i/o stream whose base is to be returned. +// +//"sc_io_show_base" +// +// This inline function returns true if the base should be shown when a SystemC +// value is displayed via the supplied stream operator. +// stream_object = reference to the i/o stream to return showbase value for. +//----------------------------------------------------------------------------- +inline sc_numrep +sc_io_base(::std::ostream &os, sc_numrep def_base) +{ + std::ios::fmtflags flags = os.flags() & std::ios::basefield; + if (flags & ::std::ios::dec) return SC_DEC; + if (flags & ::std::ios::hex) return SC_HEX; + if (flags & ::std::ios::oct) return SC_OCT; + return def_base; +} + +inline bool +sc_io_show_base(::std::ostream &os) +{ + return (os.flags() & ::std::ios::showbase) != 0; +} + +const std::string to_string(sc_numrep); + +inline ::std::ostream & +operator << (::std::ostream &os, sc_numrep numrep) +{ + os << to_string(numrep); + return os; +} + +// ---------------------------------------------------------------------------- + +// One transition of the FSM to find base and sign of a number. +extern small_type fsm_move( + char c, small_type &b, small_type &s, small_type &state); + +// Parse a character string into its equivalent binary bits. +extern void parse_binary_bits( + const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0); + +// Parse a character string into its equivalent hexadecimal bits. +extern void parse_hex_bits( + const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0); + +// Find the base and sign of a number in v. +extern const char *get_base_and_sign( + const char *v, small_type &base, small_type &sign); + +// Create a number out of v in base. +extern small_type +vec_from_str(int unb, int und, sc_digit *u, + const char *v, sc_numrep base=SC_NOBASE); + + +// ---------------------------------------------------------------------------- +// Naming convention for the vec_ functions below: +// vec_OP(u, v, w) : computes w = u OP v. +// vec_OP_on(u, v) : computes u = u OP v if u has more digits than v. +// vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v. +// _large : parameters are vectors. +// _small : one of the parameters is a single digit. +// Xlen : the number of digits in X. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Functions for vector addition: w = u + v or u += v. +// ---------------------------------------------------------------------------- + +extern void vec_add(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); +extern void vec_add_on(int ulen, sc_digit *u, int vlen, const sc_digit *v); +extern void vec_add_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v); +extern void vec_add_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); +extern void vec_add_small_on(int ulen, sc_digit *u, sc_digit v); + +// ---------------------------------------------------------------------------- +// Functions for vector subtraction: w = u - v, u -= v, or u = v - u. +// ---------------------------------------------------------------------------- + +extern void vec_sub(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); +extern void vec_sub_on(int ulen, sc_digit *u, int vlen, const sc_digit *v); +extern void vec_sub_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v); +extern void vec_sub_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); +extern void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions for vector multiplication: w = u * v or u *= v. +// ---------------------------------------------------------------------------- + +extern void vec_mul(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); +extern void vec_mul_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); +extern void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions for vector division: w = u / v. +// ---------------------------------------------------------------------------- + +extern void vec_div_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); +extern void vec_div_small(int ulen, const sc_digit *u, + sc_digit v, sc_digit *w); + + +// ---------------------------------------------------------------------------- +// Functions for vector remainder: w = u % v or u %= v. +// ---------------------------------------------------------------------------- + +extern void vec_rem_large(int ulen, const sc_digit *u, + int vlen, const sc_digit *v, sc_digit *w); +extern sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v); +extern sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v); + + +// ---------------------------------------------------------------------------- +// Functions to convert between vectors of char and sc_digit. +// ---------------------------------------------------------------------------- + +extern int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v); +extern void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v); + + +// ---------------------------------------------------------------------------- +// Functions to shift left or right, or to create a mirror image of vectors. +// ---------------------------------------------------------------------------- + +extern void vec_shift_left(int ulen, sc_digit *u, int nsl); +extern void vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill=0); +extern void vec_reverse(int unb, int und, sc_digit *ud, int l, int r=0); + + +// ---------------------------------------------------------------------------- +// Various utility functions. +// ---------------------------------------------------------------------------- + +// Return the low half part of d. +inline sc_digit low_half(sc_digit d) { return (d & HALF_DIGIT_MASK); } + +// Return the high half part of d. The high part of the digit may have +// more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the +// multiplication. Hence, in other functions that use high_half(), +// make sure that the result contains BITS_PER_HALF_DIGIT if +// necessary. This is done by high_half_masked(). +inline sc_digit high_half(sc_digit d) { return (d >> BITS_PER_HALF_DIGIT); } +inline sc_digit +high_half_masked(sc_digit d) +{ + return (high_half(d) & HALF_DIGIT_MASK); +} + +// Concatenate the high part h and low part l. Assumes that h and l +// are less than or equal to HALF_DIGIT_MASK; +inline sc_digit +concat(sc_digit h, sc_digit l) +{ + return ((h << BITS_PER_HALF_DIGIT) | l); +} + +// Create a number with n 1's. +inline sc_digit +one_and_ones(int n) +{ + return (((sc_digit) 1 << n) - 1); +} + +// Create a number with one 1 and n 0's. +inline sc_digit one_and_zeros(int n) { return ((sc_digit) 1 << n); } + + +// ---------------------------------------------------------------------------- + +// Find the digit that bit i is in. +inline int digit_ord(int i) { return (i / BITS_PER_DIGIT); } + +// Find the bit in digit_ord(i) that bit i corressponds to. +inline int bit_ord(int i) { return (i % BITS_PER_DIGIT); } + + +// ---------------------------------------------------------------------------- +// Functions to compare, zero, complement vector(s). +// ---------------------------------------------------------------------------- + +// Compare u and v and return r +// r = 0 if u == v +// r < 0 if u < v +// r > 0 if u > v +// - Assume that all the leading zero digits are already skipped. +// - ulen and/or vlen can be zero. +// - Every digit is less than or equal to DIGIT_MASK; +inline int +vec_cmp(int ulen, const sc_digit *u, + int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + // sc_assert((ulen <= 0) || (u != NULL)); + // sc_assert((vlen <= 0) || (v != NULL)); + + // ulen and vlen can be equal to 0 because vec_cmp can be called + // after vec_skip_leading_zeros. + sc_assert((ulen >= 0) && (u != NULL)); + sc_assert((vlen >= 0) && (v != NULL)); + // If ulen > 0, then the leading digit of u must be non-zero. + sc_assert((ulen <= 0) || (u[ulen - 1] != 0)); + sc_assert((vlen <= 0) || (v[vlen - 1] != 0)); +#endif + + if (ulen != vlen) + return (ulen - vlen); + + // ulen == vlen >= 1 + while ((--ulen >= 0) && (u[ulen] == v[ulen])) + {} + + if (ulen < 0) + return 0; + +#ifdef DEBUG_SYSTEMC + // Test to see if the result is wrong due to the presence of + // overflow bits. + sc_assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK)); +#endif + + return (int)(u[ulen] - v[ulen]); +} + +// Find the index of the first non-zero digit. +// - ulen (before) = the number of digits in u. +// - the returned value = the index of the first non-zero digit. +// A negative value of -1 indicates that every digit in u is zero. +inline int +vec_find_first_nonzero(int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // sc_assert((ulen <= 0) || (u != NULL)); + sc_assert((ulen > 0) && (u != NULL)); +#endif + + while ((--ulen >= 0) && (! u[ulen])) + {} + + return ulen; +} + +// Skip all the leading zero digits. +// - ulen (before) = the number of digits in u. +// - the returned value = the number of non-zero digits in u. +// - the returned value is non-negative. +inline int +vec_skip_leading_zeros(int ulen, const sc_digit *u) +{ +#ifdef DEBUG_SYSTEMC + // sc_assert((ulen <= 0) || (u != NULL)); + sc_assert((ulen > 0) && (u != NULL)); +#endif + + return (1 + vec_find_first_nonzero(ulen, u)); +} + +// Compare u and v and return r +// r = 0 if u == v +// r < 0 if u < v +// r > 0 if u > v +inline int +vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((ulen > 0) && (u != NULL)); + sc_assert((vlen > 0) && (v != NULL)); +#endif + + ulen = vec_skip_leading_zeros(ulen, u); + vlen = vec_skip_leading_zeros(vlen, v); + // ulen and/or vlen can be equal to zero here. + return vec_cmp(ulen, u, vlen, v); +} + +// Set u[i] = 0 where i = from ... (ulen - 1). +inline void +vec_zero(int from, int ulen, sc_digit *u) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((ulen > 0) && (u != NULL)); +#endif + for (int i = from; i < ulen; i++) + u[i] = 0; +} + +// Set u[i] = 0 where i = 0 .. (ulen - 1). +inline void vec_zero(int ulen, sc_digit *u) { vec_zero(0, ulen, u); } + +// Copy n digits from v to u. +inline void +vec_copy(int n, sc_digit *u, const sc_digit *v) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((n > 0) && (u != NULL) && (v != NULL)); +#endif + for (int i = 0; i < n; ++i) + u[i] = v[i]; +} + +// Copy v to u, where ulen >= vlen, and zero the rest of the digits in u. +inline void +vec_copy_and_zero(int ulen, sc_digit *u, int vlen, const sc_digit *v) +{ + +#ifdef DEBUG_SYSTEMC + sc_assert((ulen > 0) && (u != NULL)); + sc_assert((vlen > 0) && (v != NULL)); + sc_assert(ulen >= vlen); +#endif + vec_copy(vlen, u, v); + vec_zero(vlen, ulen, u); + +} + +// 2's-complement the digits in u. +inline void +vec_complement(int ulen, sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + sc_assert((ulen > 0) && (u != NULL)); +#endif + + sc_digit carry = 1; + + for (int i = 0; i < ulen; ++i) { + carry += (~u[i] & DIGIT_MASK); + u[i] = carry & DIGIT_MASK; + carry >>= BITS_PER_DIGIT; + } +} + + +// ---------------------------------------------------------------------------- +// Functions to handle built-in types or signs. +// ---------------------------------------------------------------------------- + +// u = v +// - v is an unsigned long or uint64, and positive integer. +template<class Type> +inline void +from_uint(int ulen, sc_digit *u, Type v) +{ +#ifdef DEBUG_SYSTEMC + // sc_assert((ulen <= 0) || (u != NULL)); + sc_assert((ulen > 0) && (u != NULL)); + sc_assert(v >= 0); +#endif + + int i = 0; + + while (v && (i < ulen)) { + u[i++] = static_cast<sc_digit>(v & DIGIT_MASK); + v >>= BITS_PER_DIGIT; + } + vec_zero(i, ulen, u); +} + +#ifndef __GNUC__ +# define SC_LIKELY_(x) !!(x) +#else +# define SC_LIKELY_(x) __builtin_expect(!!(x), 1) +#endif + +// Get u's sign and return its absolute value. +// u can be long, unsigned long, int64, or uint64. +template<class Type> +inline small_type +get_sign(Type &u) +{ + if (u > 0) + return SC_POS; + + if (u == 0) + return SC_ZERO; + + // no positive number representable for minimum value, + // leave as is to avoid Undefined Behaviour + if (SC_LIKELY_(u > (std::numeric_limits<Type>::min)())) + u = -u; + + return SC_NEG; +} + +#undef SC_LIKELY_ + + +// Return us * vs: +// - Return SC_ZERO if either sign is SC_ZERO. +// - Return SC_POS if us == vs +// - Return SC_NEG if us != vs. +inline small_type +mul_signs(small_type us, small_type vs) +{ + if ((us == SC_ZERO) || (vs == SC_ZERO)) + return SC_ZERO; + + if (us == vs) + return SC_POS; + + return SC_NEG; +} + + +// ---------------------------------------------------------------------------- +// Functions to test for errors and print out error messages. +// ---------------------------------------------------------------------------- + +#ifdef SC_MAX_NBITS + +void test_bound_failed(int nb); + +inline void +test_bound(int nb) +{ + if (nb > SC_MAX_NBITS) { + test_bound_failed(nb); + sc_core::sc_abort(); // can't recover from here + } +} + +#endif + +template<class Type> +inline void +div_by_zero(Type s) +{ + if (s == 0) { + SC_REPORT_ERROR("operation failed", + "div_by_zero<Type>(Type) : division by zero"); + sc_core::sc_abort(); // can't recover from here + } +} + + +// ---------------------------------------------------------------------------- +// Functions to check if a given vector is zero or make one. +// ---------------------------------------------------------------------------- + +// If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO, +// else return s. +inline small_type +check_for_zero(small_type s, int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // sc_assert(ulen >= 0); + sc_assert((ulen > 0) && (u != NULL)); +#endif + + if (vec_find_first_nonzero(ulen, u) < 0) + return SC_ZERO; + + return s; +} + +// If u[i] is zero for every i = 0,..., ulen - 1, return true, +// else return false. +inline bool +check_for_zero(int ulen, const sc_digit *u) +{ + +#ifdef DEBUG_SYSTEMC + // sc_assert(ulen >= 0); + sc_assert((ulen > 0) && (u != NULL)); +#endif + + if (vec_find_first_nonzero(ulen, u) < 0) + return true; + + return false; +} + +inline small_type +make_zero(int nd, sc_digit *d) +{ + vec_zero(nd, d); + return SC_ZERO; +} + + +// ---------------------------------------------------------------------------- +// Functions for both signed and unsigned numbers to convert sign-magnitude +// (SM) and 2's complement (2C) representations. +// added = 1 => for signed. +// added = 0 => for unsigned. +// IF_SC_SIGNED can be used as 'added'. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits of a signed or unsigned number. +inline void +trim(small_type added, int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added); +} + +// Convert an (un)signed number from sign-magnitude representation to +// 2's complement representation and trim the extra bits. +inline void +convert_SM_to_2C_trimmed(small_type added, + small_type s, int nb, int nd, sc_digit *d) +{ + if (s == SC_NEG) { + vec_complement(nd, d); + trim(added, nb, nd, d); + } +} + +// Convert an (un)signed number from sign-magnitude representation to +// 2's complement representation but do not trim the extra bits. +inline void +convert_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + if (s == SC_NEG) + vec_complement(nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to convert between sign-magnitude (SM) and 2's complement +// (2C) representations of signed numbers. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits off a signed number. +inline void +trim_signed(int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1); +} + +// Convert a signed number from 2's complement representation to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline small_type +convert_signed_2C_to_SM(int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + small_type s; + + int xnb = bit_ord(nb - 1) + 1; + + // Test the sign bit. + if (d[nd - 1] & one_and_zeros(xnb - 1)) { + s = SC_NEG; + vec_complement(nd, d); + } else { + s = SC_POS; + } + + // Trim the last digit. + d[nd - 1] &= one_and_ones(xnb); + + // Check if the new number is zero. + if (s == SC_POS) + return check_for_zero(s, nd, d); + + return s; +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation, get its sign, convert back to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline small_type +convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); + return convert_signed_2C_to_SM(nb, nd, d); +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation and trim the extra bits. +inline void +convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C_trimmed(1, s, nb, nd, d); +} + +// Convert a signed number from sign-magnitude representation to 2's +// complement representation but do not trim the extra bits. +inline void +convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to convert between sign-magnitude (SM) and 2's complement +// (2C) representations of unsigned numbers. +// ---------------------------------------------------------------------------- + +// Trim the extra leading bits off an unsigned number. +inline void +trim_unsigned(int nb, int nd, sc_digit *d) +{ +#ifdef DEBUG_SYSTEMC + sc_assert((nb > 0) && (nd > 0) && (d != NULL)); +#endif + + d[nd - 1] &= one_and_ones(bit_ord(nb - 1)); +} + +// Convert an unsigned number from 2's complement representation to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline small_type +convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d) +{ + trim_unsigned(nb, nd, d); + return check_for_zero(SC_POS, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation, get its sign, convert back to +// sign-magnitude representation, and return its sign. nd is d's +// actual size, without zeros eliminated. +inline small_type +convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); + return convert_unsigned_2C_to_SM(nb, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation and trim the extra bits. +inline void +convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d) +{ + convert_SM_to_2C_trimmed(0, s, nb, nd, d); +} + +// Convert an unsigned number from sign-magnitude representation to +// 2's complement representation but do not trim the extra bits. +inline void +convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d) +{ + convert_SM_to_2C(s, nd, d); +} + + +// ---------------------------------------------------------------------------- +// Functions to copy one (un)signed number to another. +// ---------------------------------------------------------------------------- + +// Copy v to u. +inline void +copy_digits_signed(small_type &us, + int unb, int und, sc_digit *ud, + int vnb, int vnd, const sc_digit *vd) +{ + if (und <= vnd) { + vec_copy(und, ud, vd); + + if (unb <= vnb) + us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud); + } else { // und > vnd + vec_copy_and_zero(und, ud, vnd, vd); + } +} + +// Copy v to u. +inline void +copy_digits_unsigned(small_type &us, + int unb, int und, sc_digit *ud, + int /* vnb */, int vnd, const sc_digit *vd) +{ + if (und <= vnd) + vec_copy(und, ud, vd); + else // und > vnd + vec_copy_and_zero(und, ud, vnd, vd); + + us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud); +} + + +// ---------------------------------------------------------------------------- +// Faster set(i, v), without bound checking. +// ---------------------------------------------------------------------------- + +// A version of set(i, v) without bound checking. +inline void +safe_set(int i, bool v, sc_digit *d) +{ + +#ifdef DEBUG_SYSTEMC + sc_assert((i >= 0) && (d != NULL)); +#endif + + int bit_num = bit_ord(i); + int digit_num = digit_ord(i); + + if (v) + d[digit_num] |= one_and_zeros(bit_num); + else + d[digit_num] &= ~(one_and_zeros(bit_num)); +} + + +// ---------------------------------------------------------------------------- +// Function to check if a double number is bad (NaN or infinite). +// ---------------------------------------------------------------------------- + +inline bool +is_nan(double v) +{ + return std::numeric_limits<double>::has_quiet_NaN && (v != v); +} + +inline bool +is_inf(double v) +{ + return v == std::numeric_limits<double>::infinity() || + v == -std::numeric_limits<double>::infinity(); +} + +inline void +is_bad_double(double v) +{ + // Windows throws exception. + if (is_nan(v) || is_inf(v)) + SC_REPORT_ERROR("value is not valid", + "is_bad_double(double v) : " + "v is not finite - NaN or Inf"); +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_NBUTILS_HH__ diff --git a/src/systemc/ext/dt/int/sc_signed.hh b/src/systemc/ext/dt/int/sc_signed.hh new file mode 100644 index 000000000..9d31a276d --- /dev/null +++ b/src/systemc/ext/dt/int/sc_signed.hh @@ -0,0 +1,2504 @@ +/***************************************************************************** + + 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_signed.h -- Arbitrary precision signed arithmetic. + + This file includes the definitions of sc_signed_bitref, + sc_signed_subref, and sc_signed classes. The first two classes are + proxy classes to reference one bit and a range of bits of a + sc_signed number, respectively. + + An sc_signed number has the sign-magnitude representation + internally. However, its interface guarantees a 2's-complement + representation. The sign-magnitude representation is chosen + because of its efficiency: The sc_signed and sc_unsigned types are + optimized for arithmetic rather than bitwise operations. For + arithmetic operations, the sign-magnitude representation performs + better. + + The implementations of sc_signed and sc_unsigned classes are + almost identical: Most of the member and friend functions are + defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can + be shared by both of these classes. These functions are chosed by + defining a few macros before including them such as IF_SC_SIGNED + and CLASS_TYPE. Our implementation choices are mostly dictated by + performance considerations in that we tried to provide the most + efficient sc_signed and sc_unsigned types without compromising + their interface. + + For the behavior of operators, we have two semantics: the old and + new. The most important difference between these two semantics is + that the old semantics is closer to C/C++ semantics in that the + result type of a binary operator on unsigned and signed arguments + is unsigned; the new semantics, on the other hand, requires the + result type be signed. The new semantics is required by the VSIA + C/C++ data types standard. We have implemented the new semantics. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_signed.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/08 17:50:01 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.4 2006/03/13 20:25:27 acg +// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend() +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_SIGNED_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_SIGNED_HH__ + +#include <iostream> + +#include "../misc/sc_value_base.hh" +#include "../sc_temporary.hh" +#include "sc_length_param.hh" +#include "sc_nbdefs.hh" +#include "sc_nbexterns.hh" +#include "sc_nbutils.hh" +#include "sc_unsigned.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_signed_bitref_r; +class sc_signed_bitref; +class sc_signed_subref_r; +class sc_signed_subref; +class sc_concatref; +class sc_signed; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_base; +class sc_uint_base; +class sc_int_subref_r; +class sc_uint_subref_r; +class sc_signed; +class sc_unsigned; +class sc_unsigned_subref_r; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + +} // namespace sc_dt + +// extern template instantiations +namespace sc_core +{ + +extern template class sc_vpool<sc_dt::sc_signed_bitref>; +extern template class sc_vpool<sc_dt::sc_signed_subref>; + +} // namespace sc_core + +namespace sc_dt +{ + +// Helper function declarations +sc_signed add_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_signed sub_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_signed mul_signed_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_signed div_signed_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_signed mod_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_signed and_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_signed or_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_signed xor_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +/* + * friend operator declarations + */ + +// ARITHMETIC OPERATORS: + +// ADDition operators: +sc_signed operator + (const sc_unsigned &u, const sc_signed &v); +sc_signed operator + (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator + (const sc_unsigned &u, int64 v); +sc_signed operator + (const sc_unsigned &u, long v); +inline sc_signed operator + (const sc_unsigned &u, int v); + +sc_signed operator + (int64 u, const sc_unsigned &v); +sc_signed operator + (long u, const sc_unsigned &v); +inline sc_signed operator + (int u, const sc_unsigned &v); + +sc_signed operator + (const sc_signed &u, const sc_signed &v); +sc_signed operator + (const sc_signed &u, int64 v); +sc_signed operator + (const sc_signed &u, uint64 v); +sc_signed operator + (const sc_signed &u, long v); +sc_signed operator + (const sc_signed &u, unsigned long v); +inline sc_signed operator + (const sc_signed &u, int v); +inline sc_signed operator + (const sc_signed &u, unsigned int v); + +sc_signed operator + (int64 u, const sc_signed &v); +sc_signed operator + (uint64 u, const sc_signed &v); +sc_signed operator + (long u, const sc_signed &v); +sc_signed operator + (unsigned long u, const sc_signed &v); +inline sc_signed operator + (int u, const sc_signed &v); +inline sc_signed operator + (unsigned int u, const sc_signed &v); + +sc_signed operator + (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator + (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator + (const sc_signed &u, const sc_int_base &v); +sc_signed operator + (const sc_signed &u, const sc_uint_base &v); +sc_signed operator + (const sc_int_base &u, const sc_signed &v); +sc_signed operator + (const sc_uint_base &u, const sc_signed &v); + + +// SUBtraction operators: +sc_signed operator - (const sc_unsigned &u, const sc_signed &v); +sc_signed operator - (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator - (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator - (const sc_unsigned &u, int64 v); +sc_signed operator - (const sc_unsigned &u, uint64 v); +sc_signed operator - (const sc_unsigned &u, long v); +sc_signed operator - (const sc_unsigned &u, unsigned long v); +inline sc_signed operator - (const sc_unsigned &u, int v); +inline sc_signed operator - (const sc_unsigned &u, unsigned int v); + +sc_signed operator - (int64 u, const sc_unsigned &v); +sc_signed operator - (uint64 u, const sc_unsigned &v); +sc_signed operator - (long u, const sc_unsigned &v); +sc_signed operator - (unsigned long u, const sc_unsigned &v); +inline sc_signed operator - (int u, const sc_unsigned &v); +inline sc_signed operator - (unsigned int u, const sc_unsigned &v); + +sc_signed operator - (const sc_signed &u, const sc_signed &v); +sc_signed operator - (const sc_signed &u, int64 v); +sc_signed operator - (const sc_signed &u, uint64 v); +sc_signed operator - (const sc_signed &u, long v); +sc_signed operator - (const sc_signed &u, unsigned long v); +inline sc_signed operator - (const sc_signed &u, int v); +inline sc_signed operator - (const sc_signed &u, unsigned int v); + +sc_signed operator - (int64 u, const sc_signed &v); +sc_signed operator - (uint64 u, const sc_signed &v); +sc_signed operator - (long u, const sc_signed &v); +sc_signed operator - (unsigned long u, const sc_signed &v); +inline sc_signed operator - (int u, const sc_signed &v); +inline sc_signed operator - (unsigned int u, const sc_signed &v); + + +sc_signed operator - (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator - (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator - (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator - (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator - (const sc_signed &u, const sc_int_base &v); +sc_signed operator - (const sc_signed &u, const sc_uint_base &v); +sc_signed operator - (const sc_int_base &u, const sc_signed &v); +sc_signed operator - (const sc_uint_base &u, const sc_signed &v); + + +// MULtiplication operators: +sc_signed operator * (const sc_unsigned &u, const sc_signed &v); +sc_signed operator * (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator * (const sc_unsigned &u, int64 v); +sc_signed operator * (const sc_unsigned &u, long v); +inline sc_signed operator * (const sc_unsigned &u, int v); + +sc_signed operator * (int64 u, const sc_unsigned &v); +sc_signed operator * (long u, const sc_unsigned &v); +inline sc_signed operator * (int u, const sc_unsigned &v); + +sc_signed operator * (const sc_signed &u, const sc_signed &v); +sc_signed operator * (const sc_signed &u, int64 v); +sc_signed operator * (const sc_signed &u, uint64 v); +sc_signed operator * (const sc_signed &u, long v); +sc_signed operator * (const sc_signed &u, unsigned long v); +inline sc_signed operator * (const sc_signed &u, int v); +inline sc_signed operator * (const sc_signed &u, unsigned int v); + +sc_signed operator * (int64 u, const sc_signed &v); +sc_signed operator * (uint64 u, const sc_signed &v); +sc_signed operator * (long u, const sc_signed &v); +sc_signed operator * (unsigned long u, const sc_signed &v); +inline sc_signed operator * (int u, const sc_signed &v); +inline sc_signed operator * (unsigned int u, const sc_signed &v); + +sc_signed operator * (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator * (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator * (const sc_signed &u, const sc_int_base &v); +sc_signed operator * (const sc_signed &u, const sc_uint_base &v); +sc_signed operator * (const sc_int_base &u, const sc_signed &v); +sc_signed operator * (const sc_uint_base &u, const sc_signed &v); + + +// DIVision operators: +sc_signed operator / (const sc_unsigned &u, const sc_signed &v); +sc_signed operator / (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator / (const sc_unsigned &u, int64 v); +sc_signed operator / (const sc_unsigned &u, long v); +inline sc_signed operator / (const sc_unsigned &u, int v); + +sc_signed operator / (int64 u, const sc_unsigned &v); +sc_signed operator / (long u, const sc_unsigned &v); +inline sc_signed operator / (int u, const sc_unsigned &v); + +sc_signed operator / (const sc_signed &u, const sc_signed &v); +sc_signed operator / (const sc_signed &u, int64 v); +sc_signed operator / (const sc_signed &u, uint64 v); +sc_signed operator / (const sc_signed &u, long v); +sc_signed operator / (const sc_signed &u, unsigned long v); +inline sc_signed operator / (const sc_signed &u, int v); +inline sc_signed operator / (const sc_signed &u, unsigned int v); + +sc_signed operator / (int64 u, const sc_signed &v); +sc_signed operator / (uint64 u, const sc_signed &v); +sc_signed operator / (long u, const sc_signed &v); +sc_signed operator / (unsigned long u, const sc_signed &v); +inline sc_signed operator / (int u, const sc_signed &v); +inline sc_signed operator / (unsigned int u, const sc_signed &v); + +sc_signed operator / (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator / (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator / (const sc_signed &u, const sc_int_base &v); +sc_signed operator / (const sc_signed &u, const sc_uint_base &v); +sc_signed operator / (const sc_int_base &u, const sc_signed &v); +sc_signed operator / (const sc_uint_base &u, const sc_signed &v); + + +// MODulo operators: +sc_signed operator % (const sc_unsigned &u, const sc_signed &v); +sc_signed operator % (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator % (const sc_unsigned &u, int64 v); +sc_signed operator % (const sc_unsigned &u, long v); +inline sc_signed operator % (const sc_unsigned &u, int v); + +sc_signed operator % (int64 u, const sc_unsigned &v); +sc_signed operator % (long u, const sc_unsigned &v); +inline sc_signed operator % (int u, const sc_unsigned &v); + +sc_signed operator % (const sc_signed &u, const sc_signed &v); +sc_signed operator % (const sc_signed &u, int64 v); +sc_signed operator % (const sc_signed &u, uint64 v); +sc_signed operator % (const sc_signed &u, long v); +sc_signed operator % (const sc_signed &u, unsigned long v); +inline sc_signed operator % (const sc_signed &u, int v); +inline sc_signed operator % (const sc_signed &u, unsigned int v); + +sc_signed operator % (int64 u, const sc_signed &v); +sc_signed operator % (uint64 u, const sc_signed &v); +sc_signed operator % (long u, const sc_signed &v); +sc_signed operator % (unsigned long u, const sc_signed &v); +inline sc_signed operator % (int u, const sc_signed &v); +inline sc_signed operator % (unsigned int u, const sc_signed &v); + +sc_signed operator % (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator % (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator % (const sc_signed &u, const sc_int_base &v); +sc_signed operator % (const sc_signed &u, const sc_uint_base &v); +sc_signed operator % (const sc_int_base &u, const sc_signed &v); +sc_signed operator % (const sc_uint_base &u, const sc_signed &v); + + +// BITWISE OPERATORS: + +// Bitwise AND operators: +sc_signed operator & (const sc_unsigned &u, const sc_signed &v); +sc_signed operator & (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator & (const sc_unsigned &u, int64 v); +sc_signed operator & (const sc_unsigned &u, long v); +inline sc_signed operator & (const sc_unsigned &u, int v); + +sc_signed operator & (int64 u, const sc_unsigned &v); +sc_signed operator & (long u, const sc_unsigned &v); +inline sc_signed operator & (int u, const sc_unsigned &v); + +sc_signed operator & (const sc_signed &u, const sc_signed &v); +sc_signed operator & (const sc_signed &u, int64 v); +sc_signed operator & (const sc_signed &u, uint64 v); +sc_signed operator & (const sc_signed &u, long v); +sc_signed operator & (const sc_signed &u, unsigned long v); +inline sc_signed operator & (const sc_signed &u, int v); +inline sc_signed operator & (const sc_signed &u, unsigned int v); + +sc_signed operator & (int64 u, const sc_signed &v); +sc_signed operator & (uint64 u, const sc_signed &v); +sc_signed operator & (long u, const sc_signed &v); +sc_signed operator & (unsigned long u, const sc_signed &v); +inline sc_signed operator & (int u, const sc_signed &v); +inline sc_signed operator & (unsigned int u, const sc_signed &v); + +sc_signed operator & (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator & (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator & (const sc_signed &u, const sc_int_base &v); +sc_signed operator & (const sc_signed &u, const sc_uint_base &v); +sc_signed operator & (const sc_int_base &u, const sc_signed &v); +sc_signed operator & (const sc_uint_base &u, const sc_signed &v); + + +// Bitwise OR operators: +sc_signed operator | (const sc_unsigned &u, const sc_signed &v); +sc_signed operator | (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator | (const sc_unsigned &u, int64 v); +sc_signed operator | (const sc_unsigned &u, long v); +inline sc_signed operator | (const sc_unsigned &u, int v); + +sc_signed operator | (int64 u, const sc_unsigned &v); +sc_signed operator | (long u, const sc_unsigned &v); +inline sc_signed operator | (int u, const sc_unsigned &v); + +sc_signed operator | (const sc_signed &u, const sc_signed &v); +sc_signed operator | (const sc_signed &u, int64 v); +sc_signed operator | (const sc_signed &u, uint64 v); +sc_signed operator | (const sc_signed &u, long v); +sc_signed operator | (const sc_signed &u, unsigned long v); +inline sc_signed operator | (const sc_signed &u, int v); +inline sc_signed operator | (const sc_signed &u, unsigned int v); + +sc_signed operator | (int64 u, const sc_signed &v); +sc_signed operator | (uint64 u, const sc_signed &v); +sc_signed operator | (long u, const sc_signed &v); +sc_signed operator | (unsigned long u, const sc_signed &v); +inline sc_signed operator | (int u, const sc_signed &v); +inline sc_signed operator | (unsigned int u, const sc_signed &v); + +sc_signed operator | (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator | (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator | (const sc_signed &u, const sc_int_base &v); +sc_signed operator | (const sc_signed &u, const sc_uint_base &v); +sc_signed operator | (const sc_int_base &u, const sc_signed &v); +sc_signed operator | (const sc_uint_base &u, const sc_signed &v); + + +// Bitwise XOR operators: +sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v); +sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator ^ (const sc_unsigned &u, int64 v); +sc_signed operator ^ (const sc_unsigned &u, long v); +inline sc_signed operator ^ (const sc_unsigned &u, int v); + +sc_signed operator ^ (int64 u, const sc_unsigned &v); +sc_signed operator ^ (long u, const sc_unsigned &v); +inline sc_signed operator ^ (int u, const sc_unsigned &v); + +sc_signed operator ^ (const sc_signed &u, const sc_signed &v); +sc_signed operator ^ (const sc_signed &u, int64 v); +sc_signed operator ^ (const sc_signed &u, uint64 v); +sc_signed operator ^ (const sc_signed &u, long v); +sc_signed operator ^ (const sc_signed &u, unsigned long v); +inline sc_signed operator ^ (const sc_signed &u, int v); +inline sc_signed operator ^ (const sc_signed &u, unsigned int v); + +sc_signed operator ^ (int64 u, const sc_signed &v); +sc_signed operator ^ (uint64 u, const sc_signed &v); +sc_signed operator ^ (long u, const sc_signed &v); +sc_signed operator ^ (unsigned long u, const sc_signed &v); +inline sc_signed operator ^ (int u, const sc_signed &v); +inline sc_signed operator ^ (unsigned int u, const sc_signed &v); + +sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v); +sc_signed operator ^ (const sc_signed &u, const sc_int_base &v); +sc_signed operator ^ (const sc_signed &u, const sc_uint_base &v); +sc_signed operator ^ (const sc_int_base &u, const sc_signed &v); +sc_signed operator ^ (const sc_uint_base &u, const sc_signed &v); + + +// SHIFT OPERATORS: +// LEFT SHIFT operators: +sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v); +sc_signed operator << (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator << (const sc_signed &u, const sc_signed &v); +sc_signed operator << (const sc_signed &u, int64 v); +sc_signed operator << (const sc_signed &u, uint64 v); +sc_signed operator << (const sc_signed &u, long v); +sc_signed operator << (const sc_signed &u, unsigned long v); +inline sc_signed operator << (const sc_signed &u, int v); +inline sc_signed operator << (const sc_signed &u, unsigned int v); + +sc_signed operator << (const sc_signed &u, const sc_int_base &v); +sc_signed operator << (const sc_signed &u, const sc_uint_base &v); + + +// RIGHT SHIFT operators: +sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v); +sc_signed operator >> (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator >> (const sc_signed &u, const sc_signed &v); +sc_signed operator >> (const sc_signed &u, int64 v); +sc_signed operator >> (const sc_signed &u, uint64 v); +sc_signed operator >> (const sc_signed &u, long v); +sc_signed operator >> (const sc_signed &u, unsigned long v); +inline sc_signed operator >> (const sc_signed &u, int v); +inline sc_signed operator >> (const sc_signed &u, unsigned int v); + +sc_signed operator >> (const sc_signed &u, const sc_int_base &v); +sc_signed operator >> (const sc_signed &u, const sc_uint_base &v); + + +// Unary arithmetic operators +sc_signed operator + (const sc_signed &u); +sc_signed operator - (const sc_signed &u); +sc_signed operator - (const sc_unsigned &u); + + +// LOGICAL OPERATORS: + +// Logical EQUAL operators: +bool operator == (const sc_unsigned &u, const sc_signed &v); +bool operator == (const sc_signed &u, const sc_unsigned &v); + +bool operator == (const sc_signed &u, const sc_signed &v); +bool operator == (const sc_signed &u, int64 v); +bool operator == (const sc_signed &u, uint64 v); +bool operator == (const sc_signed &u, long v); +bool operator == (const sc_signed &u, unsigned long v); +inline bool operator == (const sc_signed &u, int v); +inline bool operator == (const sc_signed &u, unsigned int v); + +bool operator == (int64 u, const sc_signed &v); +bool operator == (uint64 u, const sc_signed &v); +bool operator == (long u, const sc_signed &v); +bool operator == (unsigned long u, const sc_signed &v); +inline bool operator == (int u, const sc_signed &v); +inline bool operator == (unsigned int u, const sc_signed &v); + +bool operator == (const sc_signed &u, const sc_int_base &v); +bool operator == (const sc_signed &u, const sc_uint_base &v); +bool operator == (const sc_int_base &u, const sc_signed &v); +bool operator == (const sc_uint_base &u, const sc_signed &v); + +// Logical NOT_EQUAL operators: +bool operator != (const sc_unsigned &u, const sc_signed &v); +bool operator != (const sc_signed &u, const sc_unsigned &v); + +bool operator != (const sc_signed &u, const sc_signed &v); +bool operator != (const sc_signed &u, int64 v); +bool operator != (const sc_signed &u, uint64 v); +bool operator != (const sc_signed &u, long v); +bool operator != (const sc_signed &u, unsigned long v); +inline bool operator != (const sc_signed &u, int v); +inline bool operator != (const sc_signed &u, unsigned int v); + +bool operator != (int64 u, const sc_signed &v); +bool operator != (uint64 u, const sc_signed &v); +bool operator != (long u, const sc_signed &v); +bool operator != (unsigned long u, const sc_signed &v); +inline bool operator != (int u, const sc_signed &v); +inline bool operator != (unsigned int u, const sc_signed &v); + +bool operator != (const sc_signed &u, const sc_int_base &v); +bool operator != (const sc_signed &u, const sc_uint_base &v); +bool operator != (const sc_int_base &u, const sc_signed &v); +bool operator != (const sc_uint_base &u, const sc_signed &v); + +// Logical LESS_THAN operators: +bool operator < (const sc_unsigned &u, const sc_signed &v); +bool operator < (const sc_signed &u, const sc_unsigned &v); + +bool operator < (const sc_signed &u, const sc_signed &v); +bool operator < (const sc_signed &u, int64 v); +bool operator < (const sc_signed &u, uint64 v); +bool operator < (const sc_signed &u, long v); +bool operator < (const sc_signed &u, unsigned long v); +inline bool operator < (const sc_signed &u, int v); +inline bool operator < (const sc_signed &u, unsigned int v); + +bool operator < (int64 u, const sc_signed &v); +bool operator < (uint64 u, const sc_signed &v); +bool operator < (long u, const sc_signed &v); +bool operator < (unsigned long u, const sc_signed &v); +inline bool operator < (int u, const sc_signed &v); +inline bool operator < (unsigned int u, const sc_signed &v); + +bool operator < (const sc_signed &u, const sc_int_base &v); +bool operator < (const sc_signed &u, const sc_uint_base &v); +bool operator < (const sc_int_base &u, const sc_signed &v); +bool operator < (const sc_uint_base &u, const sc_signed &v); + +// Logical LESS_THAN_AND_EQUAL operators: +bool operator <= (const sc_unsigned &u, const sc_signed &v); +bool operator <= (const sc_signed &u, const sc_unsigned &v); + +bool operator <= (const sc_signed &u, const sc_signed &v); +bool operator <= (const sc_signed &u, int64 v); +bool operator <= (const sc_signed &u, uint64 v); +bool operator <= (const sc_signed &u, long v); +bool operator <= (const sc_signed &u, unsigned long v); +inline bool operator <= (const sc_signed &u, int v); +inline bool operator <= (const sc_signed &u, unsigned int v); + +bool operator <= (int64 u, const sc_signed &v); +bool operator <= (uint64 u, const sc_signed &v); +bool operator <= (long u, const sc_signed &v); +bool operator <= (unsigned long u, const sc_signed &v); +inline bool operator <= (int u, const sc_signed &v); +inline bool operator <= (unsigned int u, const sc_signed &v); + +bool operator <= (const sc_signed &u, const sc_int_base &v); +bool operator <= (const sc_signed &u, const sc_uint_base &v); +bool operator <= (const sc_int_base &u, const sc_signed &v); +bool operator <= (const sc_uint_base &u, const sc_signed &v); + +// Logical GREATER_THAN operators: +bool operator > (const sc_unsigned &u, const sc_signed &v); +bool operator > (const sc_signed &u, const sc_unsigned &v); + +bool operator > (const sc_signed &u, const sc_signed &v); +bool operator > (const sc_signed &u, int64 v); +bool operator > (const sc_signed &u, uint64 v); +bool operator > (const sc_signed &u, long v); +bool operator > (const sc_signed &u, unsigned long v); +inline bool operator > (const sc_signed &u, int v); +inline bool operator > (const sc_signed &u, unsigned int v); + +bool operator > (int64 u, const sc_signed &v); +bool operator > (uint64 u, const sc_signed &v); +bool operator > (long u, const sc_signed &v); +bool operator > (unsigned long u, const sc_signed &v); +inline bool operator > (int u, const sc_signed &v); +inline bool operator > (unsigned int u, const sc_signed &v); + +bool operator > (const sc_signed &u, const sc_int_base &v); +bool operator > (const sc_signed &u, const sc_uint_base &v); +bool operator > (const sc_int_base &u, const sc_signed &v); +bool operator > (const sc_uint_base &u, const sc_signed &v); + +// Logical GREATER_THAN_AND_EQUAL operators: +bool operator >= (const sc_unsigned &u, const sc_signed &v); +bool operator >= (const sc_signed &u, const sc_unsigned &v); + +bool operator >= (const sc_signed &u, const sc_signed &v); +bool operator >= (const sc_signed &u, int64 v); +bool operator >= (const sc_signed &u, uint64 v); +bool operator >= (const sc_signed &u, long v); +bool operator >= (const sc_signed &u, unsigned long v); +inline bool operator >= (const sc_signed &u, int v); +inline bool operator >= (const sc_signed &u, unsigned int v); + +bool operator >= (int64 u, const sc_signed &v); +bool operator >= (uint64 u, const sc_signed &v); +bool operator >= (long u, const sc_signed &v); +bool operator >= (unsigned long u, const sc_signed &v); +inline bool operator >= (int u, const sc_signed &v); +inline bool operator >= (unsigned int u, const sc_signed &v); + +bool operator >= (const sc_signed &u, const sc_int_base &v); +bool operator >= (const sc_signed &u, const sc_uint_base &v); +bool operator >= (const sc_int_base &u, const sc_signed &v); +bool operator >= (const sc_uint_base &u, const sc_signed &v); + + // Bitwise NOT operator (unary). +sc_signed operator ~ (const sc_signed &u); + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref_r +// +// Proxy class for sc_signed bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_signed_bitref_r : public sc_value_base +{ + friend class sc_signed; + protected: + // constructor + sc_signed_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {} + + void + initialize(const sc_signed* obj_p, int index_) + { + m_index = index_; + m_obj_p = const_cast<sc_signed*>(obj_p); + } + + public: + // destructor + virtual ~sc_signed_bitref_r() {} + + // copy constructor + sc_signed_bitref_r(const sc_signed_bitref_r &a) : + sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) + {} + + // capacity + int length() const { return 1; } + + + // implicit conversion to bool + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + + // explicit conversions + bool value() const { return operator uint64(); } + + bool to_bool() const { return operator uint64(); } + + // concatenation support + virtual int + concat_length(bool* xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return 1; + } + + virtual uint64 + concat_get_uint64() const + { + return (uint64)operator uint64(); + } + virtual bool + concat_get_ctrl(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + dst_p[word_i] &= ~bit_mask; + return false; + } + + virtual bool + concat_get_data( sc_digit* dst_p, int low_i ) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True if non-zero. + int word_i = low_i / BITS_PER_DIGIT; + if (operator uint64()) { + dst_p[word_i] |= bit_mask; + result = true; + } else { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_bool(); } + + protected: + int m_index; // Bit to be selected. + sc_signed *m_obj_p; // Target of this bit selection. + + private: + // Disabled + const sc_signed_bitref_r &operator = (const sc_signed_bitref_r &); +}; + + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_signed_bitref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_bitref +// +// Proxy class for sc_signed bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_signed_bitref : public sc_signed_bitref_r +{ + friend class sc_signed; + friend class sc_core::sc_vpool<sc_signed_bitref>; + + protected: + // constructor + sc_signed_bitref() : sc_signed_bitref_r() {} + + public: + // copy constructor + sc_signed_bitref(const sc_signed_bitref &a) : sc_signed_bitref_r(a) {} + + // assignment operators + const sc_signed_bitref &operator = (const sc_signed_bitref_r &); + const sc_signed_bitref &operator = (const sc_signed_bitref &); + const sc_signed_bitref &operator = (bool); + + const sc_signed_bitref &operator &= (bool); + const sc_signed_bitref &operator |= (bool); + const sc_signed_bitref &operator ^= (bool); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_signed_bitref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_signed_bitref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref_r +// +// Proxy class for sc_signed part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_signed_subref_r : public sc_value_base +{ + friend class sc_signed; + friend class sc_signed_signal; + friend class sc_unsigned; + + protected: + // constructor + sc_signed_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + void + initialize(const sc_signed *obj_p, int left_, int right_) + { + m_obj_p = (const_cast<sc_signed*>(obj_p)); + m_left = left_; + m_right = right_; + } + + public: + // destructor + virtual ~sc_signed_subref_r() {} + + // copy constructor + sc_signed_subref_r(const sc_signed_subref_r &a) : + sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p), + m_right(a.m_right) + {} + + // capacity + int + length() const + { + return m_left >= m_right ? (m_left-m_right + 1) : (m_right-m_left + 1); + } + + // implicit conversion to sc_unsigned + operator sc_unsigned () 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; + double to_double() const; + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // concatenation support + virtual int + concat_length(bool* xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return m_left - m_right + 1; + } + virtual uint64 concat_get_uint64() const; + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const ; + bool xnor_reduce() const; + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + protected: + int m_left; // Left-most bit in this part selection. + sc_signed *m_obj_p; // Target of this part selection. + int m_right; // Right-most bit in this part selection. + + private: + const sc_signed_subref_r &operator = (const sc_signed_subref_r &); +}; + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_signed_subref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref +// +// Proxy class for sc_signed part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_signed_subref : public sc_signed_subref_r +{ + friend class sc_signed; + friend class sc_core::sc_vpool<sc_signed_subref>; + + // constructor + sc_signed_subref() : sc_signed_subref_r() {} + + public: + // copy constructor + sc_signed_subref(const sc_signed_subref &a) : sc_signed_subref_r(a) {} + + // assignment operators + const sc_signed_subref &operator = (const sc_signed_subref_r &a); + const sc_signed_subref &operator = (const sc_signed_subref &a); + const sc_signed_subref &operator = (const sc_signed &a); + + const sc_signed_subref &operator = (const sc_unsigned_subref_r &a); + const sc_signed_subref &operator = (const sc_unsigned &a); + + template< class T > + const sc_signed_subref & + operator = (const sc_generic_base<T> &a) + { + sc_unsigned temp(length()); + a->to_sc_unsigned(temp); + return operator = (temp); + } + + const sc_signed_subref &operator = (const char *a); + const sc_signed_subref &operator = (unsigned long a); + const sc_signed_subref &operator = (long a); + const sc_signed_subref & + operator = (unsigned int a) + { + return operator = ((unsigned long)a); + } + + const sc_signed_subref & + operator = (int a) + { + return operator = ((long)a); + } + + const sc_signed_subref &operator = (uint64 a); + const sc_signed_subref &operator = (int64 a); + const sc_signed_subref &operator = (double a); + const sc_signed_subref &operator = (const sc_int_base &a); + const sc_signed_subref &operator = (const sc_uint_base &a); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_signed_subref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_signed_subref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +class sc_signed : public sc_value_base +{ + friend class sc_concatref; + friend class sc_signed_bitref_r; + friend class sc_signed_bitref; + friend class sc_signed_subref_r; + friend class sc_signed_subref; + friend class sc_unsigned; + friend class sc_unsigned_subref; + + // Needed for types using sc_signed. + typedef bool elemtype; + + void invalid_init(const char *type_name, int nb) const; + + public: + // constructors + explicit sc_signed(int nb=sc_length_param().len()); + sc_signed(const sc_signed &v); + sc_signed(const sc_unsigned &v); + template<class T> + explicit sc_signed(const sc_generic_base<T> &v); + explicit sc_signed(const sc_bv_base &v); + explicit sc_signed(const sc_lv_base &v); + explicit sc_signed(const sc_int_subref_r &v); + explicit sc_signed(const sc_uint_subref_r &v); + explicit sc_signed(const sc_signed_subref_r &v); + explicit sc_signed(const sc_unsigned_subref_r &v); + + // assignment operators + const sc_signed &operator = (const sc_signed &v); + const sc_signed &operator = (const sc_signed_subref_r &a); + + template< class T > + const sc_signed & + operator = (const sc_generic_base<T> &a) + { + a->to_sc_signed(*this); + return *this; + } + + const sc_signed &operator = (const sc_unsigned &v); + const sc_signed &operator = (const sc_unsigned_subref_r &a); + + const sc_signed &operator = (const char *v); + const sc_signed &operator = (int64 v); + const sc_signed &operator = (uint64 v); + const sc_signed &operator = (long v); + const sc_signed &operator = (unsigned long v); + + const sc_signed &operator = (int v) { return operator=((long)v); } + + const sc_signed & + operator = (unsigned int v) + { + return operator=((unsigned long)v); + } + + const sc_signed &operator = (double v); + const sc_signed &operator = (const sc_int_base & v); + const sc_signed &operator = (const sc_uint_base & v); + + const sc_signed &operator = (const sc_bv_base &); + const sc_signed &operator = (const sc_lv_base &); + + const sc_signed &operator = (const sc_fxval &); + const sc_signed &operator = (const sc_fxval_fast &); + const sc_signed &operator = (const sc_fxnum &); + const sc_signed &operator = (const sc_fxnum_fast &); + + // destructor + virtual ~sc_signed() + { +#ifndef SC_MAX_NBITS + delete [] digit; +#endif + } + + // Concatenation support: + sc_digit* get_raw() const { return digit; } + virtual int + concat_length(bool* xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return nbits; + } + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; + virtual uint64 concat_get_uint64() const; + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // Increment operators. + sc_signed &operator ++ (); + const sc_signed operator ++ (int); + + // Decrement operators. + sc_signed &operator -- (); + const sc_signed operator -- (int); + + // bit selection + inline void + check_index(int i) const + { + if (i < 0 || i >= nbits) + invalid_index(i); + } + + void invalid_index(int i) const; + + sc_signed_bitref & + operator [] (int i) + { + check_index(i); + sc_signed_bitref *result_p = sc_signed_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + const sc_signed_bitref_r & + operator [] (int i) const + { + check_index(i); + sc_signed_bitref *result_p = sc_signed_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + sc_signed_bitref & + bit(int i) + { + check_index(i); + sc_signed_bitref *result_p = sc_signed_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + const sc_signed_bitref_r & + bit(int i) const + { + check_index(i); + sc_signed_bitref *result_p = sc_signed_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + + // part selection + + // Subref operators. Help access the range of bits from the ith to + // jth. These indices have arbitrary precedence with respect to each + // other, i.e., we can have i <= j or i > j. Note the equivalence + // between range(i, j) and operator(i, j). Also note that + // operator(i, i) returns a signed number that corresponds to the + // bit operator[i], so these two forms are not the same. + + inline void + check_range(int l, int r) const + { + if (l < r) + { + if (l < 0 || r >= nbits) + invalid_range(l, r); + } else { + if (r < 0 || l >= nbits) + invalid_range(l, r); + } + } + + void invalid_range(int l, int r) const; + + sc_signed_subref & + range(int i, int j) + { + check_range(i, j); + sc_signed_subref *result_p = sc_signed_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + const sc_signed_subref_r & + range(int i, int j) const + { + check_range(i, j); + sc_signed_subref *result_p = sc_signed_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + sc_signed_subref & + operator () (int i, int j) + { + check_range(i, j); + sc_signed_subref *result_p = sc_signed_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + const sc_signed_subref_r & + operator () (int i, int j) const + { + check_range(i, j); + sc_signed_subref *result_p = sc_signed_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + + // 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; + double to_double() const; + + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + + // Print functions. dump prints the internals of the class. + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + void scan(::std::istream &is=::std::cin); + + void dump(::std::ostream &os=::std::cout) const; + + // Functions to find various properties. + int length() const { return nbits; } // Bit width. + bool iszero() const; // Is the number zero? + bool sign() const; // Sign. + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return !or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return !xor_reduce(); } + + // Functions to access individual bits. + bool test(int i) const; // Is the ith bit 0 or 1? + void set(int i); // Set the ith bit to 1. + void clear(int i); // Set the ith bit to 0. + void + set(int i, bool v) // Set the ith bit to v. + { + if (v) + set(i); + else + clear(i); + } + void + invert(int i) // Negate the ith bit. + { + if (test(i)) + clear(i); + else set(i); + } + + // Make the number equal to its mirror image. + void reverse(); + + // Get/set a packed bit representation of the number. + void get_packed_rep(sc_digit *buf) const; + void set_packed_rep(sc_digit *buf); + + /* + The comparison of the old and new semantics are as follows: + + Let s = sc_signed, + u = sc_unsigned, + un = { uint64, unsigned long, unsigned int }, + sn = { int64, long, int, char* }, and + OP = { +, -, *, /, % }. + + Old semantics: New semantics: + u OP u -> u u OP u -> u + s OP u -> u s OP u -> s + u OP s -> u u OP s -> s + s OP s -> s s OP s -> s + + u OP un = un OP u -> u u OP un = un OP u -> u + u OP sn = sn OP u -> u u OP sn = sn OP u -> s + + s OP un = un OP s -> s s OP un = un OP s -> s + s OP sn = sn OP s -> s s OP sn = sn OP s -> s + + In the new semantics, the result is u if both operands are u; the + result is s otherwise. The only exception is subtraction. The result + of a subtraction is always s. + + The old semantics is like C/C++ semantics on integer types; the + new semantics is due to the VSIA C/C++ data types standard. + */ + + // ARITHMETIC OPERATORS: + + // ADDition operators: + friend sc_signed operator + (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator + (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator + (const sc_unsigned &u, int64 v); + friend sc_signed operator + (const sc_unsigned &u, long v); + friend sc_signed + operator + (const sc_unsigned &u, int v) + { + return operator + (u, (long)v); + } + + friend sc_signed operator + (int64 u, const sc_unsigned &v); + friend sc_signed operator + (long u, const sc_unsigned &v); + friend sc_signed + operator + (int u, const sc_unsigned &v) + { + return operator + ((long)u, v); + } + + friend sc_signed operator + (const sc_signed &u, const sc_signed &v); + friend sc_signed operator + (const sc_signed &u, int64 v); + friend sc_signed operator + (const sc_signed &u, uint64 v); + friend sc_signed operator + (const sc_signed &u, long v); + friend sc_signed operator + (const sc_signed &u, unsigned long v); + friend sc_signed + operator + (const sc_signed &u, int v) + { + return operator + (u, (long)v); + } + friend sc_signed + operator + (const sc_signed &u, unsigned int v) + { + return operator + (u, (unsigned long)v); + } + + friend sc_signed operator + (int64 u, const sc_signed &v); + friend sc_signed operator + (uint64 u, const sc_signed &v); + friend sc_signed operator + (long u, const sc_signed &v); + friend sc_signed operator + (unsigned long u, const sc_signed &v); + friend sc_signed + operator + (int u, const sc_signed &v) + { + return operator + ((long)u, v); + } + friend sc_signed + operator + (unsigned int u, const sc_signed &v) + { + return operator + ((unsigned long)u, v); + } + + const sc_signed &operator += (const sc_signed &v); + const sc_signed &operator += (const sc_unsigned &v); + const sc_signed &operator += (int64 v); + const sc_signed &operator += (uint64 v); + const sc_signed &operator += (long v); + const sc_signed &operator += (unsigned long v); + const sc_signed & + operator += (int v) + { + return operator += ((long)v); + } + const sc_signed & + operator += (unsigned int v) + { + return operator += ((unsigned long)v); + } + + friend sc_signed operator + (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator + (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator + (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator + (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator + (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator + (const sc_uint_base &u, const sc_signed &v); + const sc_signed & operator += (const sc_int_base &v); + const sc_signed & operator += (const sc_uint_base &v); + + // SUBtraction operators: + friend sc_signed operator - (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator - (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator - (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator - (const sc_unsigned &u, int64 v); + friend sc_signed operator - (const sc_unsigned &u, uint64 v); + friend sc_signed operator - (const sc_unsigned &u, long v); + friend sc_signed operator - (const sc_unsigned &u, unsigned long v); + friend sc_signed + operator - (const sc_unsigned &u, int v) + { + return operator - (u, (long)v); + } + friend sc_signed + operator - (const sc_unsigned &u, unsigned int v) + { + return operator - (u, (unsigned long)v); + } + + friend sc_signed operator - (int64 u, const sc_unsigned &v); + friend sc_signed operator - (uint64 u, const sc_unsigned &v); + friend sc_signed operator - (long u, const sc_unsigned &v); + friend sc_signed operator - (unsigned long u, const sc_unsigned &v); + friend sc_signed + operator - (int u, const sc_unsigned &v) + { + return operator - ((long)u, v); + } + friend sc_signed + operator - (unsigned int u, const sc_unsigned &v) + { + return operator - ((unsigned long)u, v); + } + + friend sc_signed operator - (const sc_signed &u, const sc_signed &v); + friend sc_signed operator - (const sc_signed &u, int64 v); + friend sc_signed operator - (const sc_signed &u, uint64 v); + friend sc_signed operator - (const sc_signed &u, long v); + friend sc_signed operator - (const sc_signed &u, unsigned long v); + friend sc_signed + operator - (const sc_signed &u, int v) + { + return operator - (u, (long) v); + } + friend sc_signed + operator - (const sc_signed &u, unsigned int v) + { + return operator - (u, (unsigned long)v); + } + + friend sc_signed operator - (int64 u, const sc_signed &v); + friend sc_signed operator - (uint64 u, const sc_signed &v); + friend sc_signed operator - (long u, const sc_signed &v); + friend sc_signed operator - (unsigned long u, const sc_signed &v); + friend sc_signed + operator - (int u, const sc_signed &v) + { + return operator - ((long)u, v); + } + friend sc_signed + operator - (unsigned int u, const sc_signed &v) + { + return operator - ((unsigned long)u, v); + } + + const sc_signed &operator -= (const sc_signed &v); + const sc_signed &operator -= (const sc_unsigned &v); + const sc_signed &operator -= (int64 v); + const sc_signed &operator -= (uint64 v); + const sc_signed &operator -= (long v); + const sc_signed &operator -= (unsigned long v); + const sc_signed & + operator -= (int v) + { + return operator -= ((long)v); + } + const sc_signed & + operator -= (unsigned int v) + { + return operator -= ((unsigned long)v); + } + + friend sc_signed operator - (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator - (const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator - (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator - (const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator - (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator - (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator - (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator - (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator -= (const sc_int_base &v); + const sc_signed &operator -= (const sc_uint_base &v); + + // MULtiplication operators: + friend sc_signed operator * (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator * (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator * (const sc_unsigned &u, int64 v); + friend sc_signed operator * (const sc_unsigned &u, long v); + friend sc_signed + operator * (const sc_unsigned &u, int v) + { + return operator * (u, (long)v); + } + + friend sc_signed operator * (int64 u, const sc_unsigned &v); + friend sc_signed operator * (long u, const sc_unsigned &v); + friend sc_signed + operator * (int u, const sc_unsigned &v) + { + return operator * ((long)u, v); + } + + friend sc_signed operator * (const sc_signed &u, const sc_signed &v); + friend sc_signed operator * (const sc_signed &u, int64 v); + friend sc_signed operator * (const sc_signed &u, uint64 v); + friend sc_signed operator * (const sc_signed &u, long v); + friend sc_signed operator * (const sc_signed &u, unsigned long v); + friend sc_signed + operator * (const sc_signed &u, int v) + { + return operator * (u, (long)v); + } + friend sc_signed + operator * (const sc_signed &u, unsigned int v) + { + return operator * (u, (unsigned long)v); + } + + friend sc_signed operator * (int64 u, const sc_signed &v); + friend sc_signed operator * (uint64 u, const sc_signed &v); + friend sc_signed operator * (long u, const sc_signed &v); + friend sc_signed operator * (unsigned long u, const sc_signed &v); + friend sc_signed + operator * (int u, const sc_signed &v) + { + return operator * ((long)u, v); + } + friend sc_signed + operator * (unsigned int u, const sc_signed &v) + { + return operator * ((unsigned long)u, v); + } + + const sc_signed &operator *= (const sc_signed &v); + const sc_signed &operator *= (const sc_unsigned &v); + const sc_signed &operator *= (int64 v); + const sc_signed &operator *= (uint64 v); + const sc_signed &operator *= (long v); + const sc_signed &operator *= (unsigned long v); + const sc_signed & + operator *= (int v) + { + return operator *= ((long)v); + } + const sc_signed & + operator *= (unsigned int v) + { + return operator *= ((unsigned long)v); + } + + friend sc_signed operator * (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator * (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator * (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator * (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator * (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator * (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator *= (const sc_int_base &v); + const sc_signed &operator *= (const sc_uint_base &v); + + // DIVision operators: + friend sc_signed operator / (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator / (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator / (const sc_unsigned &u, int64 v); + friend sc_signed operator / (const sc_unsigned &u, long v); + friend sc_signed + operator / (const sc_unsigned &u, int v) + { + return operator / (u, (long)v); + } + + friend sc_signed operator / (int64 u, const sc_unsigned &v); + friend sc_signed operator / (long u, const sc_unsigned &v); + friend sc_signed + operator / (int u, const sc_unsigned &v) + { + return operator / ((long)u, v); + } + + friend sc_signed operator / (const sc_signed &u, const sc_signed &v); + friend sc_signed operator / (const sc_signed &u, int64 v); + friend sc_signed operator / (const sc_signed &u, uint64 v); + friend sc_signed operator / (const sc_signed &u, long v); + friend sc_signed operator / (const sc_signed &u, unsigned long v); + friend sc_signed + operator / (const sc_signed &u, int v) + { + return operator / (u, (long)v); + } + friend sc_signed + operator / (const sc_signed &u, unsigned int v) + { + return operator / (u, (unsigned long)v); + } + + friend sc_signed operator / (int64 u, const sc_signed &v); + friend sc_signed operator / (uint64 u, const sc_signed &v); + friend sc_signed operator / (long u, const sc_signed &v); + friend sc_signed operator / (unsigned long u, const sc_signed &v); + friend sc_signed + operator / (int u, const sc_signed &v) + { + return operator / ((long)u, v); + } + friend sc_signed + operator / (unsigned int u, const sc_signed &v) + { + return operator / ((unsigned long)u, v); + } + + const sc_signed &operator /= (const sc_signed &v); + const sc_signed &operator /= (const sc_unsigned &v); + const sc_signed &operator /= (int64 v); + const sc_signed &operator /= (uint64 v); + const sc_signed &operator /= (long v); + const sc_signed &operator /= (unsigned long v); + const sc_signed & + operator /= (int v) + { + return operator /= ((long)v); + } + const sc_signed & + operator /= (unsigned int v) + { + return operator /= ((unsigned long)v); + } + + friend sc_signed operator / (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator / (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator / (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator / (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator / (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator / (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator /= (const sc_int_base &v); + const sc_signed &operator /= (const sc_uint_base &v); + + // MODulo operators: + friend sc_signed operator % (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator % (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator % (const sc_unsigned &u, int64 v); + friend sc_signed operator % (const sc_unsigned &u, long v); + friend sc_signed + operator % (const sc_unsigned &u, int v) + { + return operator % (u, (long)v); + } + + friend sc_signed operator % (int64 u, const sc_unsigned &v); + friend sc_signed operator % (long u, const sc_unsigned &v); + friend sc_signed + operator % (int u, const sc_unsigned &v) + { + return operator % ((long)u, v); + } + + friend sc_signed operator % (const sc_signed &u, const sc_signed &v); + friend sc_signed operator % (const sc_signed &u, int64 v); + friend sc_signed operator % (const sc_signed &u, uint64 v); + friend sc_signed operator % (const sc_signed &u, long v); + friend sc_signed operator % (const sc_signed &u, unsigned long v); + friend sc_signed + operator % (const sc_signed &u, int v) + { + return operator % (u, (long)v); + } + friend sc_signed + operator % (const sc_signed &u, unsigned int v) + { + return operator % (u, (unsigned long)v); + } + + friend sc_signed operator % (int64 u, const sc_signed &v); + friend sc_signed operator % (uint64 u, const sc_signed &v); + friend sc_signed operator % (long u, const sc_signed &v); + friend sc_signed operator % (unsigned long u, const sc_signed &v); + friend sc_signed + operator % (int u, const sc_signed &v) + { + return operator % ((long)u, v); + } + friend sc_signed + operator % (unsigned int u, const sc_signed &v) + { + return operator % ((unsigned long) u, v); + } + + const sc_signed &operator %= (const sc_signed &v); + const sc_signed &operator %= (const sc_unsigned &v); + const sc_signed &operator %= (int64 v); + const sc_signed &operator %= (uint64 v); + const sc_signed &operator %= (long v); + const sc_signed &operator %= (unsigned long v); + const sc_signed & + operator %= (int v) + { + return operator %= ((long)v); + } + const sc_signed & + operator %= (unsigned int v) + { + return operator %= ((unsigned long)v); + } + + friend sc_signed operator % (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator % (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator % (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator % (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator % (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator % (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator %= (const sc_int_base &v); + const sc_signed &operator %= (const sc_uint_base &v); + + // BITWISE OPERATORS: + + // Bitwise AND operators: + friend sc_signed operator & (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator & (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator & (const sc_unsigned &u, int64 v); + friend sc_signed operator & (const sc_unsigned &u, long v); + friend sc_signed + operator &(const sc_unsigned &u, int v) + { + return operator & (u, (long)v); + } + + friend sc_signed operator & (int64 u, const sc_unsigned &v); + friend sc_signed operator & (long u, const sc_unsigned &v); + friend sc_signed + operator & (int u, const sc_unsigned &v) + { + return operator & ((long) u, v); + } + + friend sc_signed operator & (const sc_signed &u, const sc_signed &v); + friend sc_signed operator & (const sc_signed &u, int64 v); + friend sc_signed operator & (const sc_signed &u, uint64 v); + friend sc_signed operator & (const sc_signed &u, long v); + friend sc_signed operator & (const sc_signed &u, unsigned long v); + friend sc_signed + operator & (const sc_signed &u, int v) + { + return operator & (u, (long)v); + } + friend sc_signed + operator & (const sc_signed &u, unsigned int v) + { + return operator & (u, (unsigned long)v); + } + + friend sc_signed operator & (int64 u, const sc_signed &v); + friend sc_signed operator & (uint64 u, const sc_signed &v); + friend sc_signed operator & (long u, const sc_signed &v); + friend sc_signed operator & (unsigned long u, const sc_signed &v); + friend sc_signed operator & (int u, const sc_signed &v) + { return operator&((long) u, v); } + friend sc_signed operator & (unsigned int u, const sc_signed &v) + { return operator&((unsigned long) u, v); } + + const sc_signed &operator &= (const sc_signed &v); + const sc_signed &operator &= (const sc_unsigned &v); + const sc_signed &operator &= (int64 v); + const sc_signed &operator &= (uint64 v); + const sc_signed &operator &= (long v); + const sc_signed &operator &= (unsigned long v); + const sc_signed & + operator &= (int v) + { + return operator &= ((long) v); + } + const sc_signed & + operator &= (unsigned int v) + { + return operator &= ((unsigned long) v); + } + + friend sc_signed operator & (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator & (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator & (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator & (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator & (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator & (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator &= (const sc_int_base &v); + const sc_signed &operator &= (const sc_uint_base &v); + + // Bitwise OR operators: + friend sc_signed operator | (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator | (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator | (const sc_unsigned &u, int64 v); + friend sc_signed operator | (const sc_unsigned &u, long v); + friend sc_signed + operator | (const sc_unsigned &u, int v) + { + return operator | (u, (long)v); + } + + friend sc_signed operator | (int64 u, const sc_unsigned &v); + friend sc_signed operator | (long u, const sc_unsigned &v); + friend sc_signed + operator | (int u, const sc_unsigned &v) + { + return operator | ((long)u, v); + } + + friend sc_signed operator | (const sc_signed &u, const sc_signed &v); + friend sc_signed operator | (const sc_signed &u, int64 v); + friend sc_signed operator | (const sc_signed &u, uint64 v); + friend sc_signed operator | (const sc_signed &u, long v); + friend sc_signed operator | (const sc_signed &u, unsigned long v); + friend sc_signed + operator | (const sc_signed &u, int v) + { + return operator | (u, (long)v); + } + friend sc_signed + operator | (const sc_signed &u, unsigned int v) + { + return operator | (u, (unsigned long)v); + } + + friend sc_signed operator | (int64 u, const sc_signed &v); + friend sc_signed operator | (uint64 u, const sc_signed &v); + friend sc_signed operator | (long u, const sc_signed &v); + friend sc_signed operator | (unsigned long u, const sc_signed &v); + friend sc_signed + operator | (int u, const sc_signed &v) + { + return operator | ((long) u, v); + } + friend sc_signed + operator | (unsigned int u, const sc_signed &v) + { + return operator | ((unsigned long)u, v); + } + + const sc_signed &operator |= (const sc_signed &v); + const sc_signed &operator |= (const sc_unsigned &v); + const sc_signed &operator |= (int64 v); + const sc_signed &operator |= (uint64 v); + const sc_signed &operator |= (long v); + const sc_signed &operator |= (unsigned long v); + const sc_signed & + operator |= (int v) + { + return operator |= ((long)v); + } + const sc_signed & + operator |= (unsigned int v) + { + return operator |= ((unsigned long)v); + } + + friend sc_signed operator | (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator | (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator | (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator | (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator | (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator | (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator |= (const sc_int_base &v); + const sc_signed &operator |= (const sc_uint_base &v); + + // Bitwise XOR operators: + friend sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator ^ (const sc_unsigned &u, int64 v); + friend sc_signed operator ^ (const sc_unsigned &u, long v); + friend sc_signed + operator ^ (const sc_unsigned &u, int v) + { + return operator ^ (u, (long)v); + } + + friend sc_signed operator ^ (int64 u, const sc_unsigned &v); + friend sc_signed operator ^ (long u, const sc_unsigned &v); + friend sc_signed + operator ^ (int u, const sc_unsigned &v) + { + return operator ^ ((long)u, v); + } + + friend sc_signed operator ^ (const sc_signed &u, const sc_signed &v); + friend sc_signed operator ^ (const sc_signed &u, int64 v); + friend sc_signed operator ^ (const sc_signed &u, uint64 v); + friend sc_signed operator ^ (const sc_signed &u, long v); + friend sc_signed operator ^ (const sc_signed &u, unsigned long v); + friend sc_signed + operator ^ (const sc_signed &u, int v) + { + return operator ^ (u, (long)v); + } + friend sc_signed + operator ^ (const sc_signed &u, unsigned int v) + { + return operator ^ (u, (unsigned long)v); + } + + friend sc_signed operator ^ (int64 u, const sc_signed &v); + friend sc_signed operator ^ (uint64 u, const sc_signed &v); + friend sc_signed operator ^ (long u, const sc_signed &v); + friend sc_signed operator ^ (unsigned long u, const sc_signed &v); + friend sc_signed + operator ^ (int u, const sc_signed &v) + { + return operator ^ ((long)u, v); + } + friend sc_signed + operator ^ (unsigned int u, const sc_signed &v) + { + return operator ^ ((unsigned long)u, v); + } + + const sc_signed &operator ^= (const sc_signed &v); + const sc_signed &operator ^= (const sc_unsigned &v); + const sc_signed &operator ^= (int64 v); + const sc_signed &operator ^= (uint64 v); + const sc_signed &operator ^= (long v); + const sc_signed &operator ^= (unsigned long v); + const sc_signed & + operator ^= (int v) + { + return operator ^= ((long)v); + } + const sc_signed & + operator ^= (unsigned int v) + { + return operator ^= ((unsigned long)v); + } + + friend sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v); + friend sc_signed operator ^ (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator ^ (const sc_signed &u, const sc_uint_base &v); + friend sc_signed operator ^ (const sc_int_base &u, const sc_signed &v); + friend sc_signed operator ^ (const sc_uint_base &u, const sc_signed &v); + const sc_signed &operator ^= (const sc_int_base &v); + const sc_signed &operator ^= (const sc_uint_base &v); + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + friend sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator << (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator << (const sc_signed &u, const sc_signed &v); + friend sc_signed operator << (const sc_signed &u, int64 v); + friend sc_signed operator << (const sc_signed &u, uint64 v); + friend sc_signed operator << (const sc_signed &u, long v); + friend sc_signed operator << (const sc_signed &u, unsigned long v); + friend sc_signed + operator << (const sc_signed &u, int v) + { + return operator << (u, (long)v); + } + friend sc_signed + operator << (const sc_signed &u, unsigned int v) + { + return operator << (u, (unsigned long)v); + } + + const sc_signed &operator <<= (const sc_signed &v); + const sc_signed &operator <<= (const sc_unsigned &v); + const sc_signed &operator <<= (int64 v); + const sc_signed &operator <<= (uint64 v); + const sc_signed &operator <<= (long v); + const sc_signed &operator <<= (unsigned long v); + const sc_signed & + operator <<= (int v) + { + return operator <<= ((long)v); + } + const sc_signed & + operator <<= (unsigned int v) + { + return operator <<= ((unsigned long)v); + } + + friend sc_signed operator << (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator << (const sc_signed &u, const sc_uint_base &v); + const sc_signed &operator <<= (const sc_int_base &v); + const sc_signed &operator <<= (const sc_uint_base &v); + + // RIGHT SHIFT operators: + friend sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator >> (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator >> (const sc_signed &u, const sc_signed &v); + friend sc_signed operator >> (const sc_signed &u, int64 v); + friend sc_signed operator >> (const sc_signed &u, uint64 v); + friend sc_signed operator >> (const sc_signed &u, long v); + friend sc_signed operator >> (const sc_signed &u, unsigned long v); + friend sc_signed + operator >> (const sc_signed &u, int v) + { + return operator >> (u, (long)v); + } + friend sc_signed + operator >> (const sc_signed &u, unsigned int v) + { + return operator >> (u, (unsigned long) v); + } + + const sc_signed &operator >>= (const sc_signed &v); + const sc_signed &operator >>= (const sc_unsigned &v); + const sc_signed &operator >>= (int64 v); + const sc_signed &operator >>= (uint64 v); + const sc_signed &operator >>= (long v); + const sc_signed &operator >>= (unsigned long v); + const sc_signed & + operator >>= (int v) + { + return operator >>= ((long)v); + } + const sc_signed & + operator >>= (unsigned int v) + { + return operator >>= ((unsigned long)v); + } + + friend sc_signed operator >> (const sc_signed &u, const sc_int_base &v); + friend sc_signed operator >> (const sc_signed &u, const sc_uint_base &v); + const sc_signed &operator >>= (const sc_int_base &v); + const sc_signed &operator >>= (const sc_uint_base &v); + + // Unary arithmetic operators + friend sc_signed operator + (const sc_signed &u); + friend sc_signed operator - (const sc_signed &u); + friend sc_signed operator - (const sc_unsigned &u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + friend bool operator == (const sc_unsigned &u, const sc_signed &v); + friend bool operator == (const sc_signed &u, const sc_unsigned &v); + + friend bool operator == (const sc_signed &u, const sc_signed &v); + friend bool operator == (const sc_signed &u, int64 v); + friend bool operator == (const sc_signed &u, uint64 v); + friend bool operator == (const sc_signed &u, long v); + friend bool operator == (const sc_signed &u, unsigned long v); + friend bool + operator == (const sc_signed &u, int v) + { + return operator == (u, (long)v); + } + friend bool + operator == (const sc_signed &u, unsigned int v) + { + return operator == (u, (unsigned long)v); + } + + friend bool operator == (int64 u, const sc_signed &v); + friend bool operator == (uint64 u, const sc_signed &v); + friend bool operator == (long u, const sc_signed &v); + friend bool operator == (unsigned long u, const sc_signed &v); + friend bool + operator == (int u, const sc_signed &v) + { + return operator == ((long)u, v); + } + friend bool + operator == (unsigned int u, const sc_signed &v) + { + return operator == ((unsigned long)u, v); + } + + friend bool operator == (const sc_signed &u, const sc_int_base &v); + friend bool operator == (const sc_signed &u, const sc_uint_base &v); + friend bool operator == (const sc_int_base &u, const sc_signed &v); + friend bool operator == (const sc_uint_base &u, const sc_signed &v); + + // Logical NOT_EQUAL operators: + friend bool operator != (const sc_unsigned &u, const sc_signed &v); + friend bool operator != (const sc_signed &u, const sc_unsigned &v); + + friend bool operator != (const sc_signed &u, const sc_signed &v); + friend bool operator != (const sc_signed &u, int64 v); + friend bool operator != (const sc_signed &u, uint64 v); + friend bool operator != (const sc_signed &u, long v); + friend bool operator != (const sc_signed &u, unsigned long v); + friend bool + operator != (const sc_signed &u, int v) + { + return operator != (u, (long)v); + } + friend bool + operator != (const sc_signed &u, unsigned int v) + { + return operator != (u, (unsigned long)v); + } + + friend bool operator != (int64 u, const sc_signed &v); + friend bool operator != (uint64 u, const sc_signed &v); + friend bool operator != (long u, const sc_signed &v); + friend bool operator != (unsigned long u, const sc_signed &v); + friend bool + operator != (int u, const sc_signed &v) + { + return operator != ((long)u, v); + } + friend bool + operator != (unsigned int u, const sc_signed &v) + { + return operator != ((unsigned long)u, v); + } + + friend bool operator != (const sc_signed &u, const sc_int_base &v); + friend bool operator != (const sc_signed &u, const sc_uint_base &v); + friend bool operator != (const sc_int_base &u, const sc_signed &v); + friend bool operator != (const sc_uint_base &u, const sc_signed &v); + + // Logical LESS_THAN operators: + friend bool operator < (const sc_unsigned &u, const sc_signed &v); + friend bool operator < (const sc_signed &u, const sc_unsigned &v); + + friend bool operator < (const sc_signed &u, const sc_signed &v); + friend bool operator < (const sc_signed &u, int64 v); + friend bool operator < (const sc_signed &u, uint64 v); + friend bool operator < (const sc_signed &u, long v); + friend bool operator < (const sc_signed &u, unsigned long v); + friend bool operator < (const sc_signed &u, int v) + { return operator<(u, (long) v); } + friend bool operator < (const sc_signed &u, unsigned int v) + { return operator<(u, (unsigned long) v); } + + friend bool operator < (int64 u, const sc_signed &v); + friend bool operator < (uint64 u, const sc_signed &v); + friend bool operator < (long u, const sc_signed &v); + friend bool operator < (unsigned long u, const sc_signed &v); + friend bool + operator < (int u, const sc_signed &v) + { + return operator < ((long)u, v); + } + friend bool + operator < (unsigned int u, const sc_signed &v) + { + return operator < ((unsigned long)u, v); + } + + friend bool operator < (const sc_signed &u, const sc_int_base &v); + friend bool operator < (const sc_signed &u, const sc_uint_base &v); + friend bool operator < (const sc_int_base &u, const sc_signed &v); + friend bool operator < (const sc_uint_base &u, const sc_signed &v); + + // Logical LESS_THAN_AND_EQUAL operators: + friend bool operator <= (const sc_unsigned &u, const sc_signed &v); + friend bool operator <= (const sc_signed &u, const sc_unsigned &v); + + friend bool operator <= (const sc_signed &u, const sc_signed &v); + friend bool operator <= (const sc_signed &u, int64 v); + friend bool operator <= (const sc_signed &u, uint64 v); + friend bool operator <= (const sc_signed &u, long v); + friend bool operator <= (const sc_signed &u, unsigned long v); + friend bool + operator <= (const sc_signed &u, int v) + { + return operator <= (u, (long)v); + } + friend bool + operator <= (const sc_signed &u, unsigned int v) + { + return operator <= (u, (unsigned long)v); + } + + friend bool operator <= (int64 u, const sc_signed &v); + friend bool operator <= (uint64 u, const sc_signed &v); + friend bool operator <= (long u, const sc_signed &v); + friend bool operator <= (unsigned long u, const sc_signed &v); + friend bool + operator <= (int u, const sc_signed &v) + { + return operator <= ((long)u, v); + } + friend bool + operator <= (unsigned int u, const sc_signed &v) + { + return operator <= ((unsigned long)u, v); + } + + friend bool operator <= (const sc_signed &u, const sc_int_base &v); + friend bool operator <= (const sc_signed &u, const sc_uint_base &v); + friend bool operator <= (const sc_int_base &u, const sc_signed &v); + friend bool operator <= (const sc_uint_base &u, const sc_signed &v); + + // Logical GREATER_THAN operators: + friend bool operator > (const sc_unsigned &u, const sc_signed &v); + friend bool operator > (const sc_signed &u, const sc_unsigned &v); + + friend bool operator > (const sc_signed &u, const sc_signed &v); + friend bool operator > (const sc_signed &u, int64 v); + friend bool operator > (const sc_signed &u, uint64 v); + friend bool operator > (const sc_signed &u, long v); + friend bool operator > (const sc_signed &u, unsigned long v); + friend bool + operator > (const sc_signed &u, int v) + { + return operator > (u, (long)v); + } + friend bool + operator > (const sc_signed &u, unsigned int v) + { + return operator > (u, (unsigned long)v); + } + + friend bool operator > (int64 u, const sc_signed &v); + friend bool operator > (uint64 u, const sc_signed &v); + friend bool operator > (long u, const sc_signed &v); + friend bool operator > (unsigned long u, const sc_signed &v); + friend bool + operator > (int u, const sc_signed &v) + { + return operator > ((long)u, v); + } + friend bool + operator > (unsigned int u, const sc_signed &v) + { + return operator > ((unsigned long)u, v); + } + + friend bool operator > (const sc_signed &u, const sc_int_base &v); + friend bool operator > (const sc_signed &u, const sc_uint_base &v); + friend bool operator > (const sc_int_base &u, const sc_signed &v); + friend bool operator > (const sc_uint_base &u, const sc_signed &v); + + // Logical GREATER_THAN_AND_EQUAL operators: + friend bool operator >= (const sc_unsigned &u, const sc_signed &v); + friend bool operator >= (const sc_signed &u, const sc_unsigned &v); + + friend bool operator >= (const sc_signed &u, const sc_signed &v); + friend bool operator >= (const sc_signed &u, int64 v); + friend bool operator >= (const sc_signed &u, uint64 v); + friend bool operator >= (const sc_signed &u, long v); + friend bool operator >= (const sc_signed &u, unsigned long v); + friend bool + operator >= (const sc_signed &u, int v) + { + return operator >= (u, (long)v); + } + friend bool + operator >= (const sc_signed &u, unsigned int v) + { + return operator >= (u, (unsigned long)v); + } + + friend bool operator >= (int64 u, const sc_signed &v); + friend bool operator >= (uint64 u, const sc_signed &v); + friend bool operator >= (long u, const sc_signed &v); + friend bool operator >= (unsigned long u, const sc_signed &v); + friend bool + operator >= (int u, const sc_signed &v) + { + return operator >= ((long)u, v); + } + friend bool + operator >= (unsigned int u, const sc_signed &v) + { + return operator >= ((unsigned long)u, v); + } + + friend bool operator >= (const sc_signed &u, const sc_int_base &v); + friend bool operator >= (const sc_signed &u, const sc_uint_base &v); + friend bool operator >= (const sc_int_base &u, const sc_signed &v); + friend bool operator >= (const sc_uint_base &u, const sc_signed &v); + + // Bitwise NOT operator (unary). + friend sc_signed operator ~ (const sc_signed &u); + + // Helper functions. + friend sc_signed add_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_signed sub_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_signed mul_signed_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_signed div_signed_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_signed mod_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_signed and_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_signed or_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_signed xor_signed_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + private: + + small_type sgn; // Shortened as s. + int nbits; // Shortened as nb. + int ndigits; // Shortened as nd. + +#ifdef SC_MAX_NBITS + sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d. +#else + sc_digit *digit; // Shortened as d. +#endif + + /* + * Private constructors: + */ + + // Create a copy of v with sign s. + sc_signed(const sc_signed &v, small_type s); + sc_signed(const sc_unsigned &v, small_type s); + + // Create a signed number with the given attributes. + sc_signed(small_type s, int nb, int nd, sc_digit *d, bool alloc=true); + + // Create an unsigned number using the bits u[l..r]. + sc_signed(const sc_signed *u, int l, int r); + sc_signed(const sc_unsigned *u, int l, int r); + + // Private member functions. The called functions are inline functions. + small_type default_sign() const { return SC_NOSIGN; } + int num_bits(int nb) const { return nb; } + + bool check_if_outside(int bit_num) const; + + void + copy_digits(int nb, int nd, const sc_digit *d) + { + copy_digits_signed(sgn, nbits, ndigits, digit, nb, nd, d); + } + + void makezero() { sgn = make_zero(ndigits, digit); } + + // Conversion functions between 2's complement (2C) and + // sign-magnitude (SM): + void + convert_2C_to_SM() + { + sgn = convert_signed_2C_to_SM(nbits, ndigits, digit); + } + + void + convert_SM_to_2C_to_SM() + { + sgn = convert_signed_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); + } + + void + convert_SM_to_2C() + { + convert_signed_SM_to_2C(sgn, ndigits, digit); + } +}; + +inline ::std::ostream &operator << (::std::ostream &, const sc_signed &); + +inline ::std::istream &operator >> (::std::istream &, sc_signed &); + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_signed_bitref_r &a) +{ + a.print(os); + return os; +} + + +inline ::std::istream & +operator >> (::std::istream &is, sc_signed_bitref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref_r +// +// Proxy class for sc_signed part selection (r-value only). +// ---------------------------------------------------------------------------- + + +// reduce methods + +inline bool +sc_signed_subref_r::and_reduce() const +{ + const sc_signed *target_p = m_obj_p; + for (int i = m_right; i <= m_left; i++) + if (!target_p->test(i)) + return false; + return true; +} + +inline bool +sc_signed_subref_r::nand_reduce() const +{ + return !and_reduce(); +} + +inline bool +sc_signed_subref_r::or_reduce() const +{ + const sc_signed *target_p = m_obj_p; + for (int i = m_right; i <= m_left; i++) + if (target_p->test(i)) + return true; + return false; +} + +inline bool +sc_signed_subref_r::nor_reduce() const +{ + return !or_reduce(); +} + +inline bool +sc_signed_subref_r::xor_reduce() const +{ + int odd; + const sc_signed *target_p = m_obj_p; + odd = 0; + for (int i = m_right; i <= m_left; i++) + if (target_p->test(i)) odd = ~odd; + return odd ? true : false; +} + +inline bool +sc_signed_subref_r::xnor_reduce() const +{ + return !xor_reduce(); +} + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_signed_subref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed_subref +// +// Proxy class for sc_signed part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline const sc_signed_subref & +sc_signed_subref::operator = (const char *a) +{ + sc_signed aa(length()); + return (*this = aa = a); +} + + + + +inline ::std::istream & +operator >> (::std::istream &is, sc_signed_subref &a) +{ + a.scan(is); + return is; +} + + + +// ---------------------------------------------------------------------------- +// CLASS : sc_signed +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +template<class T> +sc_signed::sc_signed(const sc_generic_base<T> &v) +{ + int nb = v->length(); + sgn = default_sign(); + if (nb > 0) { + nbits = num_bits(nb); + } else { + invalid_init("sc_generic_base<T>", nb); + sc_core::sc_abort(); // can't recover from here + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + v->to_sc_signed(*this); +} + + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_signed &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_signed &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_SIGNED_HH__ diff --git a/src/systemc/ext/dt/int/sc_uint.hh b/src/systemc/ext/dt/int/sc_uint.hh new file mode 100644 index 000000000..7f4a6cf2e --- /dev/null +++ b/src/systemc/ext/dt/int/sc_uint.hh @@ -0,0 +1,382 @@ +/***************************************************************************** + + 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_uint.h -- An unsigned integer whose length is less than 64 bits. + + Unlike arbitrary precision, arithmetic and bitwise operations + are performed using the native types (hence capped at 64 bits). + The sc_uint integer is useful when the user does not need + arbitrary precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_uint.h,v $ +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_UINT_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_UINT_HH__ + +#include "sc_uint_base.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_uint; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_uint<W> +// +// Template class sc_uint<W> is the interface that the user sees. It +// is derived from sc_uint_base and most of its methods are just +// wrappers that call the corresponding method in the parent +// class. Note that the length of sc_uint datatype is specified as a +// template parameter. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_uint : public sc_uint_base +{ + public: + // constructors + sc_uint() : sc_uint_base(W) {} + sc_uint(uint_type v) : sc_uint_base(v, W) {} + sc_uint(const sc_uint<W> &a) : sc_uint_base(a) {} + sc_uint(const sc_uint_base &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const sc_uint_subref_r &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + template< class T > + sc_uint(const sc_generic_base<T> &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const sc_signed &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const sc_unsigned &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + explicit sc_uint(const sc_fxval &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + explicit sc_uint(const sc_fxval_fast &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + explicit sc_uint(const sc_fxnum &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + explicit sc_uint(const sc_fxnum_fast &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const sc_bv_base &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const sc_lv_base &a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(const char* a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(unsigned long a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(long a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(unsigned int a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(int a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(int64 a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + sc_uint(double a) : sc_uint_base(W) + { + sc_uint_base::operator = (a); + } + + // assignment operators + sc_uint<W> & + operator = (uint_type v) + { + sc_uint_base::operator = (v); + return *this; + } + sc_uint<W> & + operator = (const sc_uint_base &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_uint_subref_r &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_uint<W> &a) + { + m_val = a.m_val; + return *this; + } + template<class T> + sc_uint<W> & + operator = (const sc_generic_base<T> &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_signed &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_unsigned &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_fxval &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_fxval_fast &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_fxnum &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_fxnum_fast &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_bv_base &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const sc_lv_base &a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (const char* a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (unsigned long a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (long a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (unsigned int a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (int a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (int64 a) + { + sc_uint_base::operator = (a); + return *this; + } + sc_uint<W> & + operator = (double a) + { + sc_uint_base::operator = (a); + return *this; + } + + // arithmetic assignment operators + sc_uint<W> & + operator += (uint_type v) + { + sc_uint_base::operator += (v); + return *this; + } + sc_uint<W> & + operator -= (uint_type v) + { + sc_uint_base::operator -= (v); + return *this; + } + sc_uint<W> & + operator *= (uint_type v) + { + sc_uint_base::operator *= (v); + return *this; + } + sc_uint<W> & + operator /= (uint_type v) + { + sc_uint_base::operator /= (v); + return *this; + } + sc_uint<W> & + operator %= (uint_type v) + { + sc_uint_base::operator %= (v); + return *this; + } + + // bitwise assignment operators + sc_uint<W> & + operator &= (uint_type v) + { + sc_uint_base::operator &= (v); + return *this; + } + sc_uint<W> & + operator |= (uint_type v) + { + sc_uint_base::operator |= (v); + return *this; + } + sc_uint<W> & + operator ^= (uint_type v) + { + sc_uint_base::operator ^= (v); + return *this; + } + + sc_uint<W> & + operator <<= (uint_type v) + { + sc_uint_base::operator <<= (v); + return *this; + } + sc_uint<W> & + operator >>= (uint_type v) + { + sc_uint_base::operator >>= (v); + return *this; + } + + // prefix and postfix increment and decrement operators + sc_uint<W> & + operator ++ () // prefix + { + sc_uint_base::operator ++ (); + return *this; + } + const sc_uint<W> + operator ++ ( int ) // postfix + { + return sc_uint<W>(sc_uint_base::operator ++ (0)); + } + sc_uint<W> & + operator -- () // prefix + { + sc_uint_base::operator -- (); + return *this; + } + const sc_uint<W> + operator -- (int) // postfix + { + return sc_uint<W>(sc_uint_base::operator -- (0)); + } +}; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_UINT_HH__ diff --git a/src/systemc/ext/dt/int/sc_uint_base.hh b/src/systemc/ext/dt/int/sc_uint_base.hh new file mode 100644 index 000000000..28a2e8d85 --- /dev/null +++ b/src/systemc/ext/dt/int/sc_uint_base.hh @@ -0,0 +1,1258 @@ +/***************************************************************************** + + 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_uint_base.h -- An unsigned integer whose length is less than 64 bits. + + Unlike arbitrary precision, arithmetic and bitwise operations + are performed using the native types (hence capped at 64 bits). + The sc_uint integer is useful when the user does not need + arbitrary precision and the performance is superior to + sc_bigint/sc_biguint. + + Original Author: Amit Rao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc. + Description of Modification: - Resolved ambiguity with sc_(un)signed. + - Merged the code for 64- and 32-bit versions + via the constants in sc_nbdefs.h. + - Eliminated redundant file inclusions. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_uint_base.h,v $ +// Revision 1.3 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:02 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ + +#include <iostream> + +#include "../fx/scfx_ieee.hh" +#include "../misc/sc_value_base.hh" +#include "../sc_temporary.hh" +#include "sc_length_param.hh" +#include "sc_nbdefs.hh" + +namespace sc_dt +{ + +class sc_concatref; + +// classes defined in this module +class sc_uint_bitref_r; +class sc_uint_bitref; +class sc_uint_subref_r; +class sc_uint_subref; +class sc_uint_base; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_subref_r; +class sc_signed_subref_r; +class sc_unsigned_subref_r; +class sc_signed; +class sc_unsigned; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + +} // namespace sc_dt + +// extern template instantiations +namespace sc_core +{ + +extern template class sc_vpool<sc_dt::sc_uint_bitref>; +extern template class sc_vpool<sc_dt::sc_uint_subref>; + +} // namespace sc_core + +namespace sc_dt +{ + +extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]; + +// friend operator declarations +inline bool operator == (const sc_uint_base &a, const sc_uint_base &b); +inline bool operator != (const sc_uint_base &a, const sc_uint_base &b); +inline bool operator < (const sc_uint_base &a, const sc_uint_base &b); +inline bool operator <= (const sc_uint_base &a, const sc_uint_base &b); +inline bool operator > (const sc_uint_base &a, const sc_uint_base &b); +inline bool operator >= (const sc_uint_base &a, const sc_uint_base &b); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref_r +// +// Proxy class for sc_uint bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_uint_bitref_r : public sc_value_base +{ + friend class sc_uint_base; + friend class sc_uint_signal; + + // constructors + public: + sc_uint_bitref_r(const sc_uint_bitref_r &init) : + sc_value_base(init), m_index(init.m_index), m_obj_p(init.m_obj_p) + {} + + protected: + sc_uint_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {} + + // initializer for sc_core::sc_vpool: + void + initialize(const sc_uint_base* obj_p, int index_) + { + m_obj_p = (sc_uint_base *)obj_p; + m_index = index_; + } + + public: + // destructor + virtual ~sc_uint_bitref_r() {} + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return 1; + } + virtual bool + concat_get_ctrl(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool + concat_get_data(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True is non-zero. + int word_i = low_i / BITS_PER_DIGIT; + + if (operator uint64()) { + dst_p[word_i] |= bit_mask; + result = true; + } else { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + virtual uint64 concat_get_uint64() const { return operator uint64(); } + + // capacity + int length() const { return 1; } + + // implicit conversion to uint64 + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + // explicit conversions + uint64 value() const { return operator uint64 (); } + bool to_bool() const { return operator uint64 (); } + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_bool(); } + + protected: + int m_index; + sc_uint_base *m_obj_p; + + private: + // Disabled + sc_uint_bitref_r &operator = (const sc_uint_bitref_r &); +}; + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_uint_bitref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref +// +// Proxy class for sc_uint bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_uint_bitref : public sc_uint_bitref_r +{ + friend class sc_uint_base; + friend class sc_core::sc_vpool<sc_uint_bitref>; + + // constructors + protected: + sc_uint_bitref() : sc_uint_bitref_r() {} + + public: + sc_uint_bitref(const sc_uint_bitref &init) : sc_uint_bitref_r(init) {} + + public: + // assignment operators + sc_uint_bitref &operator = (const sc_uint_bitref_r &b); + sc_uint_bitref &operator = (const sc_uint_bitref &b); + sc_uint_bitref &operator = (bool b); + + sc_uint_bitref &operator &= (bool b); + sc_uint_bitref &operator |= (bool b); + sc_uint_bitref &operator ^= (bool b); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_uint_bitref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_uint_bitref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref_r +// +// Proxy class for sc_uint part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_uint_subref_r : public sc_value_base +{ + friend class sc_uint_base; + friend class sc_uint_subref; + + // constructors + public: + sc_uint_subref_r( const sc_uint_subref_r& init ) : + sc_value_base(init), m_left(init.m_left), m_obj_p(init.m_obj_p), + m_right(init.m_right) + {} + + protected: + sc_uint_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {} + + // initializer for sc_core::sc_vpool: + void + initialize(const sc_uint_base *obj_p, int left_i, int right_i) + { + m_obj_p = (sc_uint_base *)obj_p; + m_left = left_i; + m_right = right_i; + } + + public: + // destructor + virtual ~sc_uint_subref_r() {} + + // capacity + int length() const { return (m_left - m_right + 1); } + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return length(); + } + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; + virtual uint64 + concat_get_uint64() const + { + return (uint64)operator uint_type(); + } + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return !or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return !xor_reduce(); } + + // implicit conversion to uint_type + operator uint_type() const; + + // explicit conversions + uint_type value() const { return operator uint_type(); } + + 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; + double to_double() const; + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + protected: + int m_left; + sc_uint_base *m_obj_p; + int m_right; + + private: + // Disabled + sc_uint_subref_r &operator = (const sc_uint_subref_r &); +}; + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_uint_subref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref +// +// Proxy class for sc_uint part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_uint_subref : public sc_uint_subref_r +{ + friend class sc_uint_base; + friend class sc_core::sc_vpool<sc_uint_subref>; + + // constructors + protected: + sc_uint_subref() : sc_uint_subref_r() {} + + public: + sc_uint_subref(const sc_uint_subref &init) : sc_uint_subref_r(init) {} + + public: + // assignment operators + sc_uint_subref &operator = (uint_type v); + sc_uint_subref &operator = (const sc_uint_base &a); + sc_uint_subref & + operator = (const sc_uint_subref_r &a) + { + return operator = (a.operator uint_type()); + } + sc_uint_subref & + operator = (const sc_uint_subref &a) + { + return operator = (a.operator uint_type()); + } + template<class T> + sc_uint_subref & + operator = (const sc_generic_base<T> &a) + { + return operator = (a->to_uint64()); + } + sc_uint_subref &operator = (const char *a); + sc_uint_subref & + operator = (unsigned long a) + { + return operator = ((uint_type)a); + } + sc_uint_subref & + operator = (long a) + { + return operator = ((uint_type)a); + } + sc_uint_subref & + operator = (unsigned int a) + { + return operator = ((uint_type)a); + } + sc_uint_subref & + operator = (int a) + { + return operator = ((uint_type)a); + } + sc_uint_subref & + operator = (int64 a) + { + return operator = ((uint_type)a); + } + sc_uint_subref & + operator = (double a) + { + return operator = ((uint_type)a); + } + sc_uint_subref &operator = (const sc_signed &); + sc_uint_subref &operator = (const sc_unsigned &); + sc_uint_subref &operator = (const sc_bv_base &); + sc_uint_subref &operator = (const sc_lv_base &); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_uint_subref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_uint_subref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// +// Base class for sc_uint. +// ---------------------------------------------------------------------------- + +class sc_uint_base : public sc_value_base +{ + friend class sc_uint_bitref_r; + friend class sc_uint_bitref; + friend class sc_uint_subref_r; + friend class sc_uint_subref; + + // support methods + void invalid_length() const; + void invalid_index(int i) const; + void invalid_range(int l, int r) const; + + void + check_length() const + { + if (m_len <= 0 || m_len > SC_INTWIDTH) { + invalid_length(); + } + } + + void + check_index(int i) const + { + if (i < 0 || i >= m_len) { + invalid_index( i ); + } + } + + void + check_range(int l, int r) const + { + if (r < 0 || l >= m_len || l < r) { + invalid_range( l, r ); + } + } + + void check_value() const; + + void + extend_sign() + { +#ifdef DEBUG_SYSTEMC + check_value(); +#endif + m_val &= (~UINT_ZERO >> m_ulen); + } + + public: + // constructors + explicit sc_uint_base(int w=sc_length_param().len()) : + m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + } + + sc_uint_base(uint_type v, int w) : + m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + extend_sign(); + } + + sc_uint_base(const sc_uint_base &a) : + sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen) + {} + + explicit sc_uint_base(const sc_uint_subref_r &a) : + m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len) + { + extend_sign(); + } + + template<class T> + explicit sc_uint_base(const sc_generic_base<T> &a) : + m_val(a->to_uint64()), m_len(a->length()), + m_ulen(SC_INTWIDTH - m_len) + { + check_length(); + extend_sign(); + } + + explicit sc_uint_base(const sc_bv_base &v); + explicit sc_uint_base(const sc_lv_base &v); + explicit sc_uint_base(const sc_int_subref_r &v); + explicit sc_uint_base(const sc_signed_subref_r &v); + explicit sc_uint_base(const sc_unsigned_subref_r &v); + explicit sc_uint_base(const sc_signed &a); + explicit sc_uint_base(const sc_unsigned &a); + + // destructor + virtual ~sc_uint_base() {} + + // assignment operators + sc_uint_base & + operator = (uint_type v) + { + m_val = v; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (const sc_uint_base &a) + { + m_val = a.m_val; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (const sc_uint_subref_r &a) + { + m_val = a; + extend_sign(); + return *this; + } + template<class T> + sc_uint_base & + operator = (const sc_generic_base<T> &a) + { + m_val = a->to_uint64(); + extend_sign(); + return *this; + } + sc_uint_base &operator = (const sc_signed &a); + sc_uint_base &operator = (const sc_unsigned &a); + sc_uint_base &operator = (const sc_fxval &a); + sc_uint_base &operator = (const sc_fxval_fast &a); + sc_uint_base &operator = (const sc_fxnum &a); + sc_uint_base &operator = (const sc_fxnum_fast &a); + sc_uint_base &operator = (const sc_bv_base &a); + sc_uint_base &operator = (const sc_lv_base &a); + sc_uint_base &operator = (const char *a); + sc_uint_base & + operator = (unsigned long a) + { + m_val = a; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (long a) + { + m_val = a; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (unsigned int a) + { + m_val = a; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (int a) + { + m_val = a; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (int64 a) + { + m_val = a; + extend_sign(); + return *this; + } + sc_uint_base & + operator = (double a) + { + m_val = (uint_type)a; + extend_sign(); + return *this; + } + + // arithmetic assignment operators + sc_uint_base & + operator += (uint_type v) + { + m_val += v; + extend_sign(); + return *this; + } + sc_uint_base & + operator -= (uint_type v) + { + m_val -= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator *= (uint_type v) + { + m_val *= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator /= (uint_type v) + { + m_val /= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator %= (uint_type v) + { + m_val %= v; + extend_sign(); + return *this; + } + + // bitwise assignment operators + sc_uint_base & + operator &= (uint_type v) + { + m_val &= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator |= (uint_type v) + { + m_val |= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator ^= (uint_type v) + { + m_val ^= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator <<= (uint_type v) + { + m_val <<= v; + extend_sign(); + return *this; + } + sc_uint_base & + operator >>= (uint_type v) + { + m_val >>= v; + /* no sign extension needed */ + return *this; + } + + // prefix and postfix increment and decrement operators + sc_uint_base & + operator ++ () // prefix + { + ++m_val; + extend_sign(); + return *this; + } + const sc_uint_base + operator ++ (int) // postfix + { + sc_uint_base tmp(*this); + ++m_val; + extend_sign(); + return tmp; + } + + sc_uint_base & + operator -- () // prefix + { + --m_val; + extend_sign(); + return *this; + } + const sc_uint_base + operator -- (int) // postfix + { + sc_uint_base tmp(*this); + --m_val; + extend_sign(); + return tmp; + } + + // relational operators + friend bool + operator == (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val == b.m_val; + } + friend bool + operator != (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val != b.m_val; + } + friend bool + operator < (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val < b.m_val; + } + friend bool + operator <= (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val <= b.m_val; + } + friend bool + operator > (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val > b.m_val; + } + friend bool + operator >= (const sc_uint_base &a, const sc_uint_base &b) + { + return a.m_val >= b.m_val; + } + + // bit selection + sc_uint_bitref &operator [] (int i); + const sc_uint_bitref_r &operator [] (int i) const; + + sc_uint_bitref &bit(int i); + const sc_uint_bitref_r &bit(int i) const; + + // part selection + sc_uint_subref &operator () (int left, int right); + const sc_uint_subref_r &operator () (int left, int right) const; + + sc_uint_subref &range(int left, int right); + const sc_uint_subref_r &range(int left, int right) const; + + // bit access, without bounds checking or sign extension + bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); } + + void set(int i) { m_val |= (UINT_ONE << i); } + void + set(int i, bool v) + { + v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i); + } + + // capacity + int length() const { return m_len; } + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return length(); + } + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data( sc_digit *dst_p, int low_i) const; + virtual uint64 concat_get_uint64() const { return m_val; } + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return !or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return !xor_reduce(); } + + // implicit conversion to uint_type + operator uint_type() const { return m_val; } + + // explicit conversions + uint_type value() const { return operator uint_type(); } + + int to_int() const { return (int) m_val; } + unsigned int to_uint() const { return (unsigned int)m_val; } + long to_long() const { return (long)m_val; } + unsigned long to_ulong() const { return (unsigned long)m_val; } + int64 to_int64() const { return (int64)m_val; } + uint64 to_uint64() const { return (uint64)m_val; } + double to_double() const { return uint64_to_double(m_val); } + + long long_low() const { return (long)(m_val & UINT64_32ONES); } + long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); } + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + void scan(::std::istream &is=::std::cin); + + protected: + uint_type m_val; // value + int m_len; // length + int m_ulen; // unused length +}; + +inline ::std::ostream &operator << (::std::ostream &, const sc_uint_base &); +inline ::std::istream &operator >> (::std::istream &, sc_uint_base &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref_r +// +// Proxy class for sc_uint bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to bool + +inline sc_uint_bitref_r::operator uint64 () const +{ + return m_obj_p->test(m_index); +} + +inline bool +sc_uint_bitref_r::operator ! () const +{ + return !m_obj_p->test(m_index); +} + +inline bool +sc_uint_bitref_r::operator ~ () const +{ + return !m_obj_p->test(m_index); +} + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_uint_bitref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_bitref +// +// Proxy class for sc_uint bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline sc_uint_bitref & +sc_uint_bitref::operator = (const sc_uint_bitref_r &b) +{ + m_obj_p->set(m_index, b.to_bool()); + return *this; +} + +inline sc_uint_bitref & +sc_uint_bitref::operator = (const sc_uint_bitref &b) +{ + m_obj_p->set(m_index, b.to_bool()); + return *this; +} + +inline sc_uint_bitref & +sc_uint_bitref::operator = (bool b) +{ + m_obj_p->set(m_index, b); + return *this; +} + +inline sc_uint_bitref & +sc_uint_bitref::operator &= (bool b) +{ + if (!b) { + m_obj_p->set(m_index, b); + } + return *this; +} + +inline sc_uint_bitref & +sc_uint_bitref::operator |= (bool b) +{ + if (b) { + m_obj_p->set(m_index, b); + } + return *this; +} + +inline sc_uint_bitref & +sc_uint_bitref::operator ^= (bool b) +{ + if (b) { + m_obj_p->m_val ^= (UINT_ONE << m_index); + } + return *this; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_uint_bitref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref_r +// +// Proxy class for sc_uint part selection (r-value only). +// ---------------------------------------------------------------------------- + +// implicit conversion to uint_type + +inline sc_uint_subref_r::operator uint_type() const +{ + uint_type val = m_obj_p->m_val; + int uleft = SC_INTWIDTH - (m_left + 1); + return ((val & (~UINT_ZERO >> uleft)) >> m_right); +} + + +// reduce methods +inline bool +sc_uint_subref_r::and_reduce() const +{ + sc_uint_base a(*this); + return a.and_reduce(); +} +inline bool +sc_uint_subref_r::or_reduce() const +{ + sc_uint_base a(*this); + return a.or_reduce(); +} +inline bool +sc_uint_subref_r::xor_reduce() const +{ + sc_uint_base a(*this); + return a.xor_reduce(); +} + +// explicit conversions +inline int +sc_uint_subref_r::to_int() const +{ + sc_uint_base a(*this); + return a.to_int(); +} +inline unsigned int +sc_uint_subref_r::to_uint() const +{ + sc_uint_base a(*this); + return a.to_uint(); +} +inline long +sc_uint_subref_r::to_long() const +{ + sc_uint_base a(*this); + return a.to_long(); +} +inline unsigned long +sc_uint_subref_r::to_ulong() const +{ + sc_uint_base a(*this); + return a.to_ulong(); +} +inline int64 +sc_uint_subref_r::to_int64() const +{ + sc_uint_base a(*this); + return a.to_int64(); +} +inline uint64 +sc_uint_subref_r::to_uint64() const +{ + sc_uint_base a(*this); + return a.to_uint64(); +} +inline double +sc_uint_subref_r::to_double() const +{ + sc_uint_base a(*this); + return a.to_double(); +} + +// explicit conversion to character string +inline const std::string +sc_uint_subref_r::to_string(sc_numrep numrep) const +{ + sc_uint_base a(*this); + return a.to_string(numrep); +} + +inline const std::string +sc_uint_subref_r::to_string(sc_numrep numrep, bool w_prefix) const +{ + sc_uint_base a(*this); + return a.to_string(numrep, w_prefix); +} + +// functional notation for the reduce methods +inline bool +and_reduce(const sc_uint_subref_r &a) +{ + return a.and_reduce(); +} +inline bool +nand_reduce(const sc_uint_subref_r &a) +{ + return a.nand_reduce(); +} +inline bool +or_reduce(const sc_uint_subref_r &a) +{ + return a.or_reduce(); +} +inline bool +nor_reduce(const sc_uint_subref_r &a) +{ + return a.nor_reduce(); +} +inline bool +xor_reduce(const sc_uint_subref_r &a) +{ + return a.xor_reduce(); +} +inline bool +xnor_reduce(const sc_uint_subref_r &a) +{ + return a.xnor_reduce(); +} + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_uint_subref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_subref +// +// Proxy class for sc_uint part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline sc_uint_subref & +sc_uint_subref::operator = (const sc_uint_base &a) +{ + return operator = (a.operator uint_type()); +} + +inline sc_uint_subref & +sc_uint_subref::operator = (const char *a) +{ + sc_uint_base aa(length()); + return (*this = aa = a); +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_uint_subref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_uint_base +// +// Base class for sc_uint. +// ---------------------------------------------------------------------------- + +// bit selection +inline sc_uint_bitref & +sc_uint_base::operator [] (int i) +{ + check_index(i); + sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline const sc_uint_bitref_r & +sc_uint_base::operator [] (int i) const +{ + check_index(i); + sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline sc_uint_bitref & +sc_uint_base::bit(int i) +{ + check_index(i); + sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +inline const sc_uint_bitref_r & +sc_uint_base::bit(int i) const +{ + check_index(i); + sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; +} + +// part selection +inline sc_uint_subref & +sc_uint_base::operator () (int left, int right) +{ + check_range(left, right); + sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline const sc_uint_subref_r & +sc_uint_base::operator () (int left, int right) const +{ + check_range(left, right); + sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline sc_uint_subref & +sc_uint_base::range(int left, int right) +{ + check_range(left, right); + sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +inline const sc_uint_subref_r & +sc_uint_base::range(int left, int right) const +{ + check_range(left, right); + sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate(); + result_p->initialize(this, left, right); + return *result_p; +} + +// functional notation for the reduce methods +inline bool +and_reduce(const sc_uint_base &a) +{ + return a.and_reduce(); +} +inline bool +nand_reduce(const sc_uint_base &a) +{ + return a.nand_reduce(); +} +inline bool +or_reduce(const sc_uint_base &a) +{ + return a.or_reduce(); +} +inline bool +nor_reduce(const sc_uint_base &a) +{ + return a.nor_reduce(); +} +inline bool +xor_reduce(const sc_uint_base &a) +{ + return a.xor_reduce(); +} +inline bool +xnor_reduce(const sc_uint_base &a) +{ + return a.xnor_reduce(); +} + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_uint_base &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_uint_base &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__ diff --git a/src/systemc/ext/dt/int/sc_unsigned.hh b/src/systemc/ext/dt/int/sc_unsigned.hh new file mode 100644 index 000000000..8927c12cb --- /dev/null +++ b/src/systemc/ext/dt/int/sc_unsigned.hh @@ -0,0 +1,2195 @@ +/***************************************************************************** + + 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_unsigned.h -- Arbitrary precision unsigned arithmetic. + + This file includes the definitions of sc_unsigned_bitref, + sc_unsigned_subref, and sc_unsigned classes. The first two classes + are proxy classes to reference one bit and a range of bits of a + sc_unsigned number, respectively. + + An sc_signed number has the sign-magnitude representation + internally. However, its interface guarantees a 2's-complement + representation. The sign-magnitude representation is chosen + because of its efficiency: The sc_signed and sc_unsigned types are + optimized for arithmetic rather than bitwise operations. For + arithmetic operations, the sign-magnitude representation performs + better. + + It is also important to note that an sc_unsigned number with n + bits is equivalent to an sc_signed non-negative number with n + 1 + bits. + + The implementations of sc_signed and sc_unsigned classes are + almost identical: Most of the member and friend functions are + defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can + be shared by both of these classes. These functions are chosed by + defining a few macros before including them such as IF_SC_SIGNED + and CLASS_TYPE. Our implementation choices are mostly dictated by + performance considerations in that we tried to provide the most + efficient sc_signed and sc_unsigned types without compromising + their interface. + + For the behavior of operators, we have two semantics: the old and + new. The most important difference between these two semantics is + that the old semantics is closer to C/C++ semantics in that the + result type of a binary operator on unsigned and signed arguments + is unsigned; the new semantics, on the other hand, requires the + result type be signed. The new semantics is required by the VSIA + C/C++ data types standard. We have implemented the new semantics. + + Original Author: Ali Dasdan, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_unsigned.h,v $ +// Revision 1.4 2011/08/24 22:05:46 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/02/18 20:19:15 acg +// Andy Goodrich: updating Copyright notice. +// +// Revision 1.2 2009/02/28 00:26:26 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.1.1.1 2006/12/15 20:20:05 acg +// SystemC 2.3 +// +// Revision 1.5 2006/05/08 17:50:02 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.4 2006/03/13 20:25:27 acg +// Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend() +// to keep gcc 4.x happy. +// +// Revision 1.3 2006/01/13 18:49:32 acg +// Added $Log command so that CVS check in comments are reproduced in the +// source. +// + +#ifndef __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__ +#define __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__ + +#include <iostream> + +#include "../misc/sc_value_base.hh" +#include "../sc_temporary.hh" +#include "sc_length_param.hh" +#include "sc_nbdefs.hh" +#include "sc_nbexterns.hh" +#include "sc_nbutils.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_unsigned_bitref_r; +class sc_unsigned_bitref; +class sc_unsigned_subref_r; +class sc_unsigned_subref; +class sc_concatref; +class sc_unsigned; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +class sc_int_base; +class sc_uint_base; +class sc_int_subref_r; +class sc_uint_subref_r; +class sc_signed; +class sc_signed_subref_r; +class sc_fxval; +class sc_fxval_fast; +class sc_fxnum; +class sc_fxnum_fast; + +} // namespace sc_dt + +// extern template instantiations +namespace sc_core +{ + +extern template class sc_vpool<sc_dt::sc_unsigned_bitref>; +extern template class sc_vpool<sc_dt::sc_unsigned_subref>; +extern template class sc_vpool<sc_dt::sc_unsigned>; + +} // namespace sc_core + +namespace sc_dt +{ + +// Helper function declarions +int compare_unsigned(small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd, + small_type if_u_signed=0, small_type if_v_signed=0); + +sc_unsigned add_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_unsigned sub_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_unsigned mul_unsigned_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_unsigned div_unsigned_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_unsigned mod_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + +sc_unsigned and_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + +sc_unsigned or_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + +sc_unsigned xor_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + +/* + * friend operator declarations + */ + +// ARITHMETIC OPERATORS: + +// ADDition operators: +sc_signed operator + (const sc_unsigned &u, const sc_signed &v); +sc_signed operator + (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator + (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator + (const sc_unsigned &u, int64 v); +sc_unsigned operator + (const sc_unsigned &u, uint64 v); +sc_signed operator + (const sc_unsigned &u, long v); +sc_unsigned operator + (const sc_unsigned &u, unsigned long v); +sc_signed operator + (const sc_unsigned &u, int v); +inline sc_unsigned operator + (const sc_unsigned &u, unsigned int v); + +sc_signed operator + (int64 u, const sc_unsigned &v); +sc_unsigned operator + (uint64 u, const sc_unsigned &v); +sc_signed operator + (long u, const sc_unsigned &v); +sc_unsigned operator + (unsigned long u, const sc_unsigned &v); +sc_signed operator + (int u, const sc_unsigned &v); +inline sc_unsigned operator + (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator + (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator + (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator + (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator + (const sc_int_base &u, const sc_unsigned &v); + +// SUBtraction operators: +sc_signed operator - (const sc_unsigned &u, const sc_signed &v); +sc_signed operator - (const sc_signed &u, const sc_unsigned &v); + +sc_signed operator - (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator - (const sc_unsigned &u, int64 v); +sc_signed operator - (const sc_unsigned &u, uint64 v); +sc_signed operator - (const sc_unsigned &u, long v); +sc_signed operator - (const sc_unsigned &u, unsigned long v); +sc_signed operator - (const sc_unsigned &u, int v); +sc_signed operator - (const sc_unsigned &u, unsigned int v); + +sc_signed operator - (int64 u, const sc_unsigned &v); +sc_signed operator - (uint64 u, const sc_unsigned &v); +sc_signed operator - (long u, const sc_unsigned &v); +sc_signed operator - (unsigned long u, const sc_unsigned &v); +sc_signed operator - (int u, const sc_unsigned &v); +sc_signed operator - (unsigned int u, const sc_unsigned &v); + +sc_signed operator - (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator - (const sc_unsigned &u, const sc_int_base &v); +sc_signed operator - (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator - (const sc_int_base &u, const sc_unsigned &v); + +// MULtiplication operators: +sc_signed operator * (const sc_unsigned &u, const sc_signed &v); +sc_signed operator * (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator * (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator * (const sc_unsigned &u, int64 v); +sc_unsigned operator * (const sc_unsigned &u, uint64 v); +sc_signed operator * (const sc_unsigned &u, long v); +sc_unsigned operator * (const sc_unsigned &u, unsigned long v); +sc_signed operator * (const sc_unsigned &u, int v); +inline sc_unsigned operator * (const sc_unsigned &u, unsigned int v); + +sc_signed operator * (int64 u, const sc_unsigned &v); +sc_unsigned operator * (uint64 u, const sc_unsigned &v); +sc_signed operator * (long u, const sc_unsigned &v); +sc_unsigned operator * (unsigned long u, const sc_unsigned &v); +sc_signed operator * (int u, const sc_unsigned &v); +inline sc_unsigned operator * (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator * (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator * (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator * (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator * (const sc_int_base &u, const sc_unsigned &v); + +// DIVision operators: +sc_signed operator / (const sc_unsigned &u, const sc_signed &v); +sc_signed operator / (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator / (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator / (const sc_unsigned &u, int64 v); +sc_unsigned operator / (const sc_unsigned &u, uint64 v); +sc_signed operator / (const sc_unsigned &u, long v); +sc_unsigned operator / (const sc_unsigned &u, unsigned long v); +sc_signed operator / (const sc_unsigned &u, int v); +inline sc_unsigned operator / (const sc_unsigned &u, unsigned int v); + +sc_signed operator / (int64 u, const sc_unsigned &v); +sc_unsigned operator / (uint64 u, const sc_unsigned &v); +sc_signed operator / (long u, const sc_unsigned &v); +sc_unsigned operator / (unsigned long u, const sc_unsigned &v); +sc_signed operator / (int u, const sc_unsigned &v); +inline sc_unsigned operator / (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator / (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator / (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator / (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator / (const sc_int_base &u, const sc_unsigned &v); + +// MODulo operators: +sc_signed operator % (const sc_unsigned &u, const sc_signed &v); +sc_signed operator % (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator % (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator % (const sc_unsigned &u, int64 v); +sc_unsigned operator % (const sc_unsigned &u, uint64 v); +sc_signed operator % (const sc_unsigned &u, long v); +sc_unsigned operator % (const sc_unsigned &u, unsigned long v); +sc_signed operator % (const sc_unsigned &u, int v); +inline sc_unsigned operator % (const sc_unsigned &u, unsigned int v); + +sc_signed operator % (int64 u, const sc_unsigned &v); +sc_unsigned operator % (uint64 u, const sc_unsigned &v); +sc_signed operator % (long u, const sc_unsigned &v); +sc_unsigned operator % (unsigned long u, const sc_unsigned &v); +sc_signed operator % (int u, const sc_unsigned &v); +inline sc_unsigned operator % (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator % (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator % (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator % (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator % (const sc_int_base &u, const sc_unsigned &v); + +// BITWISE OPERATORS: + +// Bitwise AND operators: +sc_signed operator & (const sc_unsigned &u, const sc_signed &v); +sc_signed operator & (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator & (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator & (const sc_unsigned &u, int64 v); +sc_unsigned operator & (const sc_unsigned &u, uint64 v); +sc_signed operator & (const sc_unsigned &u, long v); +sc_unsigned operator & (const sc_unsigned &u, unsigned long v); +sc_signed operator & (const sc_unsigned &u, int v); +inline sc_unsigned operator & (const sc_unsigned &u, unsigned int v); + +sc_signed operator & (int64 u, const sc_unsigned &v); +sc_unsigned operator & (uint64 u, const sc_unsigned &v); +sc_signed operator & (long u, const sc_unsigned &v); +sc_unsigned operator & (unsigned long u, const sc_unsigned &v); +sc_signed operator & (int u, const sc_unsigned &v); +inline sc_unsigned operator & (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator & (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator & (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator & (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator & (const sc_int_base &u, const sc_unsigned &v); + +// Bitwise OR operators: +sc_signed operator | (const sc_unsigned &u, const sc_signed &v); +sc_signed operator | (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator | (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator | (const sc_unsigned &u, int64 v); +sc_unsigned operator | (const sc_unsigned &u, uint64 v); +sc_signed operator | (const sc_unsigned &u, long v); +sc_unsigned operator | (const sc_unsigned &u, unsigned long v); +sc_signed operator | (const sc_unsigned &u, int v); +inline sc_unsigned operator | (const sc_unsigned &u, unsigned int v); + +sc_signed operator | (int64 u, const sc_unsigned &v); +sc_unsigned operator | (uint64 u, const sc_unsigned &v); +sc_signed operator | (long u, const sc_unsigned &v); +sc_unsigned operator | (unsigned long u, const sc_unsigned &v); +sc_signed operator | (int u, const sc_unsigned &v); +inline sc_unsigned operator | (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator | (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator | (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator | (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator | (const sc_int_base &u, const sc_unsigned &v); + +// Bitwise XOR operators: +sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v); +sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator ^ (const sc_unsigned &u, const sc_unsigned &v); +sc_signed operator ^ (const sc_unsigned &u, int64 v); +sc_unsigned operator ^ (const sc_unsigned &u, uint64 v); +sc_signed operator ^ (const sc_unsigned &u, long v); +sc_unsigned operator ^ (const sc_unsigned &u, unsigned long v); +sc_signed operator ^ (const sc_unsigned &u, int v); +inline sc_unsigned operator ^ (const sc_unsigned &u, unsigned int v); + +sc_signed operator ^ (int64 u, const sc_unsigned &v); +sc_unsigned operator ^ (uint64 u, const sc_unsigned &v); +sc_signed operator ^ (long u, const sc_unsigned &v); +sc_unsigned operator ^ (unsigned long u, const sc_unsigned &v); +sc_signed operator ^ (int u, const sc_unsigned &v); +inline sc_unsigned operator ^ (unsigned int u, const sc_unsigned &v); + +sc_unsigned operator ^ (const sc_unsigned &u, const sc_uint_base &v); +sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v); +sc_unsigned operator ^ (const sc_uint_base &u, const sc_unsigned &v); +sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v); + +// SHIFT OPERATORS: + +// LEFT SHIFT operators: +sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v); +sc_signed operator << (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator << (const sc_unsigned &u, const sc_unsigned &v); +sc_unsigned operator << (const sc_unsigned &u, int64 v); +sc_unsigned operator << (const sc_unsigned &u, uint64 v); +sc_unsigned operator << (const sc_unsigned &u, long v); +sc_unsigned operator << (const sc_unsigned &u, unsigned long v); +inline sc_unsigned operator << (const sc_unsigned &u, int v); +inline sc_unsigned operator << (const sc_unsigned &u, unsigned int v); + +sc_unsigned operator << (const sc_unsigned &u, const sc_uint_base &v); +sc_unsigned operator << (const sc_unsigned &u, const sc_int_base &v); + +// RIGHT SHIFT operators: +sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v); +sc_signed operator >> (const sc_signed &u, const sc_unsigned &v); + +sc_unsigned operator >> (const sc_unsigned &u, const sc_unsigned &v); +sc_unsigned operator >> (const sc_unsigned &u, int64 v); +sc_unsigned operator >> (const sc_unsigned &u, uint64 v); +sc_unsigned operator >> (const sc_unsigned &u, long v); +sc_unsigned operator >> (const sc_unsigned &u, unsigned long v); +inline sc_unsigned operator >> (const sc_unsigned &u, int v); +inline sc_unsigned operator >> (const sc_unsigned &u, unsigned int v); + +sc_unsigned operator >> ( const sc_unsigned &, const sc_uint_base &); +sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base &); + +// Unary arithmetic operators +sc_unsigned operator + (const sc_unsigned &u); +sc_signed operator - (const sc_unsigned &u); + +// LOGICAL OPERATORS: + +// Logical EQUAL operators: +bool operator == (const sc_unsigned &u, const sc_signed &v); +bool operator == (const sc_signed &u, const sc_unsigned &v); + +bool operator == (const sc_unsigned &u, const sc_unsigned &v); +bool operator == (const sc_unsigned &u, int64 v); +bool operator == (const sc_unsigned &u, uint64 v); +bool operator == (const sc_unsigned &u, long v); +bool operator == (const sc_unsigned &u, unsigned long v); +inline bool operator == (const sc_unsigned &u, int v); +inline bool operator == (const sc_unsigned &u, unsigned int v); + +bool operator == (int64 u, const sc_unsigned &v); +bool operator == (uint64 u, const sc_unsigned &v); +bool operator == (long u, const sc_unsigned &v); +bool operator == (unsigned long u, const sc_unsigned &v); +inline bool operator == (int u, const sc_unsigned &v); +inline bool operator == (unsigned int u, const sc_unsigned &v) ; + +bool operator == (const sc_unsigned &u, const sc_uint_base &v); +bool operator == (const sc_unsigned &u, const sc_int_base &v); +bool operator == (const sc_uint_base &u, const sc_unsigned &v); +bool operator == (const sc_int_base &u, const sc_unsigned &v); + +// Logical NOT_EQUAL operators: +bool operator != (const sc_unsigned &u, const sc_signed &v); +bool operator != (const sc_signed &u, const sc_unsigned &v); + +bool operator != (const sc_unsigned &u, const sc_unsigned &v); +bool operator != (const sc_unsigned &u, int64 v); +bool operator != (const sc_unsigned &u, uint64 v); +bool operator != (const sc_unsigned &u, long v); +bool operator != (const sc_unsigned &u, unsigned long v); +inline bool operator != (const sc_unsigned &u, int v); +inline bool operator != (const sc_unsigned &u, unsigned int v); + +bool operator != (int64 u, const sc_unsigned &v); +bool operator != (uint64 u, const sc_unsigned &v); +bool operator != (long u, const sc_unsigned &v); +bool operator != (unsigned long u, const sc_unsigned &v); +inline bool operator != (int u, const sc_unsigned &v); +inline bool operator != (unsigned int u, const sc_unsigned &v); + +bool operator != (const sc_unsigned &u, const sc_uint_base &v); +bool operator != (const sc_unsigned &u, const sc_int_base &v); +bool operator != (const sc_uint_base &u, const sc_unsigned &v); +bool operator != (const sc_int_base &u, const sc_unsigned &v); + +// Logical LESS_THAN operators: +bool operator < (const sc_unsigned &u, const sc_signed &v); +bool operator < (const sc_signed &u, const sc_unsigned &v); + +bool operator < (const sc_unsigned &u, const sc_unsigned &v); +bool operator < (const sc_unsigned &u, int64 v); +bool operator < (const sc_unsigned &u, uint64 v); +bool operator < (const sc_unsigned &u, long v); +bool operator < (const sc_unsigned &u, unsigned long v); +inline bool operator < (const sc_unsigned &u, int v); +inline bool operator < (const sc_unsigned &u, unsigned int v); + +bool operator < (int64 u, const sc_unsigned &v); +bool operator < (uint64 u, const sc_unsigned &v); +bool operator < (long u, const sc_unsigned &v); +bool operator < (unsigned long u, const sc_unsigned &v); +inline bool operator < (int u, const sc_unsigned &v); +inline bool operator < (unsigned int u, const sc_unsigned &v); + +bool operator < (const sc_unsigned &u, const sc_uint_base &v); +bool operator < (const sc_unsigned &u, const sc_int_base &v); +bool operator < (const sc_uint_base &u, const sc_unsigned &v); +bool operator < (const sc_int_base &u, const sc_unsigned &v); + +// Logical LESS_THAN_AND_EQUAL operators: +bool operator <= (const sc_unsigned &u, const sc_signed &v); +bool operator <= (const sc_signed &u, const sc_unsigned &v); + +bool operator <= (const sc_unsigned &u, const sc_unsigned &v); +bool operator <= (const sc_unsigned &u, int64 v); +bool operator <= (const sc_unsigned &u, uint64 v); +bool operator <= (const sc_unsigned &u, long v); +bool operator <= (const sc_unsigned &u, unsigned long v); +inline bool operator <= (const sc_unsigned &u, int v); +inline bool operator <= (const sc_unsigned &u, unsigned int v); + +bool operator <= (int64 u, const sc_unsigned &v); +bool operator <= (uint64 u, const sc_unsigned &v); +bool operator <= (long u, const sc_unsigned &v); +bool operator <= (unsigned long u, const sc_unsigned &v); +inline bool operator <= (int u, const sc_unsigned &v); +inline bool operator <= (unsigned int u, const sc_unsigned &v); + +bool operator <= (const sc_unsigned &u, const sc_uint_base &v); +bool operator <= (const sc_unsigned &u, const sc_int_base &v); +bool operator <= (const sc_uint_base &u, const sc_unsigned &v); +bool operator <= (const sc_int_base &u, const sc_unsigned &v); + +// Logical GREATER_THAN operators: +bool operator > (const sc_unsigned &u, const sc_signed &v); +bool operator > (const sc_signed &u, const sc_unsigned &v); + +bool operator > (const sc_unsigned &u, const sc_unsigned &v); +bool operator > (const sc_unsigned &u, int64 v); +bool operator > (const sc_unsigned &u, uint64 v); +bool operator > (const sc_unsigned &u, long v); +bool operator > (const sc_unsigned &u, unsigned long v); +inline bool operator > (const sc_unsigned &u, int v); +inline bool operator > (const sc_unsigned &u, unsigned int v); + +bool operator > (int64 u, const sc_unsigned &v); +bool operator > (uint64 u, const sc_unsigned &v); +bool operator > (long u, const sc_unsigned &v); +bool operator > (unsigned long u, const sc_unsigned &v); +inline bool operator > (int u, const sc_unsigned &v); +inline bool operator > (unsigned int u, const sc_unsigned &v); + +bool operator > (const sc_unsigned &u, const sc_uint_base &v); +bool operator > (const sc_unsigned &u, const sc_int_base &v); +bool operator > (const sc_uint_base &u, const sc_unsigned &v); +bool operator > (const sc_int_base &u, const sc_unsigned &v); + +// Logical GREATER_THAN_AND_EQUAL operators: +bool operator >= (const sc_unsigned &u, const sc_signed &v); +bool operator >= (const sc_signed &u, const sc_unsigned &v); + +bool operator >= (const sc_unsigned &u, const sc_unsigned &v); +bool operator >= (const sc_unsigned &u, int64 v); +bool operator >= (const sc_unsigned &u, uint64 v); +bool operator >= (const sc_unsigned &u, long v); +bool operator >= (const sc_unsigned &u, unsigned long v); +inline bool operator >= (const sc_unsigned &u, int v); +inline bool operator >= (const sc_unsigned &u, unsigned int v); + +bool operator >= (int64 u, const sc_unsigned &v); +bool operator >= (uint64 u, const sc_unsigned &v); +bool operator >= (long u, const sc_unsigned &v); +bool operator >= (unsigned long u, const sc_unsigned &v); +inline bool operator >= (int u, const sc_unsigned &v); +inline bool operator >= (unsigned int u, const sc_unsigned &v); + +bool operator >= (const sc_unsigned &u, const sc_uint_base &v); +bool operator >= (const sc_unsigned &u, const sc_int_base &v); +bool operator >= (const sc_uint_base &u, const sc_unsigned &v); +bool operator >= (const sc_int_base &u, const sc_unsigned &v); + +// Bitwise NOT operator (unary). +sc_unsigned operator ~ (const sc_unsigned &u); + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref_r +// +// Proxy class for sc_unsigned bit selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_unsigned_bitref_r : public sc_value_base +{ + friend class sc_unsigned; + + protected: + // construction and initialization: + sc_unsigned_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {} + + void + initialize(const sc_unsigned *obj_p, int index_) + { + m_obj_p = const_cast<sc_unsigned *>(obj_p); + m_index = index_; + } + + public: + // destructor + virtual ~sc_unsigned_bitref_r() {} + + // copy constructor + sc_unsigned_bitref_r(const sc_unsigned_bitref_r &a) : + sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p) + {} + + // capacity + int length() const { return 1; } + + // implicit conversion to bool + operator uint64 () const; + bool operator ! () const; + bool operator ~ () const; + + // explicit conversions + uint64 value() const { return operator uint64(); } + bool to_bool() const { return operator uint64(); } + + // concatenation support + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return 1; + } + virtual uint64 + concat_get_uint64() const + { + return (uint64)operator uint64(); + } + virtual bool + concat_get_ctrl(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + int word_i = low_i / BITS_PER_DIGIT; + dst_p[word_i] &= ~bit_mask; + return false; + } + virtual bool + concat_get_data(sc_digit *dst_p, int low_i) const + { + int bit_mask = 1 << (low_i % BITS_PER_DIGIT); + bool result; // True if non-zero. + int word_i = low_i / BITS_PER_DIGIT; + if (operator uint64()) + { + dst_p[word_i] |= bit_mask; + result = true; + } else { + dst_p[word_i] &= ~bit_mask; + result = false; + } + return result; + } + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_bool(); } + + protected: + int m_index; + sc_unsigned *m_obj_p; + + private: + // Disabled + const sc_unsigned_bitref_r &operator = (const sc_unsigned_bitref_r &); +}; + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_unsigned_bitref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref +// +// Proxy class for sc_unsigned bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_unsigned_bitref : public sc_unsigned_bitref_r +{ + friend class sc_unsigned; + friend class sc_core::sc_vpool<sc_unsigned_bitref>; + + protected: // construction + sc_unsigned_bitref() : sc_unsigned_bitref_r() {} + + public: + // copy constructor + sc_unsigned_bitref(const sc_unsigned_bitref &a) : sc_unsigned_bitref_r(a) + {} + + // assignment operators + const sc_unsigned_bitref &operator = (const sc_unsigned_bitref_r &); + const sc_unsigned_bitref &operator = (const sc_unsigned_bitref &); + const sc_unsigned_bitref &operator = (bool); + + const sc_unsigned_bitref &operator &= (bool); + const sc_unsigned_bitref &operator |= (bool); + const sc_unsigned_bitref &operator ^= (bool); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_unsigned_bitref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_unsigned_bitref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref_r +// +// Proxy class for sc_unsigned part selection (r-value only). +// ---------------------------------------------------------------------------- + +class sc_unsigned_subref_r : public sc_value_base +{ + friend class sc_signed; + friend class sc_unsigned; + friend class sc_unsigned_signal; + + protected: + // constructor + sc_unsigned_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) + {} + + void + initialize(const sc_unsigned *obj_p, int left_, int right_) + { + m_obj_p = const_cast<sc_unsigned *>(obj_p); + m_left = left_; + m_right = right_; + } + + public: + // destructor + virtual ~sc_unsigned_subref_r() {} + + // copy constructor + sc_unsigned_subref_r(const sc_unsigned_subref_r &a) : + sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p), + m_right(a.m_right) + {} + + // capacity + int + length() const + { + if (m_left >= m_right) + return m_left - m_right + 1; + else + return m_right - m_left + 1; + } + + // implicit conversion to sc_unsigned + operator sc_unsigned () 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; + double to_double() const; + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // concatenation support + virtual int concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return m_left - m_right + 1; + } + virtual uint64 concat_get_uint64() const; + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const; + bool or_reduce() const; + bool nor_reduce() const; + bool xor_reduce() const ; + bool xnor_reduce() const; + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + protected: + int m_left; // Left-most bit in this part selection. + sc_unsigned *m_obj_p; // Target of this part selection. + int m_right; // Right-most bit in this part selection. + + private: + // Disabled + const sc_unsigned_subref_r &operator = (const sc_unsigned_subref_r &); +}; + +inline ::std::ostream &operator << ( + ::std::ostream &, const sc_unsigned_subref_r &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref +// +// Proxy class for sc_unsigned part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +class sc_unsigned_subref : public sc_unsigned_subref_r +{ + friend class sc_unsigned; + friend class sc_core::sc_vpool<sc_unsigned_subref>; + + // constructor + protected: + sc_unsigned_subref() : sc_unsigned_subref_r() {} + + public: + // copy constructor + sc_unsigned_subref(const sc_unsigned_subref &a) : sc_unsigned_subref_r(a) + {} + + // assignment operators + const sc_unsigned_subref &operator = (const sc_unsigned_subref_r &a); + const sc_unsigned_subref &operator = (const sc_unsigned_subref &a); + const sc_unsigned_subref &operator = (const sc_unsigned &a); + + template<class T> + const sc_unsigned_subref &operator = (const sc_generic_base<T> &a); + const sc_unsigned_subref &operator = (const sc_signed_subref_r &a); + const sc_unsigned_subref &operator = (const sc_signed &a); + + const sc_unsigned_subref &operator = (const char *a); + const sc_unsigned_subref &operator = (unsigned long a); + const sc_unsigned_subref &operator = (long a); + + const sc_unsigned_subref & + operator = (unsigned int a) + { + return operator = ((unsigned long)a); + } + + const sc_unsigned_subref & + operator = (int a) + { + return operator = ((long)a); + } + + const sc_unsigned_subref &operator = (uint64 a); + const sc_unsigned_subref &operator = (int64 a); + const sc_unsigned_subref &operator = (double a); + const sc_unsigned_subref &operator = (const sc_int_base &a); + const sc_unsigned_subref &operator = (const sc_uint_base &a); + + // concatenation methods + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // other methods + void scan(::std::istream &is=::std::cin); + + protected: + static sc_core::sc_vpool<sc_unsigned_subref> m_pool; +}; + +inline ::std::istream &operator >> (::std::istream &, sc_unsigned_subref &); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// +// Arbitrary precision unsigned number. +// ---------------------------------------------------------------------------- + +class sc_unsigned : public sc_value_base +{ + friend class sc_concatref; + friend class sc_unsigned_bitref_r; + friend class sc_unsigned_bitref; + friend class sc_unsigned_subref_r; + friend class sc_unsigned_subref; + friend class sc_signed; + friend class sc_signed_subref; + friend class sc_signed_subref_r; + + // Needed for types using sc_unsigned. + typedef bool elemtype; + + void invalid_init(const char *type_name, int nb) const; + + public: + // constructors + explicit sc_unsigned(int nb=sc_length_param().len()); + sc_unsigned(const sc_unsigned &v); + sc_unsigned(const sc_signed &v); + template<class T> + explicit sc_unsigned(const sc_generic_base<T> &v); + explicit sc_unsigned(const sc_bv_base &v); + explicit sc_unsigned(const sc_lv_base &v); + explicit sc_unsigned(const sc_int_subref_r &v); + explicit sc_unsigned(const sc_uint_subref_r &v); + explicit sc_unsigned(const sc_signed_subref_r &v); + explicit sc_unsigned(const sc_unsigned_subref_r &v); + + // assignment operators + const sc_unsigned &operator = (const sc_unsigned &v); + const sc_unsigned &operator = (const sc_unsigned_subref_r &a); + + template<class T> + const sc_unsigned & + operator = (const sc_generic_base<T> &a) + { + a->to_sc_unsigned(*this); + return *this; + } + + const sc_unsigned &operator = (const sc_signed &v); + const sc_unsigned &operator = (const sc_signed_subref_r &a); + + const sc_unsigned &operator = (const char *v); + const sc_unsigned &operator = (int64 v); + const sc_unsigned &operator = (uint64 v); + const sc_unsigned &operator = (long v); + const sc_unsigned &operator = (unsigned long v); + + const sc_unsigned & + operator = (int v) + { + return operator = ((long)v); + } + + const sc_unsigned & + operator = (unsigned int v) + { + return operator = ((unsigned long)v); + } + + const sc_unsigned &operator = (double v); + const sc_unsigned &operator = (const sc_int_base &v); + const sc_unsigned &operator = (const sc_uint_base &v); + + const sc_unsigned &operator = (const sc_bv_base &); + const sc_unsigned &operator = (const sc_lv_base &); + + const sc_unsigned &operator = (const sc_fxval &); + const sc_unsigned &operator = (const sc_fxval_fast &); + const sc_unsigned &operator = (const sc_fxnum &); + const sc_unsigned &operator = (const sc_fxnum_fast &); + + // destructor + virtual ~sc_unsigned() + { +# ifndef SC_MAX_NBITS + delete [] digit; +# endif + } + + // Concatenation support: + sc_digit *get_raw() const { return digit; } + virtual int + concat_length(bool *xz_present_p) const + { + if (xz_present_p) + *xz_present_p = false; + return nbits - 1; + } + virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const; + virtual bool concat_get_data(sc_digit *dst_p, int low_i) const; + virtual uint64 concat_get_uint64() const; + virtual void concat_set(int64 src, int low_i); + virtual void concat_set(const sc_signed &src, int low_i); + virtual void concat_set(const sc_unsigned &src, int low_i); + virtual void concat_set(uint64 src, int low_i); + + // Increment operators. + sc_unsigned &operator ++ (); + const sc_unsigned operator ++ (int); + + // Decrement operators. + sc_unsigned &operator -- (); + const sc_unsigned operator -- (int); + + // bit selection + inline void + check_index(int i) const + { + if ((i < 0) || (i >= nbits - 1)) + invalid_index(i); + } + + void invalid_index(int i) const; + + sc_unsigned_bitref & + operator [] (int i) + { + check_index(i); + sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + const sc_unsigned_bitref_r & + operator [] (int i) const + { + check_index(i); + sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + sc_unsigned_bitref & + bit(int i) + { + check_index(i); + sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + const sc_unsigned_bitref_r & + bit(int i) const + { + check_index(i); + sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate(); + result_p->initialize(this, i); + return *result_p; + } + + // part selection + + // Subref operators. Help access the range of bits from the ith to + // jth. These indices have arbitrary precedence with respect to each + // other, i.e., we can have i <= j or i > j. Note the equivalence + // between range(i, j) and operator (i, j). Also note that + // operator (i, i) returns an unsigned number that corresponds to the + // bit operator [i], so these two forms are not the same. + inline void + check_range(int l, int r) const + { + if (l < r) { + if ((l < 0) || (r >= nbits - 1)) + invalid_range(l, r); + } else { + if ((r < 0) || (l >= nbits - 1)) + invalid_range(l, r); + } + } + + void invalid_range(int l, int r) const; + + sc_unsigned_subref & + range(int i, int j) + { + check_range(i, j); + sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + const sc_unsigned_subref_r & + range(int i, int j) const + { + check_range(i, j); + sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + sc_unsigned_subref & + operator () (int i, int j) + { + check_range(i,j); + sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + const sc_unsigned_subref_r & + operator () (int i, int j) const + { + check_range(i,j); + sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate(); + result_p->initialize(this, i, j); + return *result_p; + } + + // 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; + double to_double() const; + + // explicit conversion to character string + const std::string to_string(sc_numrep numrep=SC_DEC) const; + const std::string to_string(sc_numrep numrep, bool w_prefix) const; + + // Print functions. dump prints the internals of the class. + void + print(::std::ostream &os=::std::cout) const + { + os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os)); + } + + void scan(::std::istream &is=::std::cin); + void dump(::std::ostream &os=::std::cout) const; + + // Functions to find various properties. + int length() const { return nbits - 1; } // Bit width. + bool iszero() const; // Is the number zero? + bool sign() const { return 0; } // Sign. + + // reduce methods + bool and_reduce() const; + bool nand_reduce() const { return !and_reduce(); } + bool or_reduce() const; + bool nor_reduce() const { return !or_reduce(); } + bool xor_reduce() const; + bool xnor_reduce() const { return !xor_reduce(); } + + // Functions to access individual bits. + bool test(int i) const; // Is the ith bit 0 or 1? + void set(int i); // Set the ith bit to 1. + void clear(int i); // Set the ith bit to 0. + void + set(int i, bool v) // Set the ith bit to v. + { + if (v) + set(i); + else + clear(i); + } + void + invert(int i) // Negate the ith bit. + { + if (test(i)) + clear(i); + else + set(i); + } + + // Make the number equal to its mirror image. + void reverse(); + + // Get/set a packed bit representation of the number. + void get_packed_rep(sc_digit *buf) const; + void set_packed_rep(sc_digit *buf); + + /* + The comparison of the old and new semantics are as follows: + + Let s = sc_signed, + u = sc_unsigned, + un = { uint64, unsigned long, unsigned int }, + sn = { int64, long, int, char* }, and + OP = { +, -, *, /, % }. + + Old semantics: New semantics: + u OP u -> u u OP u -> u + s OP u -> u s OP u -> s + u OP s -> u u OP s -> s + s OP s -> s s OP s -> s + + u OP un = un OP u -> u u OP un = un OP u -> u + u OP sn = sn OP u -> u u OP sn = sn OP u -> s + + s OP un = un OP s -> s s OP un = un OP s -> s + s OP sn = sn OP s -> s s OP sn = sn OP s -> s + + In the new semantics, the result is u if both operands are u; the + result is s otherwise. The only exception is subtraction. The result + of a subtraction is always s. + + The old semantics is like C/C++ semantics on integer types; the + new semantics is due to the VSIA C/C++ data types standard. + */ + + // ARITHMETIC OPERATORS: + + // ADDition operators: + friend sc_signed operator + (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator + (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator + (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator + (const sc_unsigned &u, int64 v); + friend sc_unsigned operator + (const sc_unsigned &u, uint64 v); + friend sc_signed operator + (const sc_unsigned &u, long v); + friend sc_unsigned operator + (const sc_unsigned &u, unsigned long v); + friend sc_signed operator + (const sc_unsigned &u, int v); + friend sc_unsigned + operator + (const sc_unsigned &u, unsigned int v) + { + return operator + (u, (unsigned long)v); + } + + friend sc_signed operator + (int64 u, const sc_unsigned &v); + friend sc_unsigned operator + (uint64 u, const sc_unsigned &v); + friend sc_signed operator + (long u, const sc_unsigned &v); + friend sc_unsigned operator + (unsigned long u, const sc_unsigned &v); + friend sc_signed operator + (int u, const sc_unsigned &v); + friend sc_unsigned + operator + (unsigned int u, const sc_unsigned &v) + { + return operator + ((unsigned long)u, v); + } + + const sc_unsigned &operator += (const sc_signed &v); + const sc_unsigned &operator += (const sc_unsigned &v); + const sc_unsigned &operator += (int64 v); + const sc_unsigned &operator += (uint64 v); + const sc_unsigned &operator += (long v); + const sc_unsigned &operator += (unsigned long v); + const sc_unsigned & + operator += (int v) + { + return operator += ((long)v); + } + const sc_unsigned & + operator += (unsigned int v) + { + return operator += ((unsigned long)v); + } + + friend sc_unsigned operator + ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator + (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator + ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator + (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator += (const sc_int_base &v); + const sc_unsigned &operator += (const sc_uint_base &v); + + // SUBtraction operators: + friend sc_signed operator - (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator - (const sc_signed &u, const sc_unsigned &v); + + friend sc_signed operator - (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator - (const sc_unsigned &u, int64 v); + friend sc_signed operator - (const sc_unsigned &u, uint64 v); + friend sc_signed operator - (const sc_unsigned &u, long v); + friend sc_signed operator - (const sc_unsigned &u, unsigned long v); + friend sc_signed operator - (const sc_unsigned &u, int v); + friend sc_signed operator - (const sc_unsigned &u, unsigned int v); + + friend sc_signed operator - (int64 u, const sc_unsigned &v); + friend sc_signed operator - (uint64 u, const sc_unsigned &v); + friend sc_signed operator - (long u, const sc_unsigned &v); + friend sc_signed operator - (unsigned long u, const sc_unsigned &v); + friend sc_signed operator - (int u, const sc_unsigned &v); + friend sc_signed operator - (unsigned int u, const sc_unsigned &v); + + const sc_unsigned &operator -= (const sc_signed &v); + const sc_unsigned &operator -= (const sc_unsigned &v); + const sc_unsigned &operator -= (int64 v); + const sc_unsigned &operator -= (uint64 v); + const sc_unsigned &operator -= (long v); + const sc_unsigned &operator -= (unsigned long v); + const sc_unsigned & + operator -= (int v) + { + return operator -= ((long)v); + } + const sc_unsigned & + operator -= (unsigned int v) + { + return operator -= ((unsigned long)v); + } + + friend sc_signed operator - (const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator - (const sc_unsigned &u, const sc_int_base &v); + friend sc_signed operator - (const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator - (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator -= (const sc_int_base &v); + const sc_unsigned &operator -= (const sc_uint_base &v); + + // MULtiplication operators: + friend sc_signed operator * (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator * (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator * (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator * (const sc_unsigned &u, int64 v); + friend sc_unsigned operator * (const sc_unsigned &u, uint64 v); + friend sc_signed operator * (const sc_unsigned &u, long v); + friend sc_unsigned operator * (const sc_unsigned &u, unsigned long v); + friend sc_signed operator * (const sc_unsigned &u, int v); + friend sc_unsigned + operator * (const sc_unsigned &u, unsigned int v) + { + return operator * (u, (unsigned long)v); + } + + friend sc_signed operator * (int64 u, const sc_unsigned &v); + friend sc_unsigned operator * (uint64 u, const sc_unsigned &v); + friend sc_signed operator * (long u, const sc_unsigned &v); + friend sc_unsigned operator * (unsigned long u, const sc_unsigned &v); + friend sc_signed operator * (int u, const sc_unsigned &v); + friend sc_unsigned + operator * (unsigned int u, const sc_unsigned &v) + { + return operator * ((unsigned long)u, v); + } + + const sc_unsigned &operator *= (const sc_signed &v); + const sc_unsigned &operator *= (const sc_unsigned &v); + const sc_unsigned &operator *= (int64 v); + const sc_unsigned &operator *= (uint64 v); + const sc_unsigned &operator *= (long v); + const sc_unsigned &operator *= (unsigned long v); + const sc_unsigned &operator *= (int v) { return operator *= ((long)v); } + const sc_unsigned & + operator *= (unsigned int v) + { + return operator *= ((unsigned long)v); + } + + friend sc_unsigned operator * ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator * (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator * ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator * (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator *= (const sc_int_base &v); + const sc_unsigned &operator *= (const sc_uint_base &v); + + // DIVision operators: + friend sc_signed operator / (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator / (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator / (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator / (const sc_unsigned &u, int64 v); + friend sc_unsigned operator / (const sc_unsigned &u, uint64 v); + friend sc_signed operator / (const sc_unsigned &u, long v); + friend sc_unsigned operator / (const sc_unsigned &u, unsigned long v); + friend sc_signed operator / (const sc_unsigned &u, int v); + friend sc_unsigned + operator / (const sc_unsigned &u, unsigned int v) + { + return operator / (u, (unsigned long)v); + } + + friend sc_signed operator / (int64 u, const sc_unsigned &v); + friend sc_unsigned operator / (uint64 u, const sc_unsigned &v); + friend sc_signed operator / (long u, const sc_unsigned &v); + friend sc_unsigned operator / (unsigned long u, const sc_unsigned &v); + friend sc_signed operator / (int u, const sc_unsigned &v); + friend sc_unsigned + operator / (unsigned int u, const sc_unsigned &v) + { + return operator / ((unsigned long)u, v); + } + + const sc_unsigned &operator /= (const sc_signed &v); + const sc_unsigned &operator /= (const sc_unsigned &v); + const sc_unsigned &operator /= (int64 v); + const sc_unsigned &operator /= (uint64 v); + const sc_unsigned &operator /= (long v); + const sc_unsigned &operator /= (unsigned long v); + const sc_unsigned &operator /= (int v) { return operator /= ((long)v); } + const sc_unsigned & + operator /= (unsigned int v) + { + return operator /= ((unsigned long)v); + } + + friend sc_unsigned operator / ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator / (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator / ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator / (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator /= (const sc_int_base &v); + const sc_unsigned &operator /= (const sc_uint_base &v); + + // MODulo operators: + friend sc_signed operator % (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator % (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator % (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator % (const sc_unsigned &u, int64 v); + friend sc_unsigned operator % (const sc_unsigned &u, uint64 v); + friend sc_signed operator % (const sc_unsigned &u, long v); + friend sc_unsigned operator % (const sc_unsigned &u, unsigned long v); + friend sc_signed operator % (const sc_unsigned &u, int v); + friend sc_unsigned + operator % (const sc_unsigned &u, unsigned int v) + { + return operator % (u, (unsigned long)v); + } + + friend sc_signed operator % (int64 u, const sc_unsigned &v); + friend sc_unsigned operator % (uint64 u, const sc_unsigned &v); + friend sc_signed operator % (long u, const sc_unsigned &v); + friend sc_unsigned operator % (unsigned long u, const sc_unsigned &v); + friend sc_signed operator % (int u, const sc_unsigned &v); + friend sc_unsigned + operator % (unsigned int u, const sc_unsigned &v) + { + return operator % ((unsigned long)u, v); + } + + const sc_unsigned &operator %= (const sc_signed &v); + const sc_unsigned &operator %= (const sc_unsigned &v); + const sc_unsigned &operator %= (int64 v); + const sc_unsigned &operator %= (uint64 v); + const sc_unsigned &operator %= (long v); + const sc_unsigned &operator %= (unsigned long v); + const sc_unsigned &operator %= (int v) { return operator %= ((long)v); } + const sc_unsigned & + operator %= (unsigned int v) + { + return operator %= ((unsigned long)v); + } + + friend sc_unsigned operator % ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator % (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator % ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator % (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator %= (const sc_int_base &v); + const sc_unsigned &operator %= (const sc_uint_base &v); + + // BITWISE OPERATORS: + + // Bitwise AND operators: + friend sc_signed operator & (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator & (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator & (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator & (const sc_unsigned &u, int64 v); + friend sc_unsigned operator & (const sc_unsigned &u, uint64 v); + friend sc_signed operator & (const sc_unsigned &u, long v); + friend sc_unsigned operator & (const sc_unsigned &u, unsigned long v); + friend sc_signed operator & (const sc_unsigned &u, int v); + friend sc_unsigned + operator & (const sc_unsigned &u, unsigned int v) + { + return operator & (u, (unsigned long)v); + } + + friend sc_signed operator & (int64 u, const sc_unsigned &v); + friend sc_unsigned operator & (uint64 u, const sc_unsigned &v); + friend sc_signed operator & (long u, const sc_unsigned &v); + friend sc_unsigned operator & (unsigned long u, const sc_unsigned &v); + friend sc_signed operator & (int u, const sc_unsigned &v); + friend sc_unsigned + operator & (unsigned int u, const sc_unsigned &v) + { + return operator & ((unsigned long)u, v); + } + + const sc_unsigned &operator &= (const sc_signed &v); + const sc_unsigned &operator &= (const sc_unsigned &v); + const sc_unsigned &operator &= (int64 v); + const sc_unsigned &operator &= (uint64 v); + const sc_unsigned &operator &= (long v); + const sc_unsigned &operator &= (unsigned long v); + const sc_unsigned &operator &= (int v) { return operator&=((long) v); } + const sc_unsigned & + operator &= (unsigned int v) + { + return operator &= ((unsigned long)v); + } + + friend sc_unsigned operator & ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator & (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator & ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator & (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator &= (const sc_int_base &v); + const sc_unsigned &operator &= (const sc_uint_base &v); + + // Bitwise OR operators: + friend sc_signed operator | (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator | (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator | (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator | (const sc_unsigned &u, int64 v); + friend sc_unsigned operator | (const sc_unsigned &u, uint64 v); + friend sc_signed operator | (const sc_unsigned &u, long v); + friend sc_unsigned operator | (const sc_unsigned &u, unsigned long v); + friend sc_signed operator | (const sc_unsigned &u, int v); + friend sc_unsigned + operator | (const sc_unsigned &u, unsigned int v) + { + return operator | (u, (unsigned long)v); + } + + friend sc_signed operator | (int64 u, const sc_unsigned &v); + friend sc_unsigned operator | (uint64 u, const sc_unsigned &v); + friend sc_signed operator | (long u, const sc_unsigned &v); + friend sc_unsigned operator | (unsigned long u, const sc_unsigned &v); + friend sc_signed operator | (int u, const sc_unsigned &v); + friend sc_unsigned + operator | (unsigned int u, const sc_unsigned &v) + { + return operator | ((unsigned long)u, v); + } + + const sc_unsigned &operator |= (const sc_signed &v); + const sc_unsigned &operator |= (const sc_unsigned &v); + const sc_unsigned &operator |= (int64 v); + const sc_unsigned &operator |= (uint64 v); + const sc_unsigned &operator |= (long v); + const sc_unsigned &operator |= (unsigned long v); + const sc_unsigned &operator |= (int v) { return operator|=((long) v); } + const sc_unsigned & + operator |= (unsigned int v) + { + return operator |= ((unsigned long)v); + } + + friend sc_unsigned operator | ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator | (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator | ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator | (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator |= (const sc_int_base &v); + const sc_unsigned &operator |= (const sc_uint_base &v); + + // Bitwise XOR operators: + friend sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator ^ (const sc_unsigned &u, const sc_unsigned &v); + friend sc_signed operator ^ (const sc_unsigned &u, int64 v); + friend sc_unsigned operator ^ (const sc_unsigned &u, uint64 v); + friend sc_signed operator ^ (const sc_unsigned &u, long v); + friend sc_unsigned operator ^ (const sc_unsigned &u, unsigned long v); + friend sc_signed operator ^ (const sc_unsigned &u, int v); + friend sc_unsigned + operator ^ (const sc_unsigned &u, unsigned int v) + { + return operator ^ (u, (unsigned long)v); + } + + friend sc_signed operator ^ (int64 u, const sc_unsigned &v); + friend sc_unsigned operator ^ (uint64 u, const sc_unsigned &v); + friend sc_signed operator ^ (long u, const sc_unsigned &v); + friend sc_unsigned operator ^ (unsigned long u, const sc_unsigned &v); + friend sc_signed operator ^ (int u, const sc_unsigned &v); + friend sc_unsigned + operator ^ (unsigned int u, const sc_unsigned &v) + { + return operator ^ ((unsigned long)u, v); + } + + const sc_unsigned &operator ^= (const sc_signed &v); + const sc_unsigned &operator ^= (const sc_unsigned &v); + const sc_unsigned &operator ^= (int64 v); + const sc_unsigned &operator ^= (uint64 v); + const sc_unsigned &operator ^= (long v); + const sc_unsigned &operator ^= (unsigned long v); + const sc_unsigned & + operator ^= (int v) + { + return operator ^= ((long)v); + } + const sc_unsigned & + operator ^= (unsigned int v) + { + return operator ^= ((unsigned long)v); + } + + friend sc_unsigned operator ^ ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v); + friend sc_unsigned operator ^ ( + const sc_uint_base &u, const sc_unsigned &v); + friend sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v); + const sc_unsigned &operator ^= (const sc_int_base &v); + const sc_unsigned &operator ^= (const sc_uint_base &v); + + // SHIFT OPERATORS: + + // LEFT SHIFT operators: + friend sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator << (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator << ( + const sc_unsigned &u, const sc_unsigned &v); + friend sc_unsigned operator << (const sc_unsigned &u, int64 v); + friend sc_unsigned operator << (const sc_unsigned &u, uint64 v); + friend sc_unsigned operator << (const sc_unsigned &u, long v); + friend sc_unsigned operator << (const sc_unsigned &u, unsigned long v); + friend sc_unsigned + operator << (const sc_unsigned &u, int v) + { + return operator << (u, (long)v); + } + friend sc_unsigned + operator << (const sc_unsigned &u, unsigned int v) + { + return operator << (u, (unsigned long)v); + } + + const sc_unsigned &operator <<= (const sc_signed &v); + const sc_unsigned &operator <<= (const sc_unsigned &v); + const sc_unsigned &operator <<= (int64 v); + const sc_unsigned &operator <<= (uint64 v); + const sc_unsigned &operator <<= (long v); + const sc_unsigned &operator <<= (unsigned long v); + const sc_unsigned &operator <<= (int v) { return operator <<= ((long)v); } + const sc_unsigned & + operator <<= (unsigned int v) + { + return operator <<= ((unsigned long)v); + } + + friend sc_unsigned operator << ( + const sc_unsigned &u, const sc_uint_base &v); + friend sc_unsigned operator << ( + const sc_unsigned &u, const sc_int_base &v); + const sc_unsigned &operator <<= (const sc_int_base &v); + const sc_unsigned &operator <<= (const sc_uint_base &v); + + // RIGHT SHIFT operators: + friend sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v); + friend sc_signed operator >> (const sc_signed &u, const sc_unsigned &v); + + friend sc_unsigned operator >> ( + const sc_unsigned &u, const sc_unsigned &v); + friend sc_unsigned operator >> (const sc_unsigned &u, int64 v); + friend sc_unsigned operator >> (const sc_unsigned &u, uint64 v); + friend sc_unsigned operator >> (const sc_unsigned &u, long v); + friend sc_unsigned operator >> (const sc_unsigned &u, unsigned long v); + friend sc_unsigned + operator >> (const sc_unsigned &u, int v) + { + return operator >> (u, (long)v); + } + friend sc_unsigned + operator >> (const sc_unsigned &u, unsigned int v) + { + return operator >> (u, (unsigned long)v); + } + + const sc_unsigned &operator >>= (const sc_signed &v); + const sc_unsigned &operator >>= (const sc_unsigned &v); + const sc_unsigned &operator >>= (int64 v); + const sc_unsigned &operator >>= (uint64 v); + const sc_unsigned &operator >>= (long v); + const sc_unsigned &operator >>= (unsigned long v); + const sc_unsigned &operator >>= (int v) { return operator >>= ((long)v); } + const sc_unsigned & + operator >>= (unsigned int v) + { + return operator >>= ((unsigned long)v); + } + + friend sc_unsigned operator >> (const sc_unsigned &, const sc_uint_base &); + friend sc_unsigned operator >> (const sc_unsigned&, const sc_int_base &); + const sc_unsigned &operator >>= (const sc_int_base &v); + const sc_unsigned &operator >>= (const sc_uint_base &v); + + // Unary arithmetic operators + friend sc_unsigned operator + (const sc_unsigned &u); + friend sc_signed operator - (const sc_unsigned &u); + + // LOGICAL OPERATORS: + + // Logical EQUAL operators: + friend bool operator == (const sc_unsigned &u, const sc_signed &v); + friend bool operator == (const sc_signed &u, const sc_unsigned &v); + + friend bool operator == (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator == (const sc_unsigned &u, int64 v); + friend bool operator == (const sc_unsigned &u, uint64 v); + friend bool operator == (const sc_unsigned &u, long v); + friend bool operator == (const sc_unsigned &u, unsigned long v); + friend bool + operator == (const sc_unsigned &u, int v) + { + return operator == (u, (long)v); + } + friend bool + operator == (const sc_unsigned &u, unsigned int v) + { + return operator == (u, (unsigned long)v); + } + + friend bool operator == (int64 u, const sc_unsigned &v); + friend bool operator == (uint64 u, const sc_unsigned &v); + friend bool operator == (long u, const sc_unsigned &v); + friend bool operator == (unsigned long u, const sc_unsigned &v); + friend bool + operator == (int u, const sc_unsigned &v) + { + return operator == ((long)u, v); + } + friend bool + operator == (unsigned int u, const sc_unsigned &v) + { + return operator == ((unsigned long)u, v); + } + + friend bool operator == (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator == (const sc_unsigned &u, const sc_int_base &v); + friend bool operator == (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator == (const sc_int_base &u, const sc_unsigned &v); + + // Logical NOT_EQUAL operators: + friend bool operator != (const sc_unsigned &u, const sc_signed &v); + friend bool operator != (const sc_signed &u, const sc_unsigned &v); + + friend bool operator != (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator != (const sc_unsigned &u, int64 v); + friend bool operator != (const sc_unsigned &u, uint64 v); + friend bool operator != (const sc_unsigned &u, long v); + friend bool operator != (const sc_unsigned &u, unsigned long v); + friend bool + operator != (const sc_unsigned &u, int v) + { + return operator != (u, (long)v); + } + friend bool + operator != (const sc_unsigned &u, unsigned int v) + { + return operator != (u, (unsigned long)v); + } + + friend bool operator != (int64 u, const sc_unsigned &v); + friend bool operator != (uint64 u, const sc_unsigned &v); + friend bool operator != (long u, const sc_unsigned &v); + friend bool operator != (unsigned long u, const sc_unsigned &v); + friend bool + operator != (int u, const sc_unsigned &v) + { + return operator != ((long)u, v); + } + friend bool + operator != (unsigned int u, const sc_unsigned &v) + { + return operator != ((unsigned long)u, v); + } + + friend bool operator != (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator != (const sc_unsigned &u, const sc_int_base &v); + friend bool operator != (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator != (const sc_int_base &u, const sc_unsigned &v); + + // Logical LESS_THAN operators: + friend bool operator < (const sc_unsigned &u, const sc_signed &v); + friend bool operator < (const sc_signed &u, const sc_unsigned &v); + + friend bool operator < (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator < (const sc_unsigned &u, int64 v); + friend bool operator < (const sc_unsigned &u, uint64 v); + friend bool operator < (const sc_unsigned &u, long v); + friend bool operator < (const sc_unsigned &u, unsigned long v); + friend bool + operator < (const sc_unsigned &u, int v) + { + return operator < (u, (long)v); + } + friend bool + operator < (const sc_unsigned &u, unsigned int v) + { + return operator < (u, (unsigned long)v); + } + + friend bool operator < (int64 u, const sc_unsigned &v); + friend bool operator < (uint64 u, const sc_unsigned &v); + friend bool operator < (long u, const sc_unsigned &v); + friend bool operator < (unsigned long u, const sc_unsigned &v); + friend bool + operator < (int u, const sc_unsigned &v) + { + return operator < ((long)u, v); + } + friend bool + operator < (unsigned int u, const sc_unsigned &v) + { + return operator < ((unsigned long)u, v); + } + + friend bool operator < (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator < (const sc_unsigned &u, const sc_int_base &v); + friend bool operator < (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator < (const sc_int_base &u, const sc_unsigned &v); + + // Logical LESS_THAN_AND_EQUAL operators: + friend bool operator <= (const sc_unsigned &u, const sc_signed &v); + friend bool operator <= (const sc_signed &u, const sc_unsigned &v); + + friend bool operator <= (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator <= (const sc_unsigned &u, int64 v); + friend bool operator <= (const sc_unsigned &u, uint64 v); + friend bool operator <= (const sc_unsigned &u, long v); + friend bool operator <= (const sc_unsigned &u, unsigned long v); + friend bool + operator <= (const sc_unsigned &u, int v) + { + return operator <= (u, (long)v); + } + friend bool + operator <= (const sc_unsigned &u, unsigned int v) + { + return operator <= (u, (unsigned long)v); + } + + friend bool operator <= (int64 u, const sc_unsigned &v); + friend bool operator <= (uint64 u, const sc_unsigned &v); + friend bool operator <= (long u, const sc_unsigned &v); + friend bool operator <= (unsigned long u, const sc_unsigned &v); + friend bool + operator <= (int u, const sc_unsigned &v) + { + return operator <= ((long)u, v); + } + friend bool + operator <= (unsigned int u, const sc_unsigned &v) + { + return operator <= ((unsigned long)u, v); + } + + friend bool operator <= (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator <= (const sc_unsigned &u, const sc_int_base &v); + friend bool operator <= (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator <= (const sc_int_base &u, const sc_unsigned &v); + + // Logical GREATER_THAN operators: + friend bool operator > (const sc_unsigned &u, const sc_signed &v); + friend bool operator > (const sc_signed &u, const sc_unsigned &v); + + friend bool operator > (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator > (const sc_unsigned &u, int64 v); + friend bool operator > (const sc_unsigned &u, uint64 v); + friend bool operator > (const sc_unsigned &u, long v); + friend bool operator > (const sc_unsigned &u, unsigned long v); + friend bool + operator > (const sc_unsigned &u, int v) + { + return operator > (u, (long)v); + } + friend bool + operator > (const sc_unsigned &u, unsigned int v) + { + return operator > (u, (unsigned long)v); + } + + friend bool operator > (int64 u, const sc_unsigned &v); + friend bool operator > (uint64 u, const sc_unsigned &v); + friend bool operator > (long u, const sc_unsigned &v); + friend bool operator > (unsigned long u, const sc_unsigned &v); + friend bool + operator > (int u, const sc_unsigned &v) + { + return operator > ((long)u, v); + } + friend bool + operator > (unsigned int u, const sc_unsigned &v) + { + return operator > ((unsigned long)u, v); + } + + friend bool operator > (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator > (const sc_unsigned &u, const sc_int_base &v); + friend bool operator > (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator > (const sc_int_base &u, const sc_unsigned &v); + + // Logical GREATER_THAN_AND_EQUAL operators: + friend bool operator >= (const sc_unsigned &u, const sc_signed &v); + friend bool operator >= (const sc_signed &u, const sc_unsigned &v); + + friend bool operator >= (const sc_unsigned &u, const sc_unsigned &v); + friend bool operator >= (const sc_unsigned &u, int64 v); + friend bool operator >= (const sc_unsigned &u, uint64 v); + friend bool operator >= (const sc_unsigned &u, long v); + friend bool operator >= (const sc_unsigned &u, unsigned long v); + friend bool + operator >= (const sc_unsigned &u, int v) + { + return operator >= (u, (long)v); + } + friend bool + operator >= (const sc_unsigned &u, unsigned int v) + { + return operator >= (u, (unsigned long)v); + } + + friend bool operator >= (int64 u, const sc_unsigned &v); + friend bool operator >= (uint64 u, const sc_unsigned &v); + friend bool operator >= (long u, const sc_unsigned &v); + friend bool operator >= (unsigned long u, const sc_unsigned &v); + friend bool + operator >= (int u, const sc_unsigned &v) + { + return operator >= ((long)u, v); + } + friend bool + operator >= (unsigned int u, const sc_unsigned &v) + { + return operator >= ((unsigned long)u, v); + } + + friend bool operator >= (const sc_unsigned &u, const sc_uint_base &v); + friend bool operator >= (const sc_unsigned &u, const sc_int_base &v); + friend bool operator >= (const sc_uint_base &u, const sc_unsigned &v); + friend bool operator >= (const sc_int_base &u, const sc_unsigned &v); + + // Bitwise NOT operator (unary). + friend sc_unsigned operator ~ (const sc_unsigned &u); + + // Helper functions. + friend int compare_unsigned( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd, + small_type if_u_signed, small_type if_v_signed); + + friend sc_unsigned add_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned sub_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned mul_unsigned_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned div_unsigned_friend( + small_type s, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned mod_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned and_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned or_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + friend sc_unsigned xor_unsigned_friend( + small_type us, int unb, int und, const sc_digit *ud, + small_type vs, int vnb, int vnd, const sc_digit *vd); + + public: + static sc_core::sc_vpool<sc_unsigned> m_pool; + + private: + small_type sgn; // Shortened as s. + int nbits; // Shortened as nb. + int ndigits; // Shortened as nd. + +#ifdef SC_MAX_NBITS + sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d. +#else + sc_digit *digit; // Shortened as d. +#endif + + // Private constructors: + + // Create a copy of v with sign s. + sc_unsigned(const sc_unsigned &v, small_type s); + sc_unsigned(const sc_signed &v, small_type s); + + // Create an unsigned number with the given attributes. + sc_unsigned(small_type s, int nb, int nd, sc_digit *d, bool alloc=true); + + // Create an unsigned number using the bits u[l..r]. + sc_unsigned(const sc_signed *u, int l, int r); + sc_unsigned(const sc_unsigned *u, int l, int r); + + // Private member functions. The called functions are inline functions. + + small_type default_sign() const { return SC_POS; } + + int num_bits(int nb) const { return nb + 1; } + + bool check_if_outside(int bit_num) const; + + void + copy_digits(int nb, int nd, const sc_digit *d) + { + copy_digits_unsigned(sgn, nbits, ndigits, digit, nb, nd, d); + } + + void makezero() { sgn = make_zero(ndigits, digit); } + + // Conversion functions between 2's complement (2C) and + // sign-magnitude (SM): + void + convert_2C_to_SM() + { + sgn = convert_unsigned_2C_to_SM(nbits, ndigits, digit); + } + + void + convert_SM_to_2C_to_SM() + { + sgn = convert_unsigned_SM_to_2C_to_SM(sgn, nbits, ndigits, digit); + } + + void convert_SM_to_2C() { convert_unsigned_SM_to_2C(sgn, ndigits, digit); } +}; + +inline ::std::ostream &operator << (::std::ostream &, const sc_unsigned &); + +inline ::std::istream &operator >> (::std::istream &, sc_unsigned &); + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref_r +// +// Proxy class for sc_unsigned bit selection (r-value only). +// ---------------------------------------------------------------------------- + + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_unsigned_bitref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_bitref +// +// Proxy class for sc_unsigned bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template<class T> +inline const sc_unsigned_subref & +sc_unsigned_subref::operator = (const sc_generic_base<T> &a) +{ + sc_unsigned temp(length()); + a->to_sc_unsigned(temp); + return *this = temp; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_unsigned_bitref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref_r +// +// Proxy class for sc_unsigned part selection (r-value only). +// ---------------------------------------------------------------------------- + +// reduce methods + +inline bool +sc_unsigned_subref_r::and_reduce() const +{ + const sc_unsigned *target_p = m_obj_p; + for (int i = m_right; i <= m_left; i++) + if (!target_p->test(i)) + return false; + return true; +} + +inline bool +sc_unsigned_subref_r::nand_reduce() const +{ + return !and_reduce(); +} + +inline bool +sc_unsigned_subref_r::or_reduce() const +{ + const sc_unsigned *target_p = m_obj_p; + for (int i = m_right; i <= m_left; i++) + if (target_p->test(i)) + return true; + return false; +} + +inline bool +sc_unsigned_subref_r::nor_reduce() const +{ + return !or_reduce(); +} + +inline bool +sc_unsigned_subref_r::xor_reduce() const +{ + int odd; + const sc_unsigned *target_p = m_obj_p; + odd = 0; + for (int i = m_right; i <= m_left; i++) + if (target_p->test(i)) odd = ~odd; + return odd ? true : false; +} + +inline bool sc_unsigned_subref_r::xnor_reduce() const { return !xor_reduce(); } + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_unsigned_subref_r &a) +{ + a.print(os); + return os; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned_subref +// +// Proxy class for sc_unsigned part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators + +inline const sc_unsigned_subref & +sc_unsigned_subref::operator = (const char *a) +{ + sc_unsigned aa(length()); + return (*this = aa = a); +} + + +inline ::std::istream & +operator >> (::std::istream &is, sc_unsigned_subref &a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_unsigned +// +// Arbitrary precision signed number. +// ---------------------------------------------------------------------------- + +template<class T> +sc_unsigned::sc_unsigned( const sc_generic_base<T> &v) +{ + int nb = v->length(); + sgn = default_sign(); + if (nb > 0) { + nbits = num_bits(nb); + } else { + invalid_init("sc_generic_base<T>", nb); + sc_core::sc_abort(); // can't recover from here + } + ndigits = DIV_CEIL(nbits); +# ifdef SC_MAX_NBITS + test_bound(nb); +# else + digit = new sc_digit[ndigits]; +# endif + makezero(); + v->to_sc_unsigned(*this); +} + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_unsigned &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_unsigned &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__ |