diff options
Diffstat (limited to 'src/systemc/ext/dt/bit')
-rw-r--r-- | src/systemc/ext/dt/bit/_bit.hh | 42 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/_using.hh | 45 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_bit.hh | 381 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_bit_proxies.hh | 3419 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_bv.hh | 208 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_bv_base.hh | 282 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_logic.hh | 381 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_lv.hh | 205 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_lv_base.hh | 1589 | ||||
-rw-r--r-- | src/systemc/ext/dt/bit/sc_proxy.hh | 1394 |
10 files changed, 7946 insertions, 0 deletions
diff --git a/src/systemc/ext/dt/bit/_bit.hh b/src/systemc/ext/dt/bit/_bit.hh new file mode 100644 index 000000000..b549e2828 --- /dev/null +++ b/src/systemc/ext/dt/bit/_bit.hh @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __SYSTEMC_EXT_DT_BIT__BIT_HH__ +#define __SYSTEMC_EXT_DT_BIT__BIT_HH__ + +#include "sc_bit.hh" +#include "sc_bit_proxies.hh" +#include "sc_bv.hh" +#include "sc_bv_base.hh" +#include "sc_logic.hh" +#include "sc_lv.hh" +#include "sc_lv_base.hh" +#include "sc_proxy.hh" + +#endif //__SYSTEMC_EXT_DT_BIT__BIT_HH__ diff --git a/src/systemc/ext/dt/bit/_using.hh b/src/systemc/ext/dt/bit/_using.hh new file mode 100644 index 000000000..8bc747957 --- /dev/null +++ b/src/systemc/ext/dt/bit/_using.hh @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __SYSTEMC_EXT_DT_BIT__USING_HH__ +#define __SYSTEMC_EXT_DT_BIT__USING_HH__ + +#include "_bit.hh" + +using sc_dt::SC_LOGIC_0; +using sc_dt::SC_LOGIC_1; +using sc_dt::SC_LOGIC_X; +using sc_dt::SC_LOGIC_Z; +using sc_dt::sc_bit; +using sc_dt::sc_bv; +using sc_dt::sc_bv_base; +using sc_dt::sc_lv; +using sc_dt::sc_lv_base; + +#endif //__SYSTEMC_EXT_DT_BIT__USING_HH__ diff --git a/src/systemc/ext/dt/bit/sc_bit.hh b/src/systemc/ext/dt/bit/sc_bit.hh new file mode 100644 index 000000000..f4000a226 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_bit.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_bit.h -- Bit class. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bit.h,v $ +// Revision 1.2 2011/08/07 18:54:19 acg +// Philipp A. Hartmann: remove friend function declarations that implement +// code, and clean up how bit and logic operators are defined in general. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.6 2006/05/08 17:49:59 acg +// Andy Goodrich: Added David Long's declarations for friend operators, +// functions, and methods, to keep the Microsoft compiler happy. +// +// Revision 1.5 2006/04/12 20:17:52 acg +// Andy Goodrich: enabled deprecation message for sc_bit. +// +// Revision 1.4 2006/01/24 20:50:55 acg +// Andy Goodrich: added warnings indicating that sc_bit is deprecated and that +// the C bool data type should be used in its place. +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_BIT_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_BIT_HH__ + +#include <iostream> + +#include "../int/sc_nbdefs.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_bit; + +// forward class declarations +class sc_logic; + +extern void sc_deprecated_sc_bit(); + +// ---------------------------------------------------------------------------- +// CLASS : sc_bit +// +// Bit class. +// Note: VSIA compatibility indicated. +// ---------------------------------------------------------------------------- + +class sc_bit +{ + // support methods + + static void invalid_value(char); + static void invalid_value(int); + + static bool + to_value(char c) + { + if (c != '0' && c != '1') { + invalid_value(c); + } + return (c == '0' ? false : true); + } + + static bool + to_value(int i) + { + if (i != 0 && i != 1) { + invalid_value(i); + } + return (i == 0 ? false : true); + } + static bool to_value(bool b) { return b; } + +#define DEFN_TO_VALUE_T(tp) \ + static bool to_value(tp i) { return to_value((int)i); } + + DEFN_TO_VALUE_T(unsigned) + DEFN_TO_VALUE_T(long) + DEFN_TO_VALUE_T(unsigned long) + DEFN_TO_VALUE_T(int64) + DEFN_TO_VALUE_T(uint64) + +#undef DEFN_TO_VALUE_T + + public: + // constructors + // MANDATORY + sc_bit() : m_val(false) { sc_deprecated_sc_bit(); } + +#define DEFN_CTOR_T(tp) \ + explicit sc_bit(tp a) : m_val(to_value(a)) { sc_deprecated_sc_bit(); } + + DEFN_CTOR_T(bool) + DEFN_CTOR_T(char) + DEFN_CTOR_T(int) + DEFN_CTOR_T(unsigned) + DEFN_CTOR_T(long) + DEFN_CTOR_T(unsigned long) + DEFN_CTOR_T(int64) + DEFN_CTOR_T(uint64) + +#undef DEFN_CTOR_T + + explicit sc_bit(const sc_logic &a); // non-VSIA + + // copy constructor + // MANDATORY + sc_bit(const sc_bit &a) : m_val(a.m_val) {} + + // destructor + // MANDATORY + ~sc_bit() {} + + // assignment operators + // MANDATORY + sc_bit & + operator = (const sc_bit &b) + { + m_val = b.m_val; + return *this; + } + +#define DEFN_ASN_OP_T(op, tp) \ + sc_bit &operator op(tp b) { return (*this op sc_bit(b)); } +#define DEFN_ASN_OP(op) \ + DEFN_ASN_OP_T(op,int) \ + DEFN_ASN_OP_T(op,bool) \ + DEFN_ASN_OP_T(op,char) + + DEFN_ASN_OP(=) + DEFN_ASN_OP_T(=,int64) + DEFN_ASN_OP_T(=,uint64) + DEFN_ASN_OP_T(=,long) + DEFN_ASN_OP_T(=,unsigned long) + + sc_bit &operator = (const sc_logic &b); // non-VSIA + + // bitwise assignment operators + sc_bit & + operator &= (const sc_bit &b) + { + m_val = (m_val && b.m_val); + return *this; + } + + sc_bit & + operator |= (const sc_bit &b) + { + m_val = (m_val || b.m_val); + return *this; + } + + sc_bit & + operator ^= (const sc_bit &b) + { + m_val = (m_val != b.m_val); + return *this; + } + + DEFN_ASN_OP(&=) + DEFN_ASN_OP(|=) + DEFN_ASN_OP(^=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + // conversions + // MANDATORY + + // implicit conversion to bool + operator bool () const { return m_val; } + + // non-VSIA + bool operator ! () const { return !m_val; } + + + // explicit conversions - non-VSIA + bool to_bool() const { return m_val; } + char to_char() const { return (m_val ? '1' : '0'); } + + // relational operators and functions + // MANDATORY + friend bool operator == (const sc_bit &a, const sc_bit &b); + friend bool operator != (const sc_bit &a, const sc_bit &b); + + // bitwise operators and functions + + // bitwise complement + // MANDATORY + friend const sc_bit operator ~ (const sc_bit &a); + + // RECOMMENDED + sc_bit & + b_not() + { + m_val = (!m_val); + return *this; + } + + // binary bit-wise operations + friend const sc_bit operator | (const sc_bit &a, const sc_bit &b); + friend const sc_bit operator & (const sc_bit &a, const sc_bit &b); + friend const sc_bit operator ^ (const sc_bit &a, const sc_bit &b); + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_bool(); } + void scan(::std::istream & =::std::cin); + + private: + bool m_val; +}; + +// ---------------------------------------------------------------------------- +// relational operators and functions + +#define DEFN_BIN_FUN_T(ret,fun,tp) \ + inline ret fun(const sc_bit& a, tp b) { return fun(a, sc_bit(b)); } \ + inline ret fun(tp b, const sc_bit &a) { return fun(sc_bit(a), b); } + +#define DEFN_BIN_FUN(ret,fun) \ + DEFN_BIN_FUN_T(ret,fun,bool) \ + DEFN_BIN_FUN_T(ret,fun,char) \ + DEFN_BIN_FUN_T(ret,fun,int) + +// MANDATORY +inline bool +operator == (const sc_bit &a, const sc_bit &b) +{ + return (a.m_val == b.m_val); +} + +inline bool +operator != (const sc_bit &a, const sc_bit &b) +{ + return (a.m_val != b.m_val); +} + +DEFN_BIN_FUN(bool, operator ==) +DEFN_BIN_FUN(bool, operator !=) + +// OPTIONAL + +inline bool equal(const sc_bit &a, const sc_bit &b) { return (a == b); } + +inline bool not_equal(const sc_bit &a, const sc_bit &b) { return (a != b); } + +DEFN_BIN_FUN(bool,equal) +DEFN_BIN_FUN(bool,not_equal) + +// ---------------------------------------------------------------------------- +// bitwise operators and functions + +// bitwise complement + +// MANDATORY +inline const sc_bit operator ~ (const sc_bit &a) { return sc_bit(!a.m_val); } + +// OPTIONAL +inline const sc_bit b_not(const sc_bit &a) { return (~a); } + +// RECOMMENDED +inline void b_not(sc_bit &r, const sc_bit &a) { r = (~a); } + +// binary bit-wise operations +// MANDATORY +inline const sc_bit +operator & (const sc_bit &a, const sc_bit &b) +{ + return sc_bit(a.m_val && b.m_val); +} + +inline const sc_bit +operator | (const sc_bit &a, const sc_bit &b) +{ + return sc_bit(a.m_val || b.m_val); +} + +inline const sc_bit +operator ^ (const sc_bit &a, const sc_bit &b) +{ + return sc_bit(a.m_val != b.m_val); +} + +DEFN_BIN_FUN(const sc_bit,operator&) +DEFN_BIN_FUN(const sc_bit,operator|) +DEFN_BIN_FUN(const sc_bit,operator^) + +// OPTIONAL +inline const sc_bit b_and(const sc_bit &a, const sc_bit &b) { return a & b; } +inline const sc_bit b_or(const sc_bit &a, const sc_bit &b) { return a | b; } +inline const sc_bit b_xor(const sc_bit &a, const sc_bit &b) { return a ^ b; } + +DEFN_BIN_FUN(const sc_bit,b_and) +DEFN_BIN_FUN(const sc_bit,b_or) +DEFN_BIN_FUN(const sc_bit,b_xor) + +// RECOMMENDED + +#define DEFN_TRN_FUN_T(fun,tp) \ + inline void \ + fun(sc_bit &r, const sc_bit &a, tp b) \ + { r = fun(a, sc_bit(b)); } \ + inline void \ + fun(sc_bit &r, tp a, const sc_bit &b) \ + { r = fun(sc_bit(a), b); } + +#define DEFN_TRN_FUN(fun) \ + inline void \ + fun(sc_bit &r, const sc_bit &a, const sc_bit &b) { r = fun(a , b); } \ + DEFN_TRN_FUN_T(fun, int) \ + DEFN_TRN_FUN_T(fun, bool) \ + DEFN_TRN_FUN_T(fun, char) + + DEFN_TRN_FUN(b_and) + DEFN_TRN_FUN(b_or) + DEFN_TRN_FUN(b_xor) + +#undef DEFN_BIN_FUN_T +#undef DEFN_BIN_FUN +#undef DEFN_TRN_FUN_T +#undef DEFN_TRN_FUN + + +// ---------------------------------------------------------------------------- + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_bit &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_bit &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_BIT_HH__ diff --git a/src/systemc/ext/dt/bit/sc_bit_proxies.hh b/src/systemc/ext/dt/bit/sc_bit_proxies.hh new file mode 100644 index 000000000..0eec8aac0 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_bit_proxies.hh @@ -0,0 +1,3419 @@ +/***************************************************************************** + + 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_bit_proxies.h -- Proxy classes for vector data types. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + CHANGE LOG AT THE END OF THE FILE + *****************************************************************************/ + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__ + +#include <iostream> + +#include "sc_proxy.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <class X, class Traits> +class sc_bitref_conv_r; +template <class X> +class sc_bitref_r; +template <class X> +class sc_bitref; +template <class X> +class sc_subref_r; +template <class X> +class sc_subref; +template <class X, class Y> +class sc_concref_r; +template <class X, class Y> +class sc_concref; + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_conv_r<T> +// +// Proxy class for sc_proxy bit selection (r-value only, boolean conversion). +// ---------------------------------------------------------------------------- +template <class T, class Traits=typename T::traits_type> +class sc_bitref_conv_r { /* empty by default */ }; + +// specialization for bit-vector based sc_proxy classes +template<typename T> +class sc_bitref_conv_r<T, sc_proxy_traits<sc_bv_base> > +{ + public: +#if __cplusplus >= 201103L // explicit operator needs C++11 + // explicit conversion to bool + explicit operator bool() const + { + return static_cast<const sc_bitref_r<T> &>(*this).to_bool(); + } +#endif + + // explicit (negating) conversion to bool + bool + operator ! () const + { + return !static_cast<const sc_bitref_r<T> &>(*this).to_bool(); + } +}; + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<T> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class T> +class sc_bitref_r : public sc_bitref_conv_r<T> +{ + friend class sc_bv_base; + friend class sc_lv_base; + + public: + // typedefs + typedef typename T::traits_type traits_type; + typedef typename traits_type::bit_type bit_type; + typedef typename traits_type::value_type value_type; + + // constructor + sc_bitref_r(const T &obj_, int index_) : + m_obj(const_cast<T &>(obj_)), m_index(index_) + {} + + // copy constructor + sc_bitref_r(const sc_bitref_r<T> &a) : m_obj(a.m_obj), m_index(a.m_index) + {} + + // cloning + sc_bitref_r<T> *clone() const { return new sc_bitref_r<T>(*this); } + + // bitwise operators and functions + + // bitwise complement + bit_type + operator ~ () const + { + return bit_type(sc_logic::not_table[value()]); + } + + // implicit conversion to bit_type + operator bit_type() const { return bit_type(m_obj.get_bit(m_index)); } + + // explicit conversions + value_type value() const { return m_obj.get_bit(m_index); } + bool is_01() const { return sc_logic(value()).is_01(); } + bool to_bool() const { return sc_logic(value()).to_bool(); } + char to_char() const { return sc_logic(value()).to_char(); } + + // common methods + int length() const { return 1; } + int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } + + value_type get_bit(int n) const; + + sc_digit get_word(int i) const; + sc_digit get_cword(int i) const; + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_char(); } + + protected: + T &m_obj; + int m_index; + + private: + // Disabled + sc_bitref_r(); + sc_bitref_r<T> &operator = (const sc_bitref_r<T> &); +}; + +// bitwise operators and functions + +// bitwise and +template <class T1, class T2> +inline sc_logic operator & ( + const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b); + + +// bitwise or +template <class T1, class T2> +inline sc_logic operator | ( + const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b); + +// bitwise xor +template <class T1, class T2> +inline sc_logic operator ^ ( + const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b); + +// relational operators and functions +template <class T1, class T2> +inline bool operator == (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b); + +template <class T1, class T2> +inline bool operator != (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b); + +// r-value concatenation operators and functions +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_bitref_r<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , ( + sc_bitref_r<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > operator , ( + sc_bitref_r<T1>, sc_concref_r<T2,T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> operator , ( + sc_bitref_r<T1>, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref_r<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + const char *, sc_bitref_r<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref_r<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + const sc_logic &, sc_bitref_r<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref_r<T>, bool); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + bool, sc_bitref_r<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat( + sc_bitref_r<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat( + sc_bitref_r<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > concat( + sc_bitref_r<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> concat( + sc_bitref_r<T1>, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat( + sc_bitref_r<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat( + const char *, sc_bitref_r<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat( + sc_bitref_r<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat( + const sc_logic &, sc_bitref_r<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat( + sc_bitref_r<T>, bool); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat( + bool, sc_bitref_r<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_bitref_r<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_bitref<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , ( + sc_bitref_r<T1>, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , ( + sc_bitref<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > operator , ( + sc_bitref_r<T1>, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > operator , ( + sc_bitref<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> operator , ( + sc_bitref<T1>, const sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> operator , ( + sc_bitref_r<T1>, sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + const char *, sc_bitref<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + const sc_logic &, sc_bitref<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , ( + sc_bitref<T>, bool); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , ( + bool, sc_bitref<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat( + sc_bitref_r<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat( + sc_bitref<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat( + sc_bitref_r<T1>, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat( + sc_bitref<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > concat( + sc_bitref_r<T1>, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > concat( + sc_bitref<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> concat( + sc_bitref<T1>, const sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> concat( + sc_bitref_r<T1>, sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat( + sc_bitref<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat( + const char *, sc_bitref<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat( + sc_bitref<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat( + const sc_logic &, sc_bitref<T>); + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(sc_bitref<T>, bool); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(bool, sc_bitref<T>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref<X> +// +// Proxy class for sc_proxy bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_bitref : public sc_bitref_r<X> +{ + friend class sc_bv_base; + friend class sc_lv_base; + + public: + typedef typename sc_bitref_r<X>::value_type value_type; + + // constructor + sc_bitref(X &obj_, int index_) : sc_bitref_r<X>(obj_, index_) {} + + // copy constructor + sc_bitref(const sc_bitref<X> &a) : sc_bitref_r<X>(a) {} + + // cloning + sc_bitref<X> *clone() const { return new sc_bitref<X>(*this); } + + // assignment operators + sc_bitref<X> &operator = (const sc_bitref_r<X> &a); + sc_bitref<X> &operator = (const sc_bitref<X> &a); + + sc_bitref<X> & + operator = (const sc_logic &a) + { + this->m_obj.set_bit(this->m_index, a.value()); + return *this; + } + + sc_bitref<X> & + operator = (sc_logic_value_t v) + { + *this = sc_logic(v); + return *this; + } + + sc_bitref<X> & + operator = (bool a) + { + *this = sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator = (char a) + { + *this = sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator = (int a) + { + *this = sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator = (const sc_bit &a) + { + *this = sc_logic(a); + return *this; + } + + // bitwise assignment operators + sc_bitref<X> &operator &= (const sc_bitref_r<X> &a); + sc_bitref<X> &operator &= (const sc_logic &a); + + sc_bitref<X> & + operator &= (sc_logic_value_t v) + { + *this &= sc_logic(v); + return *this; + } + + sc_bitref<X> & + operator &= (bool a) + { + *this &= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator &= (char a) + { + *this &= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator &= (int a) + { + *this &= sc_logic(a); + return *this; + } + + sc_bitref<X> &operator |= (const sc_bitref_r<X> &a); + sc_bitref<X> &operator |= (const sc_logic &a); + + sc_bitref<X> & + operator |= (sc_logic_value_t v) + { + *this |= sc_logic(v); + return *this; + } + + sc_bitref<X> & + operator |= (bool a) + { + *this |= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator |= (char a) + { + *this |= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator |= (int a) + { + *this |= sc_logic(a); + return *this; + } + + sc_bitref<X> &operator ^= (const sc_bitref_r<X> &a); + sc_bitref<X> &operator ^= (const sc_logic &a); + + sc_bitref<X> & + operator ^= (sc_logic_value_t v) + { + *this ^= sc_logic(v); + return *this; + } + + sc_bitref<X> & + operator ^= (bool a) + { + *this ^= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator ^= (char a) + { + *this ^= sc_logic(a); + return *this; + } + + sc_bitref<X> & + operator ^= (int a) + { + *this ^= sc_logic(a); + return *this; + } + + // bitwise operators and functions + + // bitwise complement + sc_bitref<X> &b_not(); + + // common methods + void set_bit(int n, value_type value); + + void set_word(int i, sc_digit w); + void set_cword(int i, sc_digit w); + + void clean_tail() { this->m_obj.clean_tail(); } + + // other methods + void scan(::std::istream &is=::std::cin); + + private: + // Disabled + sc_bitref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > operator , ( + sc_bitref<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_subref<T2> > operator , ( + sc_bitref<T1>, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> > operator , ( + sc_bitref<T1>, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, T2> operator , ( + sc_bitref<T1>, sc_proxy<T2> &); + + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > concat( + sc_bitref<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_subref<T2> > concat( + sc_bitref<T1>, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_bitref<T1>, sc_concref<T2,T3> > concat( + sc_bitref<T1>, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, T2> concat(sc_bitref<T1>, sc_proxy<T2> &); + + +template <class T> +::std::istream &operator >> (::std::istream &, sc_bitref<T>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_subref_r : public sc_proxy<sc_subref_r<X> > +{ + void check_bounds(); + + public: + typedef typename sc_proxy<sc_subref_r<X> >::value_type value_type; + + // constructor + sc_subref_r(const X &obj_, int hi_, int lo_) : + m_obj(const_cast<X &>(obj_)), m_hi(hi_), m_lo(lo_), m_len(0) + { check_bounds(); } + + // copy constructor + sc_subref_r(const sc_subref_r<X> &a) : + m_obj(a.m_obj), m_hi(a.m_hi), m_lo(a.m_lo), m_len(a.m_len) + {} + + // cloning + sc_subref_r<X> *clone() const { return new sc_subref_r<X>(*this); } + + // common methods + int length() const { return m_len; } + + int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } + + value_type get_bit(int n) const; + void set_bit(int n, value_type value); + + sc_digit get_word(int i) const; + void set_word(int i, sc_digit w); + + sc_digit get_cword(int i) const; + void set_cword(int i, sc_digit w); + + void clean_tail() { m_obj.clean_tail(); } + + // other methods + bool is_01() const; + bool reversed() const { return m_lo > m_hi; } + + protected: + X &m_obj; + int m_hi; + int m_lo; + int m_len; + + private: + // Disabled + sc_subref_r(); + sc_subref_r<X> &operator = (const sc_subref_r<X> &); +}; + + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_subref_r<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , ( + sc_subref_r<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2,T3> > operator , ( + sc_subref_r<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> operator , ( + sc_subref_r<T1>, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_subref_r<T>,sc_lv_base> operator , ( + sc_subref_r<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , ( + const char *, sc_subref_r<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , ( + sc_subref_r<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , ( + const sc_logic &, sc_subref_r<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> operator , ( + sc_subref_r<T>, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > operator , ( + bool, sc_subref_r<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat( + sc_subref_r<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat( + sc_subref_r<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat( + sc_subref_r<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> concat( + sc_subref_r<T1>, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat( + sc_subref_r<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base,sc_subref_r<T> > concat( + const char *, sc_subref_r<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat( + sc_subref_r<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat( + const sc_logic &, sc_subref_r<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> concat(sc_subref_r<T>, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > concat(bool, sc_subref_r<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_subref_r<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , ( + sc_subref<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , ( + sc_subref_r<T1>, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , ( + sc_subref<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > operator , ( + sc_subref_r<T1>, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > operator , ( + sc_subref<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> operator , ( + sc_subref<T1>, const sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> operator , ( + sc_subref_r<T1>, sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , ( + sc_subref<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , ( + const char *, sc_subref<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , ( + sc_subref<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , ( + const sc_logic &, sc_subref<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> operator , ( + sc_subref<T>, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > operator , ( + bool, sc_subref<T>); + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat( + sc_subref_r<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat( + sc_subref<T1>, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat( + sc_subref_r<T1>, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat( + sc_subref<T1>, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat( + sc_subref_r<T1>, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat( + sc_subref<T1>, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> concat( + sc_subref<T1>, const sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> concat( + sc_subref_r<T1>, sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat( + sc_subref<T>, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat( + const char *, sc_subref<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat( + sc_subref<T>, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat( + const sc_logic &, sc_subref<T>); + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> concat(sc_subref<T>, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > concat(bool, sc_subref<T>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +class sc_subref : public sc_subref_r<X> +{ + public: + // typedefs + typedef sc_subref_r<X> base_type; + + // constructor + sc_subref(X &obj_, int hi_, int lo_) : sc_subref_r<X>(obj_, hi_, lo_) {} + + // copy constructor + sc_subref(const sc_subref<X> &a) : sc_subref_r<X>(a) {} + + // cloning + sc_subref<X> *clone() const { return new sc_subref<X>(*this); } + + // assignment operators + template <class Y> + sc_subref<X> & + operator = (const sc_proxy<Y> &a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> &operator = (const sc_subref_r<X> &a); + sc_subref<X> &operator = (const sc_subref<X> &a); + + sc_subref<X> & + operator = (const char *a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const bool *a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const sc_logic *a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const sc_unsigned &a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const sc_signed &a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const sc_uint_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (const sc_int_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (unsigned long a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (long a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (unsigned int a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (int a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (uint64 a) + { + base_type::assign_(a); + return *this; + } + + sc_subref<X> & + operator = (int64 a) + { + base_type::assign_(a); + return *this; + } + + // other methods + void scan(::std::istream & =::std::cin); + + private: + // Disabled + sc_subref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_bitref<T2> > operator , ( + sc_subref<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_subref<T2> > operator , ( + sc_subref<T1>, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> > operator , ( + sc_subref<T1>, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, T2> operator , ( + sc_subref<T1>, sc_proxy<T2> &); + + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_bitref<T2> > concat( + sc_subref<T1>, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_subref<T2> > concat( + sc_subref<T1>, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> > concat( + sc_subref<T1>, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, T2> concat(sc_subref<T1>, sc_proxy<T2> &); + + +template <class T> +inline ::std::istream &operator >> (::std::istream &, sc_subref<T>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +template <class X, class Y> +class sc_concref_r : public sc_proxy<sc_concref_r<X, Y> > +{ + public: + typedef typename sc_proxy<sc_concref_r<X, Y> >::value_type value_type; + + // constructor + sc_concref_r(const X &left_, const Y &right_, int delete_=0) : + m_left(const_cast<X &>(left_)), m_right(const_cast<Y &>(right_)), + m_delete(delete_), m_refs(*new int(1)) + {} + + // copy constructor + sc_concref_r(const sc_concref_r<X, Y> &a) : + m_left(a.m_left), m_right(a.m_right), + m_delete(a.m_delete), m_refs(a.m_refs) + { ++ m_refs; } + + // destructor + virtual ~sc_concref_r(); + + // cloning + sc_concref_r<X, Y> *clone() const { return new sc_concref_r<X, Y>(*this); } + + // common methods + int length() const { return (m_left.length() + m_right.length()); } + + int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); } + + value_type get_bit(int n) const; + void set_bit(int n, value_type value); + + sc_digit get_word(int i) const; + void set_word(int i, sc_digit w); + + sc_digit get_cword(int i) const; + void set_cword(int i, sc_digit w); + + void clean_tail() { m_left.clean_tail(); m_right.clean_tail(); } + + // other methods + bool is_01() const { return (m_left.is_01() && m_right.is_01()); } + + protected: + X &m_left; + Y &m_right; + mutable int m_delete; + int &m_refs; + + private: + // Disabled + sc_concref_r(); + sc_concref_r<X, Y> &operator = (const sc_concref_r<X, Y> &); +}; + + +// r-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> > operator , ( + sc_concref_r<T1, T2>, sc_bitref_r<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , ( + sc_concref_r<T1, T2>, sc_subref_r<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , ( + sc_concref_r<T1, T2>, sc_concref_r<T3, T4>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , ( + sc_concref_r<T1, T2>, const sc_proxy<T3> &); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , ( + sc_concref_r<T1, T2>, const char *); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , ( + const char *, sc_concref_r<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , ( + sc_concref_r<T1, T2>, const sc_logic &); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , ( + const sc_logic &, sc_concref_r<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> operator , ( + sc_concref_r<T1, T2>, bool); + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > operator , ( + bool, sc_concref_r<T1, T2>); + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat( + sc_concref_r<T1, T2>, sc_bitref_r<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat( + sc_concref_r<T1, T2>, sc_subref_r<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat( + sc_concref_r<T1, T2>, sc_concref_r<T3, T4>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat( + sc_concref_r<T1, T2>, const sc_proxy<T3> &); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat( + sc_concref_r<T1, T2>, const char *); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat( + const char *, sc_concref_r<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat( + sc_concref_r<T1, T2>, const sc_logic &); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat( + const sc_logic &, sc_concref_r<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> concat( + sc_concref_r<T1, T2>, bool); + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > concat( + bool, sc_concref_r<T1, T2>); + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > operator , ( + sc_concref_r<T1, T2>, sc_bitref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > operator , ( + sc_concref<T1, T2>, sc_bitref_r<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , ( + sc_concref_r<T1, T2>, sc_subref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , ( + sc_concref<T1, T2>, sc_subref_r<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , ( + sc_concref_r<T1, T2>, sc_concref<T3, T4>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , ( + sc_concref<T1, T2>, sc_concref_r<T3, T4>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , ( + sc_concref<T1, T2>, const sc_proxy<T3> &); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , ( + sc_concref_r<T1, T2>, sc_proxy<T3> &); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , ( + sc_concref<T1, T2>, const char *); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , ( + const char *, sc_concref<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , ( + sc_concref<T1, T2>, const sc_logic &); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , ( + const sc_logic &, sc_concref<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> operator , ( + sc_concref<T1, T2>, bool); + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > operator , ( + bool, sc_concref<T1, T2>); + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat( + sc_concref_r<T1, T2>, sc_bitref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat( + sc_concref<T1, T2>, sc_bitref_r<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat( + sc_concref_r<T1, T2>, sc_subref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat( + sc_concref<T1, T2>, sc_subref_r<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat( + sc_concref_r<T1, T2>, sc_concref<T3, T4>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat( + sc_concref<T1, T2>, sc_concref_r<T3, T4> ); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat( + sc_concref<T1, T2>, const sc_proxy<T3> &); + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat( + sc_concref_r<T1, T2>, sc_proxy<T3> &); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat( + sc_concref<T1, T2>, const char *); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat( + const char *, sc_concref<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat( + sc_concref<T1, T2>, const sc_logic &); + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat( + const sc_logic &, sc_concref<T1, T2>); + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> concat( + sc_concref<T1, T2>, bool); + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > concat( + bool, sc_concref<T1, T2>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X, class Y> +class sc_concref : public sc_concref_r<X, Y> +{ + public: + // typedefs + typedef sc_concref_r<X, Y> base_type; + + // constructor + sc_concref(X &left_, Y &right_, int delete_=0) : + sc_concref_r<X, Y>(left_, right_, delete_) + {} + + // copy constructor + sc_concref(const sc_concref<X, Y> &a) : sc_concref_r<X, Y>(a) {} + + // cloning + sc_concref<X, Y> *clone() const { return new sc_concref<X, Y>(*this); } + + // assignment operators + template <class Z> + sc_concref<X, Y> & + operator = (const sc_proxy<Z> &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_concref<X, Y> &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const char *a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const bool *a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_logic *a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_unsigned &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_signed &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_uint_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (const sc_int_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (unsigned long a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (long a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (unsigned int a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (int a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (uint64 a) + { + base_type::assign_(a); + return *this; + } + + sc_concref<X, Y> & + operator = (int64 a) + { + base_type::assign_(a); + return *this; + } + + // other methods + void scan(::std::istream & =::std::cin); + + private: + // Disabled + sc_concref(); +}; + + +// l-value concatenation operators and functions + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > operator , ( + sc_concref<T1, T2>, sc_bitref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > operator , ( + sc_concref<T1, T2>, sc_subref<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > operator , ( + sc_concref<T1, T2>, sc_concref<T3, T4>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, T3> operator , ( + sc_concref<T1, T2>, sc_proxy<T3> &); + + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > concat( + sc_concref<T1, T2>, sc_bitref<T3>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > concat( + sc_concref<T1, T2>, sc_subref<T3>); + +template <class T1, class T2, class T3, class T4> +inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > concat( + sc_concref<T1, T2>, sc_concref<T3, T4>); + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, T3> concat( + sc_concref<T1, T2>, sc_proxy<T3> &); + + +template <class T1, class T2> +inline ::std::istream &operator >> (::std::istream &, sc_concref<T1, T2>); + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > operator , ( + const sc_proxy<T1> &, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > operator , ( + const sc_proxy<T1> &, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , ( + const sc_proxy<T1> &, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> operator , ( + const sc_proxy<T1> &, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> operator , ( + const sc_proxy<T> &, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base,T> operator , ( + const char *, const sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> operator , ( + const sc_proxy<T> &, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, T> operator , ( + const sc_logic &, const sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_bv_base> operator , (const sc_proxy<T> &, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, T> operator , (bool, const sc_proxy<T> &); + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > concat( + const sc_proxy<T1> &, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > concat( + const sc_proxy<T1> &, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat( + const sc_proxy<T1> &, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> concat(const sc_proxy<T1> &, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> concat(const sc_proxy<T> &, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, T> concat(const char *, const sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> concat( + const sc_proxy<T> &, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, T> concat( + const sc_logic &, const sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_bv_base> concat(const sc_proxy<T> &, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, T> concat(bool, const sc_proxy<T> &); + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > operator , ( + const sc_proxy<T1> &, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > operator , ( + sc_proxy<T1> &, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > operator , ( + const sc_proxy<T1> &, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > operator , ( + sc_proxy<T1> &, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , ( + const sc_proxy<T1> &, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , ( + sc_proxy<T1> &, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> operator , (const sc_proxy<T1> &, sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> operator , (sc_proxy<T1> &, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> operator , (sc_proxy<T> &, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, T> operator , (const char *, sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> operator , ( + sc_proxy<T> &, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, T> operator , ( + const sc_logic &, sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_bv_base> operator , (sc_proxy<T> &, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, T> operator , (bool, sc_proxy<T> &); + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > concat( + const sc_proxy<T1> &, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > concat( + sc_proxy<T1> &, sc_bitref_r<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > concat( + const sc_proxy<T1> &, sc_subref<T2>); + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > concat( + sc_proxy<T1> &, sc_subref_r<T2>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat( + const sc_proxy<T1> &, sc_concref<T2, T3>); + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat( + sc_proxy<T1> &, sc_concref_r<T2, T3>); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> concat(const sc_proxy<T1> &, sc_proxy<T2> &); + +template <class T1, class T2> +inline sc_concref_r<T1, T2> concat(sc_proxy<T1> &, const sc_proxy<T2> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> concat(sc_proxy<T> &, const char *); + +template <class T> +inline sc_concref_r<sc_lv_base, T> concat(const char *, sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_lv_base> concat(sc_proxy<T> &, const sc_logic &); + +template <class T> +inline sc_concref_r<sc_lv_base, T> concat(const sc_logic &, sc_proxy<T> &); + +template <class T> +inline sc_concref_r<T, sc_bv_base> concat(sc_proxy<T> &, bool); + +template <class T> +inline sc_concref_r<sc_bv_base, T> concat(bool, sc_proxy<T> &); + + +// l-value concatenation operators and functions +template <class T1, class T2> +inline sc_concref<T1,sc_bitref<T2> > operator , ( + sc_proxy<T1> &, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<T1, sc_subref<T2> > operator , ( + sc_proxy<T1> &, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<T1, sc_concref<T2, T3> > operator , ( + sc_proxy<T1> &, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<T1, T2> operator , (sc_proxy<T1> &, sc_proxy<T2> &); + + +template <class T1, class T2> +inline sc_concref<T1, sc_bitref<T2> > concat(sc_proxy<T1> &, sc_bitref<T2>); + +template <class T1, class T2> +inline sc_concref<T1, sc_subref<T2> > concat(sc_proxy<T1> &, sc_subref<T2>); + +template <class T1, class T2, class T3> +inline sc_concref<T1, sc_concref<T2, T3> > concat( + sc_proxy<T1> &, sc_concref<T2, T3>); + +template <class T1, class T2> +inline sc_concref<T1, T2> concat(sc_proxy<T1> &, sc_proxy<T2> &); + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<T> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise and +template <class T1, class T2> +inline sc_logic +operator & (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b) +{ + return sc_logic(sc_logic::and_table[a.value()][b.value()]); +} + +// bitwise or +template <class T1, class T2> +inline sc_logic +operator | (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b) +{ + return sc_logic(sc_logic::or_table[a.value()][b.value()]); +} + +// bitwise xor +template <class T1, class T2> +inline sc_logic +operator ^ (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b) +{ + return sc_logic(sc_logic::xor_table[a.value()][b.value()]); +} + +// relational operators and functions +template <class T1, class T2> +inline bool +operator == (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b) +{ + return ((int)a.value() == b.value()); +} + +template <class T1, class T2> +inline bool +operator != (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b) +{ + return ((int)a.value() != b.value()); +} + +// common methods +template <class T> +inline typename sc_bitref_r<T>::value_type +sc_bitref_r<T>::get_bit(int n) const +{ + if (n == 0) { + return m_obj.get_bit(m_index); + } else { + SC_REPORT_ERROR("out of bounds", 0); + return Log_0; + } +} + +template <class T> +inline sc_digit +sc_bitref_r<T>::get_word(int n) const +{ + if (n == 0) { + return (get_bit(n) & SC_DIGIT_ONE); + } else { + SC_REPORT_ERROR("out of bounds", 0); + return 0; + } +} + +template <class T> +inline sc_digit +sc_bitref_r<T>::get_cword(int n) const +{ + if (n == 0) { + return ((get_bit(n) & SC_DIGIT_TWO) >> 1); + } else { + SC_REPORT_ERROR("out of bounds", 0); + return 0; + } +} + +// r-value concatenation operators and functions +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +operator , (sc_bitref_r<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +operator , (sc_bitref_r<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_bitref_r<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +operator , (sc_bitref_r<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline +sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +concat(sc_bitref_r<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +concat(sc_bitref_r<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_bitref_r<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +concat(sc_bitref_r<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +operator , (sc_bitref_r<T1> a, sc_bitref<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +operator , (sc_bitref<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +operator , (sc_bitref_r<T1> a, sc_subref<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +operator , (sc_bitref<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_bitref_r<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_bitref<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +operator , (sc_bitref<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>( + *a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +operator , (sc_bitref_r<T1> a, sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +concat(sc_bitref_r<T1> a, sc_bitref<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > +concat(sc_bitref<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +concat(sc_bitref_r<T1> a, sc_subref<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > +concat(sc_bitref<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_bitref_r<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_bitref<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +concat(sc_bitref<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bitref_r<T1>, T2> +concat(sc_bitref_r<T1> a, sc_proxy<T2> &b) +{ + return sc_concref_r<sc_bitref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref<X> +// +// Proxy class for sc_proxy bit selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator = (const sc_bitref_r<X> &a) +{ + this->m_obj.set_bit(this->m_index, a.value()); + return *this; +} + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator = (const sc_bitref<X> &a) +{ + if (&a != this) { + this->m_obj.set_bit(this->m_index, a.value()); + } + return *this; +} + + +// bitwise assignment operators +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator &= (const sc_bitref_r<X> &a) +{ + if (&a != this) { + this->m_obj.set_bit( + this->m_index, sc_logic::and_table[this->value()][a.value()]); + } + return *this; +} + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator &= (const sc_logic &a) +{ + this->m_obj.set_bit( + this->m_index, sc_logic::and_table[this->value()][a.value()]); + return *this; +} + + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator |= (const sc_bitref_r<X> &a) +{ + if (&a != this) { + this->m_obj.set_bit( + this->m_index, sc_logic::or_table[this->value()][a.value()]); + } + return *this; +} + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator |= (const sc_logic &a) +{ + this->m_obj.set_bit( + this->m_index, sc_logic::or_table[this->value()][a.value()]); + return *this; +} + + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator ^= (const sc_bitref_r<X> &a) +{ + if (&a != this) { + this->m_obj.set_bit( + this->m_index, sc_logic::xor_table[this->value()][a.value()]); + } + return *this; +} + +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::operator ^= (const sc_logic &a) +{ + this->m_obj.set_bit( + this->m_index, sc_logic::xor_table[this->value()][a.value()]); + return *this; +} + +// bitwise operators and functions + +// bitwise complement +template <class X> +inline sc_bitref<X> & +sc_bitref<X>::b_not() +{ + this->m_obj.set_bit(this->m_index, sc_logic::not_table[this->value()]); + return *this; +} + +// common methods +template <class X> +inline void +sc_bitref<X>::set_bit(int n, value_type value) +{ + if (n == 0) { + this->m_obj.set_bit(this->m_index, value); + } else { + SC_REPORT_ERROR("out of bounds", 0); + } +} + +template <class X> +inline void +sc_bitref<X>::set_word(int n, sc_digit w) +{ + unsigned int bi = this->m_index % (8 * sizeof(sc_digit)); + sc_digit temp; + unsigned int wi = this->m_index / (8 * sizeof(sc_digit)); + if (n == 0) { + temp = this->m_obj.get_word(wi); + temp = (temp & ~(1 << bi)) | ((w & 1) << bi); + this->m_obj.set_word(wi, temp); + } else { + SC_REPORT_ERROR("out of bounds", 0); + } +} + +template <class X> +inline void +sc_bitref<X>::set_cword(int n, sc_digit w) +{ + unsigned int bi = this->m_index % (8 * sizeof(sc_digit)); + sc_digit temp; + unsigned int wi = this->m_index / (8 * sizeof(sc_digit)); + if (n == 0) { + temp = this->m_obj.get_cword(wi); + temp = (temp & ~(1 << bi)) | ((w & 1) << bi); + this->m_obj.set_cword(wi, temp); + } else { + SC_REPORT_ERROR("out of bounds", 0); + } +} + +// other methods +template <class X> +inline void +sc_bitref<X>::scan(::std::istream &is) +{ + char c; + is >> c; + *this = c; +} + +// l-value concatenation operators and functions +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > +operator , (sc_bitref<T1> a, sc_bitref<T2> b) +{ + return sc_concref<sc_bitref<T1>, sc_bitref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_subref<T2> > +operator , (sc_bitref<T1> a, sc_subref<T2> b) +{ + return sc_concref<sc_bitref<T1>, sc_subref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> > +operator , (sc_bitref<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref<sc_bitref<T1>, sc_concref<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, T2> +operator , (sc_bitref<T1> a, sc_proxy<T2> &b) +{ + return sc_concref<sc_bitref<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > +concat(sc_bitref<T1> a, sc_bitref<T2> b) +{ + return sc_concref<sc_bitref<T1>, sc_bitref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, sc_subref<T2> > +concat(sc_bitref<T1> a, sc_subref<T2> b) +{ + return sc_concref<sc_bitref<T1>, sc_subref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> > +concat(sc_bitref<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref<sc_bitref<T1>, sc_concref<T2,T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_bitref<T1>, T2> +concat(sc_bitref<T1> a, sc_proxy<T2> &b) +{ + return sc_concref<sc_bitref<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + +template <class X> +inline ::std::istream & +operator >> (::std::istream &is, sc_bitref<X> a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +template <class X> +inline void +sc_subref_r<X>::check_bounds() +{ + int len = m_obj.length(); + if (m_hi < 0 || m_hi >= len || m_lo < 0 || m_lo >= len) { + SC_REPORT_ERROR("out of bounds", 0); + sc_core::sc_abort(); // can't recover from here + } + if (reversed()) { + m_len = m_lo - m_hi + 1; + } else { + m_len = m_hi - m_lo + 1; + } +} + +// common methods +template <class X> +inline typename sc_subref_r<X>::value_type +sc_subref_r<X>::get_bit(int n) const +{ + if (reversed()) { + return m_obj.get_bit(m_lo - n); + } else { + return m_obj.get_bit(m_lo + n); + } +} + +template <class X> +inline void +sc_subref_r<X>::set_bit(int n, value_type value) +{ + if (reversed()) { + m_obj.set_bit(m_lo - n, value); + } else { + m_obj.set_bit(m_lo + n, value); + } +} + +template <class X> +inline sc_digit +sc_subref_r<X>::get_word(int i) const +{ + int n1 = 0; + int n2 = 0; + sc_digit result = 0; + int k = 0; + if (reversed()) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); + for (int n = n1; n > n2; n--) { + result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++; + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); + for (int n = n1; n < n2; n++) { + result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++; + } + } + return result; +} + +template <class X> +inline void +sc_subref_r<X>::set_word(int i, sc_digit w) +{ + int n1 = 0; + int n2 = 0; + int k = 0; + if (reversed()) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); + for (int n = n1; n > n2; n--) { + m_obj.set_bit(n, value_type( + ((w >> k++) & SC_DIGIT_ONE) | + (m_obj[n].value() & SC_DIGIT_TWO))); + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); + for (int n = n1; n < n2; n++) { + m_obj.set_bit(n, value_type( + ((w >> k++) & SC_DIGIT_ONE) | + (m_obj[n].value() & SC_DIGIT_TWO))); + } + } +} + + +template <class X> +inline sc_digit +sc_subref_r<X>::get_cword(int i) const +{ + int n1 = 0; + int n2 = 0; + sc_digit result = 0; + int k = 0; + if (reversed()) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); + for (int n = n1; n > n2; n--) { + result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++; + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); + for (int n = n1; n < n2; n++) { + result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++; + } + } + return result; +} + +template <class X> +inline void +sc_subref_r<X>::set_cword(int i, sc_digit w) +{ + int n1 = 0; + int n2 = 0; + int k = 0; + if (reversed()) { + n1 = m_lo - i * SC_DIGIT_SIZE; + n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1); + for (int n = n1; n > n2; n--) { + m_obj.set_bit(n, value_type( + (((w >> k++) & SC_DIGIT_ONE) << 1) | + (m_obj[n].value() & SC_DIGIT_ONE))); + } + } else { + n1 = m_lo + i * SC_DIGIT_SIZE; + n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1); + for (int n = n1; n < n2; n++) { + m_obj.set_bit(n, value_type( + (((w >> k++) & SC_DIGIT_ONE) << 1) | + (m_obj[n].value() & SC_DIGIT_ONE))); + } + } +} + +// other methods +template <class X> +inline bool +sc_subref_r<X>::is_01() const +{ + int sz = size(); + for (int i = 0; i < sz; ++i) { + if (get_cword(i) != SC_DIGIT_ZERO) { + return false; + } + } + return true; +} + +// r-value concatenation operators and functions +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +operator , (sc_subref_r<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +operator , (sc_subref_r<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_subref_r<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +operator , (sc_subref_r<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +concat(sc_subref_r<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +concat(sc_subref_r<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_subref_r<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +concat(sc_subref_r<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +operator , (sc_subref_r<T1> a, sc_bitref<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +operator , (sc_subref<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +operator , (sc_subref_r<T1> a, sc_subref<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +operator , (sc_subref<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_subref_r<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +operator , (sc_subref<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +operator , (sc_subref<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +operator , (sc_subref_r<T1> a, sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +concat(sc_subref_r<T1> a, sc_bitref<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > +concat(sc_subref<T1> a, sc_bitref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +concat(sc_subref_r<T1> a, sc_subref<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > +concat(sc_subref<T1> a, sc_subref_r<T2> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_subref_r<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > +concat(sc_subref<T1> a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +concat(sc_subref<T1> a, const sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2> +inline sc_concref_r<sc_subref_r<T1>, T2> +concat(sc_subref_r<T1> a, sc_proxy<T2> &b) +{ + return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +// assignment operators +// sc_subref<X>::operator = ( const sc_subref_r<X>& ) in sc_lv_base.h +// sc_subref<X>::operator = ( const sc_subref<X>& ) in sc_lv_base.h + +// other methods +template <class T> +inline void +sc_subref<T>::scan(::std::istream &is) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +// l-value concatenation operators and functions +template <class T1, class T2> +inline +sc_concref<sc_subref<T1>, sc_bitref<T2> > +operator , (sc_subref<T1> a, sc_bitref<T2> b) +{ + return sc_concref<sc_subref<T1>, sc_bitref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_subref<T2> > +operator , (sc_subref<T1> a, sc_subref<T2> b) +{ + return sc_concref<sc_subref<T1>, sc_subref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_subref<T1>, sc_concref<T2,T3> > +operator , (sc_subref<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref<sc_subref<T1>, sc_concref<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, T2> +operator , (sc_subref<T1> a, sc_proxy<T2> &b) +{ + return sc_concref<sc_subref<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_bitref<T2> > +concat(sc_subref<T1> a, sc_bitref<T2> b) +{ + return sc_concref<sc_subref<T1>, sc_bitref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, sc_subref<T2> > +concat(sc_subref<T1> a, sc_subref<T2> b) +{ + return sc_concref<sc_subref<T1>, sc_subref<T2> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> > +concat(sc_subref<T1> a, sc_concref<T2, T3> b) +{ + return sc_concref<sc_subref<T1>, sc_concref<T2, T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref<sc_subref<T1>, T2> +concat(sc_subref<T1> a, sc_proxy<T2> &b) +{ + return sc_concref<sc_subref<T1>, T2>(*a.clone(), b.back_cast(), 1); +} + +template <class X> +inline ::std::istream & +operator >> (::std::istream &is, sc_subref<X> a) +{ + a.scan(is); + return is; +} + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +// destructor +template <class X, class Y> +inline sc_concref_r<X, Y>::~sc_concref_r() +{ + if (--m_refs == 0) { + delete &m_refs; + if (m_delete == 0) { + return; + } + if (m_delete & 1) { + delete &m_left; + } + if (m_delete & 2) { + delete &m_right; + } + } +} + +// common methods +template <class X, class Y> +inline typename sc_concref_r<X, Y>::value_type +sc_concref_r<X, Y>::get_bit(int n) const +{ + int r_len = m_right.length(); + if (n < r_len) { + return value_type(m_right.get_bit(n)); + } else if (n < r_len + m_left.length()) { + return value_type(m_left.get_bit(n - r_len)); + } else { + SC_REPORT_ERROR("out of bounds", 0); + return Log_0; + } +} + +template <class X, class Y> +inline void +sc_concref_r<X, Y>::set_bit(int n, value_type v) +{ + int r_len = m_right.length(); + if (n < r_len) { + m_right.set_bit(n, typename Y::value_type(v)); + } else if (n < r_len + m_left.length()) { + m_left.set_bit(n - r_len, typename X::value_type(v)); + } else { + SC_REPORT_ERROR("out of bounds", 0); + } +} + +template <class X, class Y> +inline sc_digit +sc_concref_r<X, Y>::get_word(int i) const +{ + if (i < 0 || i >= size()) { + SC_REPORT_ERROR("out of bounds", 0); + } + // 0 <= i < size() + Y &r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if (i < border) { + return r.get_word(i); + } + // border <= i < size() + X& l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if (shift == 0) { + return l.get_word(j); + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + if (i == border) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + return ((r.get_word(i) & rl_mask) | (l.get_word(0) << shift)); + } + // border < i < size() && shift != 0 + if (j < l.size()) + return ((l.get_word(j - 1) >> nshift) | (l.get_word(j) << shift)); + else + return (l.get_word(j - 1) >> nshift); +} + +template <class X, class Y> +inline void +sc_concref_r<X, Y>::set_word(int i, sc_digit w) +{ + if (i < 0 || i >= size()) { + SC_REPORT_ERROR("out of bounds", 0); + } + // 0 <= i < size() + Y &r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if (i < border) { + r.set_word(i, w); + return; + } + // border <= i < size() + X &l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if (shift == 0) { + l.set_word(j, w); + return; + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; + if (i == border) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + r.set_word(i, w & rl_mask); + l.set_word(0, (l.get_word(0) & lh_mask) | (w >> shift)); + return; + } + // border < i < size() && shift != 0 + sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; + l.set_word(j - 1, (l.get_word(j - 1) & ll_mask) | (w << nshift)); + if (j < l.size()) + l.set_word(j, (l.get_word(j) & lh_mask) | (w >> shift)); +} + +template <class X, class Y> +inline sc_digit +sc_concref_r<X, Y>::get_cword(int i) const +{ + if (i < 0 || i >= size()) { + SC_REPORT_ERROR("out of bounds", 0); + } + // 0 <= i < size() + Y &r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if (i < border) { + return r.get_cword(i); + } + // border <= i < size() + X &l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if (shift == 0) { + return l.get_cword(j); + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + if (i == border) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + return ((r.get_cword(i) & rl_mask) | (l.get_cword(0) << shift)); + } + // border < i < size() && shift != 0 + if (j < l.size()) + return ((l.get_cword(j - 1) >> nshift) | (l.get_cword(j) << shift)); + else + return (l.get_cword( j - 1 ) >> nshift); +} + +template <class X, class Y> +inline void +sc_concref_r<X, Y>::set_cword(int i, sc_digit w) +{ + if (i < 0 || i >= size()) { + SC_REPORT_ERROR("out of bounds", 0); + } + // 0 <= i < size() + Y &r = m_right; + int r_len = r.length(); + int border = r_len / SC_DIGIT_SIZE; + if (i < border) { + r.set_cword(i, w); + return; + } + // border <= i < size() + X &l = m_left; + int shift = r_len % SC_DIGIT_SIZE; + int j = i - border; + if (shift == 0) { + l.set_cword(j, w); + return; + } + // border <= i < size() && shift != 0 + int nshift = SC_DIGIT_SIZE - shift; + sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift; + if (i == border) { + sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift; + r.set_cword(i, w & rl_mask); + l.set_cword(0, (l.get_cword(0) & lh_mask) | (w >> shift)); + return; + } + // border < i < size() && shift != 0 + sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift; + l.set_cword(j - 1, (l.get_cword(j - 1) & ll_mask) | (w << nshift)); + if (j < l.size()) + l.set_cword(j, (l.get_cword(j) & lh_mask) | (w >> shift)); +} + +// r-value concatenation operators and functions +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> > +operator , (sc_concref_r<T1, T2> a, sc_bitref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +operator , (sc_concref_r<T1, T2> a, sc_subref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +operator , (sc_concref_r<T1, T2> a, sc_concref_r<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>,sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +operator , (sc_concref_r<T1, T2> a, const sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > +concat(sc_concref_r<T1, T2> a, sc_bitref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +concat(sc_concref_r<T1, T2> a, sc_subref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +concat(sc_concref_r<T1, T2> a, sc_concref_r<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +concat(sc_concref_r<T1, T2> a, const sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > +operator , (sc_concref_r<T1, T2> a, sc_bitref<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > +operator , (sc_concref<T1, T2> a, sc_bitref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline +sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +operator , (sc_concref_r<T1, T2> a, sc_subref<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +operator , (sc_concref<T1, T2> a, sc_subref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +operator , (sc_concref_r<T1, T2> a, sc_concref<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +operator , (sc_concref<T1, T2> a, sc_concref_r<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +operator , (sc_concref<T1, T2> a, const sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +operator , (sc_concref_r<T1, T2> a, sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > +concat(sc_concref_r<T1, T2> a, sc_bitref<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > +concat(sc_concref<T1, T2> a, sc_bitref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +concat(sc_concref_r<T1, T2> a, sc_subref<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > +concat(sc_concref<T1, T2> a, sc_subref_r<T3> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +concat(sc_concref_r<T1, T2> a, sc_concref<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > +concat(sc_concref<T1, T2> a, sc_concref_r<T3, T4> b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +concat(sc_concref<T1, T2> a, const sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<sc_concref_r<T1, T2>, T3> +concat(sc_concref_r<T1, T2> a, sc_proxy<T3> &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value and l-value). +// ---------------------------------------------------------------------------- + +// other methods +template <class T1, class T2> +inline void +sc_concref<T1, T2>::scan(::std::istream &is) +{ + std::string s; + is >> s; + *this = s.c_str(); +} + +// l-value concatenation operators and functions +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > +operator , (sc_concref<T1, T2> a, sc_bitref<T3> b) +{ + return sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > +operator , (sc_concref<T1, T2> a, sc_subref<T3>b) +{ + return sc_concref<sc_concref<T1, T2>, sc_subref<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > +operator , (sc_concref<T1, T2> a, sc_concref<T3, T4> b) +{ + return sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, T3> +operator , (sc_concref<T1, T2> a, sc_proxy<T3> &b) +{ + return sc_concref<sc_concref<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > +concat(sc_concref<T1, T2> a, sc_bitref<T3> b) +{ + return sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > +concat(sc_concref<T1, T2> a, sc_subref<T3> b) +{ + return sc_concref<sc_concref<T1, T2>, sc_subref<T3> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3, class T4> +inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > +concat(sc_concref<T1, T2> a, sc_concref<T3, T4> b) +{ + return sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >( + *a.clone(), *b.clone(), 3); +} + +template <class T1, class T2, class T3> +inline sc_concref<sc_concref<T1, T2>, T3> +concat(sc_concref<T1, T2> a, sc_proxy<T3> &b) +{ + return sc_concref<sc_concref<T1, T2>, T3>( + *a.clone(), b.back_cast(), 1); +} + +template <class X, class Y> +inline ::std::istream & +operator >> (::std::istream &is, sc_concref<X, Y> a) +{ + a.scan(is); + return is; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +operator , (const sc_proxy<T1> &a, sc_bitref_r<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +operator , (const sc_proxy<T1> &a, sc_subref_r<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +operator , (const sc_proxy<T1> &a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +operator , (const sc_proxy<T1> &a, const sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +concat(const sc_proxy<T1> &a, sc_bitref_r<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +concat(const sc_proxy<T1> &a, sc_subref_r<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +concat(const sc_proxy<T1> &a, sc_concref_r<T2, T3> b ) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +concat(const sc_proxy<T1> &a, const sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +operator , (const sc_proxy<T1> &a, sc_bitref<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +operator , (sc_proxy<T1> &a, sc_bitref_r<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +operator , (const sc_proxy<T1> &a, sc_subref<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +operator , (sc_proxy<T1> &a, sc_subref_r<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +operator , (const sc_proxy<T1> &a, sc_concref<T2, T3> b) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +operator , (sc_proxy<T1> &a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +operator , (const sc_proxy<T1> &a, sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +operator , (sc_proxy<T1> &a, const sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +concat(const sc_proxy<T1> &a, sc_bitref<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_bitref_r<T2> > +concat(sc_proxy<T1> &a, sc_bitref_r<T2> b) +{ + return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +concat(const sc_proxy<T1> &a, sc_subref<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, sc_subref_r<T2> > +concat(sc_proxy<T1> &a, sc_subref_r<T2> b) +{ + return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +concat(const sc_proxy<T1> &a, sc_concref<T2, T3> b) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref_r<T1, sc_concref_r<T2, T3> > +concat(sc_proxy<T1> &a, sc_concref_r<T2, T3> b) +{ + return sc_concref_r<T1, sc_concref_r<T2, T3> >( + a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +concat(const sc_proxy<T1> &a, sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + +template <class T1, class T2> +inline sc_concref_r<T1, T2> +concat(sc_proxy<T1> &a, const sc_proxy<T2> &b) +{ + return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast()); +} + + +// l-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref<T1, sc_bitref<T2> > +operator , (sc_proxy<T1> &a, sc_bitref<T2> b) +{ + return sc_concref<T1, sc_bitref<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref<T1, sc_subref<T2> > +operator , (sc_proxy<T1> &a, sc_subref<T2> b) +{ + return sc_concref<T1, sc_subref<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref<T1, sc_concref<T2, T3> > +operator , (sc_proxy<T1> &a, sc_concref<T2, T3> b) +{ + return sc_concref<T1, sc_concref<T2, T3> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref<T1, T2> +operator , (sc_proxy<T1> &a, sc_proxy<T2> &b) +{ + return sc_concref<T1, T2>(a.back_cast(), b.back_cast()); +} + + +template <class T1, class T2> +inline sc_concref<T1, sc_bitref<T2> > +concat(sc_proxy<T1> &a, sc_bitref<T2> b) +{ + return sc_concref<T1, sc_bitref<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref<T1, sc_subref<T2> > +concat(sc_proxy<T1> &a, sc_subref<T2> b) +{ + return sc_concref<T1, sc_subref<T2> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2, class T3> +inline sc_concref<T1, sc_concref<T2, T3> > +concat(sc_proxy<T1> &a, sc_concref<T2, T3> b) +{ + return sc_concref<T1, sc_concref<T2, T3> >(a.back_cast(), *b.clone(), 2); +} + +template <class T1, class T2> +inline sc_concref<T1, T2> +concat(sc_proxy<T1> &a, sc_proxy<T2> &b) +{ + return sc_concref<T1, T2>(a.back_cast(), b.back_cast()); +} + +} // namespace sc_dt + +// $Log: sc_bit_proxies.h,v $ +// Revision 1.10 2011/09/05 21:19:53 acg +// Philipp A. Hartmann: added parentheses to expressions to eliminate +// compiler warnings. +// +// Revision 1.9 2011/09/01 15:03:42 acg +// Philipp A. Hartmann: add parentheses to eliminate compiler warnings. +// +// Revision 1.8 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.7 2011/08/24 22:05:40 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.6 2010/02/22 14:25:43 acg +// Andy Goodrich: removed 'mutable' directive from references, since it +// is not a legal C++ construct. +// +// Revision 1.5 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.4 2007/03/14 17:48:37 acg +// Andy Goodrich: fixed bug. +// +// Revision 1.3 2007/01/18 19:29:18 acg +// Andy Goodrich: fixed bug in concatenations of bit selects on sc_lv and +// sc_bv types. The offending code was in sc_bitref<X>::set_word and +// sc_bitref<X>::get_word. These methods were not writing the bit they +// represented, but rather writing an entire word whose index was the +// index of the bit they represented. This not only did not write the +// correct bit, but clobbered a word that might not even be in the +// variable the reference was for. +// +// Revision 1.2 2007/01/17 22:45:08 acg +// Andy Goodrich: fixed sc_bitref<X>::set_bit(). +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif // __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__ diff --git a/src/systemc/ext/dt/bit/sc_bv.hh b/src/systemc/ext/dt/bit/sc_bv.hh new file mode 100644 index 000000000..8b48b0984 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_bv.hh @@ -0,0 +1,208 @@ +/***************************************************************************** + + 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_bv.h -- Arbitrary size bit vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bv.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_BV_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_BV_HH__ + +#include "sc_bv_base.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_bv; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bv<W> +// +// Arbitrary size bit vector class. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_bv : public sc_bv_base +{ + public: + // constructors + sc_bv() :sc_bv_base(W) {} + + explicit sc_bv(bool init_value) : sc_bv_base(init_value, W) {} + + explicit sc_bv(char init_value) : sc_bv_base((init_value != '0'), W) {} + + sc_bv(const char *a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const bool *a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const sc_logic *a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const sc_unsigned &a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const sc_signed &a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const sc_uint_base &a) : sc_bv_base(W) + { + sc_bv_base::operator = (a); + } + sc_bv(const sc_int_base &a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(unsigned long a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(long a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(unsigned int a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(int a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(uint64 a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(int64 a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + + template <class X> + sc_bv(const sc_proxy<X> &a) : sc_bv_base(W) { sc_bv_base::operator = (a); } + sc_bv(const sc_bv<W> &a) : sc_bv_base(a) {} + + // assignment operators + template <class X> + sc_bv<W> & + operator = (const sc_proxy<X> &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_bv<W> &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const char *a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const bool *a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_logic *a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_unsigned &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_signed &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_uint_base &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (const sc_int_base &a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (unsigned long a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (long a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (unsigned int a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (int a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (uint64 a) + { + sc_bv_base::operator = (a); + return *this; + } + + sc_bv<W> & + operator = (int64 a) + { + sc_bv_base::operator = (a); + return *this; + } +}; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_BV_HH__ diff --git a/src/systemc/ext/dt/bit/sc_bv_base.hh b/src/systemc/ext/dt/bit/sc_bv_base.hh new file mode 100644 index 000000000..8aac78d37 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_bv_base.hh @@ -0,0 +1,282 @@ +/***************************************************************************** + + 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_bv_base.h -- Arbitrary size bit vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_bv_base.h,v $ +// Revision 1.3 2011/08/26 22:32:00 acg +// Torsten Maehne: added parentheses to make opearator ordering more obvious. +// +// Revision 1.2 2011/08/15 16:43:24 acg +// Torsten Maehne: changes to remove unused argument warnings. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__ + +#include "../int/sc_length_param.hh" +#include "sc_bit_proxies.hh" +#include "sc_proxy.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_bv_base; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_bv_base +// +// Arbitrary size bit vector base class. +// ---------------------------------------------------------------------------- + +class sc_bv_base : public sc_proxy<sc_bv_base> +{ + friend class sc_lv_base; + + void init(int length_, bool init_value=false); + void assign_from_string(const std::string &); + + public: + // typedefs + typedef sc_proxy<sc_bv_base> base_type; + typedef base_type::value_type value_type; + + // constructors + explicit sc_bv_base(int length_=sc_length_param().len()) : + m_len(0), m_size(0), m_data(0) + { + init(length_); + } + + explicit sc_bv_base(bool a, int length_=sc_length_param().len()) : + m_len(0), m_size(0), m_data(0) + { + init(length_, a); + } + + sc_bv_base(const char *a); + sc_bv_base(const char *a, int length_); + + template <class X> + sc_bv_base(const sc_proxy<X> &a) : m_len(0), m_size(0), m_data(0) + { + init(a.back_cast().length()); + base_type::assign_(a); + } + + sc_bv_base(const sc_bv_base &a); + + // destructor + virtual ~sc_bv_base() { delete [] m_data; } + + // assignment operators + template <class X> + sc_bv_base & + operator = (const sc_proxy<X> &a) + { + assign_p_(*this, a); + return *this; + } + + sc_bv_base & + operator = (const sc_bv_base &a) + { + assign_p_(*this, a); + return *this; + } + + sc_bv_base &operator = (const char *a); + + sc_bv_base & + operator = (const bool *a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (const sc_logic *a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (const sc_unsigned &a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (const sc_signed &a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (const sc_uint_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (const sc_int_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (unsigned long a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (long a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (unsigned int a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (int a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (uint64 a) + { + base_type::assign_(a); + return *this; + } + + sc_bv_base & + operator = (int64 a) + { + base_type::assign_(a); + return *this; + } + + // common methods + int length() const { return m_len; } + int size() const { return m_size; } + + value_type get_bit(int i) const; + void set_bit(int i, value_type value); + + sc_digit get_word(int i) const { return m_data[i]; } + + void set_word(int i, sc_digit w) { m_data[i] = w; } + + sc_digit get_cword(int /*i*/) const { return SC_DIGIT_ZERO; } + + void set_cword(int i, sc_digit w); + + void clean_tail(); + + // other methods + bool is_01() const { return true; } + + protected: + int m_len; // length in bits + int m_size; // size of data array + sc_digit *m_data; // data array +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +// common methods +inline sc_bv_base::value_type +sc_bv_base::get_bit(int i) const +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + return value_type((m_data[wi] >> bi) & SC_DIGIT_ONE); +} + +inline void +sc_bv_base::set_bit(int i, value_type value) +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + sc_digit mask = SC_DIGIT_ONE << bi; + m_data[wi] |= mask; // set bit to 1 + m_data[wi] &= value << bi | ~mask; +} + +inline void +sc_bv_base::set_cword(int /*i*/, sc_digit w) +{ + if (w) { + SC_REPORT_WARNING("sc_bv cannot contain values X and Z", 0); + } +} + +inline void +sc_bv_base::clean_tail() +{ + int wi = m_size - 1; + int bi = m_len % SC_DIGIT_SIZE; + if (bi != 0) + m_data[wi] &= ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi); +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_BV_BASE_HH__ diff --git a/src/systemc/ext/dt/bit/sc_logic.hh b/src/systemc/ext/dt/bit/sc_logic.hh new file mode 100644 index 000000000..184e763b5 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_logic.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_logic.h -- C++ implementation of logic type. Behaves + pretty much the same way as HDLs except with 4 values. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_logic.h,v $ +// Revision 1.3 2011/08/07 18:54:19 acg +// Philipp A. Hartmann: remove friend function declarations that implement +// code, and clean up how bit and logic operators are defined in general. +// +// Revision 1.2 2011/01/25 20:50:37 acg +// Andy Goodrich: changes for IEEE 1666 2011. +// +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.5 2006/12/02 21:00:57 acg +// Andy Goodrich: fixes for concatenation support. +// +// Revision 1.4 2006/05/08 17:49:59 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:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__ + +#include <cstdio> +#include <iostream> + +#include "../sc_mempool.hh" +#include "sc_bit.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_logic; + + +// ---------------------------------------------------------------------------- +// ENUM : sc_logic_value_t +// +// Enumeration of values for sc_logic. +// ---------------------------------------------------------------------------- + +enum sc_logic_value_t +{ + Log_0 = 0, + Log_1, + Log_Z, + Log_X +}; + +// ---------------------------------------------------------------------------- +// CLASS : sc_logic +// +// Four-valued logic type. +// ---------------------------------------------------------------------------- + +class sc_logic +{ + private: + // support methods + static void invalid_value(sc_logic_value_t); + static void invalid_value(char); + static void invalid_value(int); + + static sc_logic_value_t + to_value(sc_logic_value_t v) + { + if (v < Log_0 || v > Log_X) { + invalid_value(v); + // may continue, if suppressed + v = Log_X; + } + return v; + } + + static sc_logic_value_t to_value(bool b) { return (b ? Log_1 : Log_0); } + + static sc_logic_value_t + to_value(char c) + { + unsigned int index = (int)c; + if (index > 127) { + invalid_value(c); + // may continue, if suppressed + index = 127; // aka Log_X + } + return char_to_logic[index]; + } + + static sc_logic_value_t + to_value(int i) + { + if (i < Log_0 || i > Log_X) { + invalid_value(i); + // may continue, if suppressed + i = Log_X; + } + return sc_logic_value_t(i); + } + + void invalid_01() const; + + public: + // conversion tables + static const sc_logic_value_t char_to_logic[128]; + static const char logic_to_char[4]; + static const sc_logic_value_t and_table[4][4]; + static const sc_logic_value_t or_table[4][4]; + static const sc_logic_value_t xor_table[4][4]; + static const sc_logic_value_t not_table[4]; + + // constructors + sc_logic() : m_val(Log_X) {} + sc_logic(const sc_logic &a) : m_val(a.m_val) {} + sc_logic(sc_logic_value_t v) : m_val(to_value(v)) {} + explicit sc_logic(bool a) : m_val(to_value(a)) {} + explicit sc_logic(char a) : m_val(to_value(a)) {} + explicit sc_logic(int a) : m_val(to_value(a)) {} + explicit sc_logic(const sc_bit &a) : m_val(to_value(a.to_bool())) {} + + // destructor + ~sc_logic() {} + + // (bitwise) assignment operators +#define DEFN_ASN_OP_T(op,tp) \ + sc_logic & \ + operator op (tp v) \ + { \ + *this op sc_logic(v); \ + return *this; \ + } + +#define DEFN_ASN_OP(op) \ + DEFN_ASN_OP_T(op, sc_logic_value_t) \ + DEFN_ASN_OP_T(op, bool) \ + DEFN_ASN_OP_T(op, char) \ + DEFN_ASN_OP_T(op, int) \ + DEFN_ASN_OP_T(op, const sc_bit &) + + sc_logic & + operator = (const sc_logic &a) + { + m_val = a.m_val; + return *this; + } + + sc_logic & + operator &= (const sc_logic &b) + { + m_val = and_table[m_val][b.m_val]; + return *this; + } + + sc_logic & + operator |= (const sc_logic &b) + { + m_val = or_table[m_val][b.m_val]; + return *this; + } + + sc_logic & + operator ^= (const sc_logic &b) + { + m_val = xor_table[m_val][b.m_val]; + return *this; + } + + DEFN_ASN_OP(=) + DEFN_ASN_OP(&=) + DEFN_ASN_OP(|=) + DEFN_ASN_OP(^=) + +#undef DEFN_ASN_OP_T +#undef DEFN_ASN_OP + + // bitwise operators and functions + friend const sc_logic operator & (const sc_logic &, const sc_logic &); + friend const sc_logic operator | (const sc_logic &, const sc_logic &); + friend const sc_logic operator ^ (const sc_logic &, const sc_logic &); + + // relational operators + friend bool operator == (const sc_logic &, const sc_logic &); + friend bool operator != (const sc_logic &, const sc_logic &); + + // bitwise complement + const sc_logic operator ~ () const { return sc_logic(not_table[m_val]); } + sc_logic & + b_not() + { + m_val = not_table[m_val]; + return *this; + } + + // explicit conversions + sc_logic_value_t value() const { return m_val; } + + bool is_01() const { return ((int)m_val == Log_0 || (int)m_val == Log_1); } + bool + to_bool() const + { + if (!is_01()) { + invalid_01(); + } + return ((int)m_val != Log_0); + } + + char to_char() const { return logic_to_char[m_val]; } + + // other methods + void print(::std::ostream &os=::std::cout) const { os << to_char(); } + void scan(::std::istream &is=::std::cin); + + // memory (de)allocation + // placement new + static void *operator new (std::size_t, void *p) { return p; } + static void * + operator new (std::size_t sz) + { + return sc_core::sc_mempool::allocate(sz); + } + static void + operator delete (void *p, std::size_t sz) + { + sc_core::sc_mempool::release(p, sz); + } + static void * + operator new [] (std::size_t sz) + { + return sc_core::sc_mempool::allocate(sz); + } + static void + operator delete [] (void *p, std::size_t sz) + { + sc_core::sc_mempool::release(p, sz); + } + + private: + sc_logic_value_t m_val; + + private: + // Disabled + explicit sc_logic(const char *); + sc_logic &operator = (const char *); +}; + +// ---------------------------------------------------------------------------- + +// bitwise operators +inline const sc_logic +operator & (const sc_logic &a, const sc_logic &b) +{ + return sc_logic(sc_logic::and_table[a.m_val][b.m_val]); +} + +inline const sc_logic +operator | (const sc_logic &a, const sc_logic &b) +{ + return sc_logic(sc_logic::or_table[a.m_val][b.m_val]); +} + +inline const sc_logic +operator ^ (const sc_logic &a, const sc_logic &b) +{ + return sc_logic(sc_logic::xor_table[a.m_val][b.m_val]); +} + +#define DEFN_BIN_OP_T(ret,op,tp) \ + inline ret \ + operator op (const sc_logic &a, tp b) \ + { \ + return (a op sc_logic(b)); \ + } \ + inline ret \ + operator op (tp a, const sc_logic &b) \ + { \ + return (sc_logic(a) op b); \ + } + +#define DEFN_BIN_OP(ret, op) \ + DEFN_BIN_OP_T(ret, op, sc_logic_value_t) \ + DEFN_BIN_OP_T(ret, op, bool) \ + DEFN_BIN_OP_T(ret, op, char) \ + DEFN_BIN_OP_T(ret, op, int) + +DEFN_BIN_OP(const sc_logic, &) +DEFN_BIN_OP(const sc_logic, |) +DEFN_BIN_OP(const sc_logic, ^) + +// relational operators and functions + +inline bool +operator == (const sc_logic &a, const sc_logic &b) +{ + return ((int)a.m_val == b.m_val); +} + +inline bool +operator != (const sc_logic &a, const sc_logic &b) +{ + return ((int)a.m_val != b.m_val); +} + +DEFN_BIN_OP(bool, ==) +DEFN_BIN_OP(bool, !=) + +#undef DEFN_BIN_OP_T +#undef DEFN_BIN_OP + +// ---------------------------------------------------------------------------- + +inline ::std::ostream & +operator << (::std::ostream &os, const sc_logic &a) +{ + a.print(os); + return os; +} + +inline ::std::istream & +operator >> (::std::istream &is, sc_logic &a) +{ + a.scan(is); + return is; +} + + +extern const sc_logic SC_LOGIC_0; +extern const sc_logic SC_LOGIC_1; +extern const sc_logic SC_LOGIC_Z; +extern const sc_logic SC_LOGIC_X; + +// #ifdef SC_DT_DEPRECATED +extern const sc_logic sc_logic_0; +extern const sc_logic sc_logic_1; +extern const sc_logic sc_logic_Z; +extern const sc_logic sc_logic_X; +// #endif + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_LOGIC_HH__ diff --git a/src/systemc/ext/dt/bit/sc_lv.hh b/src/systemc/ext/dt/bit/sc_lv.hh new file mode 100644 index 000000000..cab58df25 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_lv.hh @@ -0,0 +1,205 @@ +/***************************************************************************** + + 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_lv.h -- Arbitrary size logic vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_lv.h,v $ +// Revision 1.1.1.1 2006/12/15 20:20:04 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_LV_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_LV_HH__ + +#include "sc_lv_base.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <int W> +class sc_lv; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_lv<W> +// +// Arbitrary size logic vector class. +// ---------------------------------------------------------------------------- + +template <int W> +class sc_lv : public sc_lv_base +{ + public: + // constructors + sc_lv() : sc_lv_base(W) {} + explicit sc_lv(const sc_logic &init_value) : sc_lv_base(init_value, W) {} + explicit sc_lv(bool init_value) : sc_lv_base(sc_logic(init_value), W) {} + explicit sc_lv(char init_value) : sc_lv_base(sc_logic(init_value), W) {} + sc_lv(const char *a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const bool *a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const sc_logic *a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const sc_unsigned &a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const sc_signed &a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const sc_uint_base &a) : sc_lv_base(W) + { + sc_lv_base::operator = (a); + } + sc_lv(const sc_int_base &a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(unsigned long a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(long a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(unsigned int a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(int a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(uint64 a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(int64 a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + template <class X> + sc_lv(const sc_proxy<X> &a) : sc_lv_base(W) { sc_lv_base::operator = (a); } + sc_lv(const sc_lv<W> &a) : sc_lv_base(a) {} + + // assignment operators + template <class X> + sc_lv<W> & + operator = (const sc_proxy<X> &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_lv<W> &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const char *a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const bool *a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_logic *a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_unsigned &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_signed &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_uint_base &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (const sc_int_base &a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (unsigned long a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (long a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (unsigned int a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (int a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (uint64 a) + { + sc_lv_base::operator = (a); + return *this; + } + + sc_lv<W> & + operator = (int64 a) + { + sc_lv_base::operator = (a); + return *this; + } +}; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_LV_HH__ diff --git a/src/systemc/ext/dt/bit/sc_lv_base.hh b/src/systemc/ext/dt/bit/sc_lv_base.hh new file mode 100644 index 000000000..b7aa1a966 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_lv_base.hh @@ -0,0 +1,1589 @@ +/***************************************************************************** + + 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_lv_base.h -- Arbitrary size logic vector class. + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + Andy Goodrich, Forte Design Systems + Fixed bug in clean_tail for sizes that are modulo 32, which caused + zeroing of values. + + *****************************************************************************/ + +// $Log: sc_lv_base.h,v $ +// Revision 1.4 2011/08/26 22:32:00 acg +// Torsten Maehne: added parentheses to make opearator ordering more obvious. +// +// Revision 1.3 2010/01/27 19:41:29 acg +// Andy Goodrich: fix 8 instances of sc_concref constructor invocations +// that failed to indicate that their arguments should be freed when the +// object was freed. +// +// Revision 1.2 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.2 2007/03/14 17:47:49 acg +// Andy Goodrich: Formatting. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__ + +#include "../int/sc_length_param.hh" +#include "sc_bv_base.hh" +#include "sc_logic.hh" + +namespace sc_dt +{ + +// classes defined in this module +class sc_lv_base; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_lv_base +// +// Arbitrary size logic vector base class. +// ---------------------------------------------------------------------------- + +class sc_lv_base : public sc_proxy<sc_lv_base> +{ + friend class sc_bv_base; + + void init(int length_, const sc_logic &init_value=SC_LOGIC_X); + void assign_from_string(const std::string &); + + public: + // typedefs + typedef sc_proxy<sc_lv_base> base_type; + typedef base_type::value_type value_type; + + // constructors + explicit sc_lv_base(int length_=sc_length_param().len()) : + m_len(0), m_size(0), m_data(0), m_ctrl(0) + { + init(length_); + } + + explicit sc_lv_base( + const sc_logic &a, int length_=sc_length_param().len()) : + m_len(0), m_size(0), m_data(0), m_ctrl(0) + { + init(length_, a); + } + + sc_lv_base(const char *a); + sc_lv_base(const char *a, int length_); + + template <class X> + sc_lv_base(const sc_proxy<X> &a) : + m_len(0), m_size(0), m_data(0), m_ctrl(0) + { + init(a.back_cast().length()); + base_type::assign_(a); + } + + sc_lv_base(const sc_lv_base &a); + + // destructor + virtual ~sc_lv_base() { delete [] m_data; } + + // assignment operators + template <class X> + sc_lv_base & + operator = (const sc_proxy<X> &a) + { + assign_p_(*this, a); + return *this; + } + + sc_lv_base & + operator = (const sc_lv_base &a) + { + assign_p_(*this, a); + return *this; + } + + sc_lv_base &operator = (const char *a); + + sc_lv_base & + operator = (const bool *a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (const sc_logic *a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (const sc_unsigned &a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (const sc_signed &a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (const sc_uint_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (const sc_int_base &a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (unsigned long a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (long a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (unsigned int a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (int a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (uint64 a) + { + base_type::assign_(a); + return *this; + } + + sc_lv_base & + operator = (int64 a) + { + base_type::assign_(a); + return *this; + } + + // common methods + int length() const { return m_len; } + int size() const { return m_size; } + + value_type get_bit(int i) const; + void set_bit(int i, value_type value); + + sc_digit get_word(int wi) const { return m_data[wi]; } + + // note the test for out of range access here. this is necessary + // because of the hair-brained way concatenations are set up. + // an extend_sign on a concatenation uses the whole length of + // the concatenation to determine how many words to set. + void + set_word(int wi, sc_digit w) + { + sc_assert(wi < m_size); + m_data[wi] = w; + } + + sc_digit get_cword(int wi) const { return m_ctrl[wi]; } + + void + set_cword(int wi, sc_digit w) + { + sc_assert(wi < m_size); + m_ctrl[wi] = w; + } + void clean_tail(); + + // other methods + bool is_01() const; + + protected: + int m_len; // length in bits + int m_size; // size of the data array + sc_digit *m_data; // data array + sc_digit *m_ctrl; // dito (control part) +}; + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline sc_lv_base::value_type +sc_lv_base::get_bit(int i) const +{ + int wi = i / SC_DIGIT_SIZE; + int bi = i % SC_DIGIT_SIZE; + return value_type(((m_data[wi] >> bi) & SC_DIGIT_ONE) | + (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO)); +} + +inline void +sc_lv_base::set_bit(int i, value_type value) +{ + int wi = i / SC_DIGIT_SIZE; // word index + int bi = i % SC_DIGIT_SIZE; // bit index + sc_digit mask = SC_DIGIT_ONE << bi; + m_data[wi] |= mask; // set bit to 1 + m_ctrl[wi] |= mask; // set bit to 1 + m_data[wi] &= value << bi | ~mask; + m_ctrl[wi] &= value >> 1 << bi | ~mask; +} + +inline void +sc_lv_base::clean_tail() +{ + int wi = m_size - 1; + int bi = m_len % SC_DIGIT_SIZE; + sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi); + if (mask) { + m_data[wi] &= mask; + m_ctrl[wi] &= mask; + } +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise complement +template <class X> +inline const sc_lv_base +sc_proxy<X>::operator ~ () const +{ + sc_lv_base a(back_cast()); + return a.b_not(); +} + +// bitwise and +template <class X, class Y> +inline X & +operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + X &x = px.back_cast(); + sc_lv_base a(x.length()); + a = py.back_cast(); + return b_and_assign_(x, a); +} + +#define DEFN_BITWISE_AND_ASN_OP_T(tp) \ +template <class X> \ +inline X & \ +sc_proxy<X>::operator &= (tp b) \ +{ \ + X &x = back_cast(); \ + sc_lv_base a(x.length()); \ + a = b; \ + return b_and_assign_(x, a); \ +} + +DEFN_BITWISE_AND_ASN_OP_T(const char *) +DEFN_BITWISE_AND_ASN_OP_T(const bool *) +DEFN_BITWISE_AND_ASN_OP_T(const sc_logic *) +DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned &) +DEFN_BITWISE_AND_ASN_OP_T(const sc_signed &) +DEFN_BITWISE_AND_ASN_OP_T(unsigned long) +DEFN_BITWISE_AND_ASN_OP_T(long) +DEFN_BITWISE_AND_ASN_OP_T(uint64) +DEFN_BITWISE_AND_ASN_OP_T(int64) + +#undef DEFN_BITWISE_AND_ASN_OP_T + +template <class X, class Y> +inline const sc_lv_base +operator & (const sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + sc_lv_base a(px.back_cast()); + return (a &= py.back_cast()); +} + +#define DEFN_BITWISE_AND_OP_T_A(tp) \ +template <class X> \ +inline const sc_lv_base \ +sc_proxy<X>::operator & (tp b) const \ +{ \ + sc_lv_base a(back_cast()); \ + return (a &= b); \ +} + +DEFN_BITWISE_AND_OP_T_A(const char *) +DEFN_BITWISE_AND_OP_T_A(const bool *) +DEFN_BITWISE_AND_OP_T_A(const sc_logic *) +DEFN_BITWISE_AND_OP_T_A(const sc_unsigned &) +DEFN_BITWISE_AND_OP_T_A(const sc_signed &) +DEFN_BITWISE_AND_OP_T_A(const sc_uint_base &) +DEFN_BITWISE_AND_OP_T_A(const sc_int_base &) +DEFN_BITWISE_AND_OP_T_A(unsigned long) +DEFN_BITWISE_AND_OP_T_A(long) +DEFN_BITWISE_AND_OP_T_A(unsigned int) +DEFN_BITWISE_AND_OP_T_A(int) +DEFN_BITWISE_AND_OP_T_A(uint64) +DEFN_BITWISE_AND_OP_T_A(int64) + +#undef DEFN_BITWISE_AND_OP_T_A + +#define DEFN_BITWISE_AND_OP_T_B(tp) \ +template <class X> \ +inline const sc_lv_base \ +operator & (tp b, const sc_proxy<X> &px) \ +{ \ + return (px & b); \ +} + +DEFN_BITWISE_AND_OP_T_B(const char *) +DEFN_BITWISE_AND_OP_T_B(const bool *) +DEFN_BITWISE_AND_OP_T_B(const sc_logic *) +DEFN_BITWISE_AND_OP_T_B(const sc_unsigned &) +DEFN_BITWISE_AND_OP_T_B(const sc_signed &) +DEFN_BITWISE_AND_OP_T_B(const sc_uint_base &) +DEFN_BITWISE_AND_OP_T_B(const sc_int_base &) +DEFN_BITWISE_AND_OP_T_B(unsigned long) +DEFN_BITWISE_AND_OP_T_B(long) +DEFN_BITWISE_AND_OP_T_B(unsigned int) +DEFN_BITWISE_AND_OP_T_B(int) +DEFN_BITWISE_AND_OP_T_B(uint64) +DEFN_BITWISE_AND_OP_T_B(int64) + +#undef DEFN_BITWISE_AND_OP_T_B + +// bitwise or +template <class X, class Y> +inline X & +operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + X &x = px.back_cast(); + sc_lv_base a(x.length()); + a = py.back_cast(); + return b_or_assign_(x, a); +} + +#define DEFN_BITWISE_OR_ASN_OP_T(tp) \ +template <class X> \ +inline X & \ +sc_proxy<X>::operator |= (tp b) \ +{ \ + X &x = back_cast(); \ + sc_lv_base a(x.length()); \ + a = b; \ + return b_or_assign_(x, a); \ +} + +DEFN_BITWISE_OR_ASN_OP_T(const char *) +DEFN_BITWISE_OR_ASN_OP_T(const bool *) +DEFN_BITWISE_OR_ASN_OP_T(const sc_logic *) +DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned &) +DEFN_BITWISE_OR_ASN_OP_T(const sc_signed &) +DEFN_BITWISE_OR_ASN_OP_T(unsigned long) +DEFN_BITWISE_OR_ASN_OP_T(long) +DEFN_BITWISE_OR_ASN_OP_T(uint64) +DEFN_BITWISE_OR_ASN_OP_T(int64) + +#undef DEFN_BITWISE_OR_ASN_OP_T + +template <class X, class Y> +inline const sc_lv_base +operator | (const sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + sc_lv_base a(px.back_cast()); + return (a |= py.back_cast()); +} + +#define DEFN_BITWISE_OR_OP_T_A(tp) \ +template <class X> \ +inline const sc_lv_base \ +sc_proxy<X>::operator | (tp b) const \ +{ \ + sc_lv_base a(back_cast()); \ + return (a |= b); \ +} + +DEFN_BITWISE_OR_OP_T_A(const char *) +DEFN_BITWISE_OR_OP_T_A(const bool *) +DEFN_BITWISE_OR_OP_T_A(const sc_logic *) +DEFN_BITWISE_OR_OP_T_A(const sc_unsigned &) +DEFN_BITWISE_OR_OP_T_A(const sc_signed &) +DEFN_BITWISE_OR_OP_T_A(const sc_uint_base &) +DEFN_BITWISE_OR_OP_T_A(const sc_int_base &) +DEFN_BITWISE_OR_OP_T_A(unsigned long) +DEFN_BITWISE_OR_OP_T_A(long) +DEFN_BITWISE_OR_OP_T_A(unsigned int) +DEFN_BITWISE_OR_OP_T_A(int) +DEFN_BITWISE_OR_OP_T_A(uint64) +DEFN_BITWISE_OR_OP_T_A(int64) + +#undef DEFN_BITWISE_OR_OP_T_A + +#define DEFN_BITWISE_OR_OP_T_B(tp) \ +template <class X> \ +inline const sc_lv_base \ +operator | (tp b, const sc_proxy<X> &px) \ +{ \ + return (px | b); \ +} + +DEFN_BITWISE_OR_OP_T_B(const char *) +DEFN_BITWISE_OR_OP_T_B(const bool *) +DEFN_BITWISE_OR_OP_T_B(const sc_logic *) +DEFN_BITWISE_OR_OP_T_B(const sc_unsigned &) +DEFN_BITWISE_OR_OP_T_B(const sc_signed &) +DEFN_BITWISE_OR_OP_T_B(const sc_uint_base &) +DEFN_BITWISE_OR_OP_T_B(const sc_int_base &) +DEFN_BITWISE_OR_OP_T_B(unsigned long) +DEFN_BITWISE_OR_OP_T_B(long) +DEFN_BITWISE_OR_OP_T_B(unsigned int) +DEFN_BITWISE_OR_OP_T_B(int) +DEFN_BITWISE_OR_OP_T_B(uint64) +DEFN_BITWISE_OR_OP_T_B(int64) + +#undef DEFN_BITWISE_OR_OP_T_B + +// bitwise xor +template <class X, class Y> +inline X & +operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + X &x = px.back_cast(); + sc_lv_base a(x.length()); + a = py.back_cast(); + return b_xor_assign_(x, a); +} + +#define DEFN_BITWISE_XOR_ASN_OP_T(tp) \ +template <class X> \ +inline X & \ +sc_proxy<X>::operator ^= (tp b) \ +{ \ + X &x = back_cast(); \ + sc_lv_base a(x.length()); \ + a = b; \ + return b_xor_assign_(x, a); \ +} + +DEFN_BITWISE_XOR_ASN_OP_T(const char *) +DEFN_BITWISE_XOR_ASN_OP_T(const bool *) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic *) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned &) +DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed &) +DEFN_BITWISE_XOR_ASN_OP_T(unsigned long) +DEFN_BITWISE_XOR_ASN_OP_T(long) +DEFN_BITWISE_XOR_ASN_OP_T(uint64) +DEFN_BITWISE_XOR_ASN_OP_T(int64) + +#undef DEFN_BITWISE_XOR_ASN_OP_T + +template <class X, class Y> +inline const sc_lv_base +operator ^ (const sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + sc_lv_base a(px.back_cast()); + return (a ^= py.back_cast()); +} + +#define DEFN_BITWISE_XOR_OP_T_A(tp) \ +template <class X> \ +inline const sc_lv_base \ +sc_proxy<X>::operator ^ (tp b) const \ +{ \ + sc_lv_base a(back_cast()); \ + return (a ^= b); \ +} + +DEFN_BITWISE_XOR_OP_T_A(const char *) +DEFN_BITWISE_XOR_OP_T_A(const bool *) +DEFN_BITWISE_XOR_OP_T_A(const sc_logic *) +DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned &) +DEFN_BITWISE_XOR_OP_T_A(const sc_signed &) +DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base &) +DEFN_BITWISE_XOR_OP_T_A(const sc_int_base &) +DEFN_BITWISE_XOR_OP_T_A(unsigned long) +DEFN_BITWISE_XOR_OP_T_A(long) +DEFN_BITWISE_XOR_OP_T_A(unsigned int) +DEFN_BITWISE_XOR_OP_T_A(int) +DEFN_BITWISE_XOR_OP_T_A(uint64) +DEFN_BITWISE_XOR_OP_T_A(int64) + +#undef DEFN_BITWISE_XOR_OP_T_A + +#define DEFN_BITWISE_XOR_OP_T_B(tp) \ +template <class X> \ +inline const sc_lv_base \ +operator ^ (tp b, const sc_proxy<X> &px) \ +{ \ + return (px ^ b); \ +} + +DEFN_BITWISE_XOR_OP_T_B(const char *) +DEFN_BITWISE_XOR_OP_T_B(const bool *) +DEFN_BITWISE_XOR_OP_T_B(const sc_logic *) +DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned &) +DEFN_BITWISE_XOR_OP_T_B(const sc_signed &) +DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base &) +DEFN_BITWISE_XOR_OP_T_B(const sc_int_base &) +DEFN_BITWISE_XOR_OP_T_B(unsigned long) +DEFN_BITWISE_XOR_OP_T_B(long) +DEFN_BITWISE_XOR_OP_T_B(unsigned int) +DEFN_BITWISE_XOR_OP_T_B(int) +DEFN_BITWISE_XOR_OP_T_B(uint64) +DEFN_BITWISE_XOR_OP_T_B(int64) + +#undef DEFN_BITWISE_XOR_OP_T_B + +// bitwise left shift +template <class X> +inline const sc_lv_base +sc_proxy<X>::operator << (int n) const +{ + sc_lv_base a(back_cast().length() + n); + a = back_cast(); + return (a <<= n); +} + +// bitwise right shift +template <class X> +inline const sc_lv_base +sc_proxy<X>::operator >> (int n) const +{ + sc_lv_base a(back_cast()); + return (a >>= n); +} + +// bitwise left rotate +template <class X> +inline X & +sc_proxy<X>::lrotate(int n) +{ + X &x = back_cast(); + if (n < 0) { + sc_proxy_out_of_bounds("left rotate operation is only allowed with " + "positive rotate values, rotate value = ", n); + return x; + } + int len = x.length(); + n %= len; + // x = (x << n) | (x >> (len - n)); + sc_lv_base a(x << n); + sc_lv_base b(x >> (len - n)); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + x.set_word(i, a.get_word(i) | b.get_word(i)); + x.set_cword(i, a.get_cword(i) | b.get_cword(i)); + } + x.clean_tail(); + return x; +} + +template <class X> +inline const sc_lv_base +lrotate(const sc_proxy<X> &x, int n) +{ + sc_lv_base a(x.back_cast()); + return a.lrotate(n); +} + +// bitwise right rotate +template <class X> +inline X & +sc_proxy<X>::rrotate(int n) +{ + X &x = back_cast(); + if (n < 0 ) { + sc_proxy_out_of_bounds("right rotate operation is only allowed with " + "positive rotate values, rotate value = ", n); + return x; + } + int len = x.length(); + n %= len; + // x = (x >> n) | (x << (len - n)); + sc_lv_base a(x >> n); + sc_lv_base b(x << (len - n)); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + x.set_word(i, a.get_word(i) | b.get_word(i)); + x.set_cword(i, a.get_cword(i) | b.get_cword(i)); + } + x.clean_tail(); + return x; +} + +template <class X> +inline const sc_lv_base +rrotate(const sc_proxy<X> &x, int n) +{ + sc_lv_base a(x.back_cast()); + return a.rrotate(n); +} + +// bitwise reverse +template <class X> +inline const sc_lv_base +reverse(const sc_proxy<X> &x) +{ + sc_lv_base a(x.back_cast()); + return a.reverse(); +} + +// relational operators +template <class X, class Y> +inline bool +operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + const X &x = px.back_cast(); + const Y &y = py.back_cast(); + int x_len = x.length(); + int y_len = y.length(); + if (x_len != y_len) { + return false; + } + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + if (x.get_word(i) != y.get_word(i) || + x.get_cword(i) != y.get_cword(i)) { + return false; + } + } + return true; +} + +#define DEFN_REL_OP_T(tp) \ +template <class X> \ +inline bool \ +sc_proxy<X>::operator == (tp b) const \ +{ \ + const X &x = back_cast(); \ + sc_lv_base y(x.length()); \ + y = b; \ + return (x == y); \ +} + +DEFN_REL_OP_T(const char *) +DEFN_REL_OP_T(const bool *) +DEFN_REL_OP_T(const sc_logic *) +DEFN_REL_OP_T(const sc_unsigned &) +DEFN_REL_OP_T(const sc_signed &) +DEFN_REL_OP_T(const sc_uint_base &) +DEFN_REL_OP_T(const sc_int_base &) +DEFN_REL_OP_T(unsigned long) +DEFN_REL_OP_T(long) +DEFN_REL_OP_T(unsigned int) +DEFN_REL_OP_T(int) +DEFN_REL_OP_T(uint64) +DEFN_REL_OP_T(int64) + +#undef DEFN_REL_OP_T + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_bitref_r<X> +// +// Proxy class for sc_proxy bit selection (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +operator , (sc_bitref_r<T> a, const char *b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +operator , (const char *a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +operator , (sc_bitref_r<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +operator , (const sc_logic &a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_lv_base,sc_bitref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_bv_base> +operator , (sc_bitref_r<T> a, bool b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_bitref_r<T> > +operator , (bool a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_bv_base, sc_bitref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +concat(sc_bitref_r<T> a, const char *b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +concat(const char *a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +concat(sc_bitref_r<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +concat(const sc_logic &a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_bv_base> +concat(sc_bitref_r<T> a, bool b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_bitref_r<T> > +concat(bool a, sc_bitref_r<T> b) +{ + return sc_concref_r<sc_bv_base, sc_bitref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +operator , (sc_bitref<T> a, const char *b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +operator , (const char *a, sc_bitref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +operator , (sc_bitref<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +operator , (const sc_logic &a, sc_bitref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_bv_base> +operator , (sc_bitref<T> a, bool b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_bitref_r<T> > +operator , (bool a, sc_bitref<T> b) +{ + return sc_concref_r<sc_bv_base, sc_bitref_r<T> > ( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +concat(sc_bitref<T> a, const char *b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +concat(const char *a, sc_bitref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> +concat(sc_bitref<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > +concat(const sc_logic &a, sc_bitref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_bitref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_bitref_r<T>, sc_bv_base> +concat(sc_bitref<T> a, bool b) +{ + return sc_concref_r<sc_bitref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_bitref_r<T> > +concat(bool a, sc_bitref<T> b) +{ + return sc_concref_r<sc_bv_base, sc_bitref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref_r<X> +// +// Proxy class for sc_proxy part selection (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +operator , (sc_subref_r<T> a, const char *b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +operator , (const char *a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +operator , (sc_subref_r<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +operator , (const sc_logic &a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> +operator , (sc_subref_r<T> a, bool b) +{ + return sc_concref_r<sc_subref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > +operator , (bool a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_bv_base, sc_subref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +concat(sc_subref_r<T> a, const char *b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +concat(const char *a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +concat(sc_subref_r<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +concat(const sc_logic &a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> +concat(sc_subref_r<T> a, bool b) +{ + return sc_concref_r<sc_subref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > +concat(bool a, sc_subref_r<T> b) +{ + return sc_concref_r<sc_bv_base, sc_subref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +operator , (sc_subref<T> a, const char *b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +operator , (const char *a, sc_subref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +operator , (sc_subref<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +operator , (const sc_logic &a, sc_subref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> +operator , (sc_subref<T> a, bool b) +{ + return sc_concref_r<sc_subref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > +operator , (bool a, sc_subref<T> b) +{ + return sc_concref_r<sc_bv_base, sc_subref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +concat(sc_subref<T> a, const char *b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +concat(const char *a, sc_subref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_lv_base> +concat(sc_subref<T> a, const sc_logic &b) +{ + return sc_concref_r<sc_subref_r<T>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_lv_base, sc_subref_r<T> > +concat(const sc_logic &a, sc_subref<T> b) +{ + return sc_concref_r<sc_lv_base, sc_subref_r<T> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T> +inline sc_concref_r<sc_subref_r<T>, sc_bv_base> +concat(sc_subref<T> a, bool b) +{ + return sc_concref_r<sc_subref_r<T>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T> +inline sc_concref_r<sc_bv_base, sc_subref_r<T> > +concat(bool a, sc_subref<T> b) +{ + return sc_concref_r<sc_bv_base, sc_subref_r<T> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_subref<X> +// +// Proxy class for sc_proxy part selection (r-value and l-value). +// ---------------------------------------------------------------------------- + +template <class X> +inline sc_subref<X> & +sc_subref<X>::operator = (const sc_subref_r<X> &b) +{ + sc_lv_base t(b); // (partial) self assignment protection + int len = sc_min(this->length(), t.length()); + if (!this->reversed()) { + for (int i = len - 1; i >= 0; --i) { + this->m_obj.set_bit(this->m_lo + i, t[i].value()); + } + } else { + for (int i = len - 1; i >= 0; --i) { + this->m_obj.set_bit(this->m_lo - i, t[i].value()); + } + } + return *this; +} + +template <class X> +inline sc_subref<X> & +sc_subref<X>::operator = (const sc_subref<X> &b) +{ + sc_lv_base t(b); // (partial) self assignment protection + int len = sc_min(this->length(), t.length()); + if (!this->reversed()) { + for (int i = len - 1; i >= 0; --i) { + this->m_obj.set_bit(this->m_lo + i, t[i].value()); + } + } else { + for (int i = len - 1; i >= 0; --i) { + this->m_obj.set_bit(this->m_lo - i, t[i].value()); + } + } + return *this; +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_concref_r<X,Y> +// +// Proxy class for sc_proxy concatenation (r-value only). +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +operator , (sc_concref_r<T1, T2> a, const char *b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +operator , (const char *a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +operator , (sc_concref_r<T1, T2> a, const sc_logic &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +operator , (const sc_logic &a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> +operator , (sc_concref_r<T1, T2> a, bool b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > +operator , (bool a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +concat(sc_concref_r<T1, T2> a, const char *b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +concat(const char *a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +concat(sc_concref_r<T1, T2> a, const sc_logic &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +concat(const sc_logic &a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> +concat(sc_concref_r<T1, T2> a, bool b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > +concat(bool a, sc_concref_r<T1, T2> b) +{ + return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +operator , (sc_concref<T1, T2> a, const char *b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +operator , (const char *a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +operator , (sc_concref<T1, T2> a, const sc_logic &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +operator , (const sc_logic &a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> +operator , (sc_concref<T1, T2> a, bool b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > +operator , (bool a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +concat(sc_concref<T1, T2> a, const char *b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +concat(const char *a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> +concat(sc_concref<T1, T2> a, const sc_logic &b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>( + *a.clone(), *new sc_lv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > +concat(const sc_logic &a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >( + *new sc_lv_base(a, 1), *b.clone(), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> +concat(sc_concref<T1, T2> a, bool b) +{ + return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>( + *a.clone(), *new sc_bv_base(b, 1), 3); +} + +template <class T1, class T2> +inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > +concat(bool a, sc_concref<T1, T2> b) +{ + return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >( + *new sc_bv_base(a, 1), *b.clone(), 3); +} + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy<T> +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +// r-value concatenation operators and functions + +template <class T> +inline sc_concref_r<T, sc_lv_base> +operator , (const sc_proxy<T> &a, const char *b) +{ + return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +operator , (const char *a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_lv_base> +operator , (const sc_proxy<T> &a, const sc_logic &b) +{ + return sc_concref_r<T, sc_lv_base>( + a.back_cast(), *new sc_lv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +operator , (const sc_logic &a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>( + *new sc_lv_base(a, 1), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_bv_base> +operator , (const sc_proxy<T> &a, bool b) +{ + return sc_concref_r<T, sc_bv_base>( + a.back_cast(), *new sc_bv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_bv_base, T> +operator , (bool a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_bv_base, T>( + *new sc_bv_base(a, 1), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_lv_base> +concat(const sc_proxy<T> &a, const char *b) +{ + return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +concat(const char *a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_lv_base> +concat(const sc_proxy<T> &a, const sc_logic &b) +{ + return sc_concref_r<T, sc_lv_base>( + a.back_cast(), *new sc_lv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +concat(const sc_logic &a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>( + *new sc_lv_base(a, 1), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_bv_base> +concat(const sc_proxy<T> &a, bool b) +{ + return sc_concref_r<T, sc_bv_base>( + a.back_cast(), *new sc_bv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_bv_base, T> +concat(bool a, const sc_proxy<T> &b) +{ + return sc_concref_r<sc_bv_base, T>( + *new sc_bv_base(a, 1), b.back_cast(), 1); +} + + +template <class T> +inline sc_concref_r<T, sc_lv_base> +operator , (sc_proxy<T> &a, const char *b) +{ + return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +operator , (const char *a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_lv_base> +operator , (sc_proxy<T> &a, const sc_logic &b) +{ + return sc_concref_r<T, sc_lv_base>( + a.back_cast(), *new sc_lv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +operator , (const sc_logic &a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>( + *new sc_lv_base(a, 1), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_bv_base> +operator , (sc_proxy<T> &a, bool b) +{ + return sc_concref_r<T, sc_bv_base>( + a.back_cast(), *new sc_bv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_bv_base, T> +operator , (bool a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_bv_base, T>( + *new sc_bv_base(a, 1), b.back_cast(), 1); +} + + +template <class T> +inline sc_concref_r<T, sc_lv_base> +concat(sc_proxy<T> &a, const char *b) +{ + return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +concat(const char *a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_lv_base> +concat(sc_proxy<T> &a, const sc_logic &b) +{ + return sc_concref_r<T, sc_lv_base>( + a.back_cast(), *new sc_lv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_lv_base, T> +concat(const sc_logic &a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_lv_base, T>( + *new sc_lv_base(a, 1), b.back_cast(), 1); +} + +template <class T> +inline sc_concref_r<T, sc_bv_base> +concat(sc_proxy<T> &a, bool b) +{ + return sc_concref_r<T, sc_bv_base>( + a.back_cast(), *new sc_bv_base(b, 1), 2); +} + +template <class T> +inline sc_concref_r<sc_bv_base, T> +concat(bool a, sc_proxy<T> &b) +{ + return sc_concref_r<sc_bv_base, T>( + *new sc_bv_base(a, 1), b.back_cast(), 1); +} + +// extern template instantiations +extern template class sc_proxy<sc_lv_base>; +extern template class sc_proxy<sc_bv_base>; + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__ diff --git a/src/systemc/ext/dt/bit/sc_proxy.hh b/src/systemc/ext/dt/bit/sc_proxy.hh new file mode 100644 index 000000000..cf7bcbfc9 --- /dev/null +++ b/src/systemc/ext/dt/bit/sc_proxy.hh @@ -0,0 +1,1394 @@ +/***************************************************************************** + + 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_proxy.h -- Proxy base class for vector data types. + + This class is created for several purposes: + 1) hiding operators from the global namespace that would be + otherwise found by Koenig lookup + 2) avoiding repeating the same operations in every class + including proxies that could also be achieved by common + base class, but this method allows + 3) improve performance by using non-virtual functions + + Original Author: Gene Bushuyev, Synopsys, Inc. + + *****************************************************************************/ + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + *****************************************************************************/ + +// $Log: sc_proxy.h,v $ +// Revision 1.3 2010/12/07 20:09:07 acg +// Andy Goodrich: Fix for returning enough data +// +// Revision 1.2 2009/02/28 00:26:14 acg +// Andy Goodrich: bug fixes. +// +// Revision 1.1.1.1 2006/12/15 20:31:36 acg +// SystemC 2.2 +// +// Revision 1.3 2006/01/13 18:53:53 acg +// Andy Goodrich: added $Log command so that CVS comments are reproduced in +// the source. +// + +#ifndef __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ +#define __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ + +#include <iostream> + +#include "../../utils/functions.hh" +#include "../int/sc_int_base.hh" +#include "../int/sc_signed.hh" +#include "../int/sc_uint_base.hh" +#include "../int/sc_unsigned.hh" +#include "sc_bit.hh" +#include "sc_logic.hh" + +namespace sc_dt +{ + +// classes defined in this module +template <class X> +class sc_proxy; + +// forward class declarations +class sc_bv_base; +class sc_lv_base; +template <class X> +class sc_bitref_r; +template <class X> +class sc_bitref; +template <class X> +class sc_subref_r; +template <class X> +class sc_subref; +template <class X, class Y> +class sc_concref_r; +template <class X, class Y> +class sc_concref; + +const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof(sc_digit); + +const sc_digit SC_DIGIT_ZERO = (sc_digit)0; +const sc_digit SC_DIGIT_ONE = (sc_digit)1; +const sc_digit SC_DIGIT_TWO = (sc_digit)2; + +void sc_proxy_out_of_bounds(const char *msg=NULL, int64 val=0); + +// assignment functions; forward declarations + +template <class X, class Y> +inline void assign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py); + +// Vector types that are not derived from sc_proxy must have a length() +// function and an operator []. + +template <class X, class T> +inline void assign_v_(sc_proxy<X> &px, const T &a); + +// other functions; forward declarations +const std::string convert_to_bin(const char *s); +const std::string convert_to_fmt(const std::string &s, sc_numrep numrep, bool); + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy_traits +// +// Template traits helper to select the correct bit/value/vector_types for +// sc_proxy-based vector classes. +// +// All types derived from/based on a bit-vector contain typedef to a plain +// bool, all others point to the sc_logic_value_t/sc_logic/sc_lv_base types. +// ---------------------------------------------------------------------------- + +template <typename X> +struct sc_proxy_traits; + +template <> +struct sc_proxy_traits<sc_bv_base> +{ + typedef sc_proxy_traits<sc_bv_base> traits_type; + typedef bool value_type; + typedef sc_logic bit_type; // sc_logic needed for mixed expressions + typedef sc_bv_base vector_type; +}; + +template <> +struct sc_proxy_traits<sc_lv_base> +{ + typedef sc_proxy_traits<sc_lv_base> traits_type; + typedef sc_logic_value_t value_type; + typedef sc_logic bit_type; + typedef sc_lv_base vector_type; +}; + +template <typename X> +struct sc_proxy_traits<sc_bitref_r<X> > : sc_proxy_traits<X> {}; + +template <typename X> +struct sc_proxy_traits<sc_bitref<X> > : sc_proxy_traits<X> {}; + +template <typename X> +struct sc_proxy_traits<sc_subref_r<X> > : sc_proxy_traits<X> {}; + +template <typename X> +struct sc_proxy_traits<sc_subref<X> > : sc_proxy_traits<X> {}; + +template <typename X> +struct sc_proxy_traits<sc_proxy<X> > : sc_proxy_traits<X> {}; + + +template <typename X, typename Y> +struct sc_mixed_proxy_traits_helper : sc_proxy_traits<sc_lv_base> +{}; // logic vector by default + +template <typename X> +struct sc_mixed_proxy_traits_helper<X, X> : X {}; + +template <typename X, typename Y> +struct sc_proxy_traits<sc_concref_r<X, Y> > : + sc_mixed_proxy_traits_helper< + typename X::traits_type, typename Y::traits_type> +{}; + +template <typename X, typename Y> +struct sc_proxy_traits<sc_concref<X, Y> > : + sc_mixed_proxy_traits_helper< + typename X::traits_type, typename Y::traits_type> +{}; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_proxy +// +// Base class template for bit/logic vector classes. +// (Barton/Nackmann implementation) +// ---------------------------------------------------------------------------- + +template <class X> +class sc_proxy // #### : public sc_value_base +{ + public: + typedef typename sc_proxy_traits<X>::traits_type traits_type; + typedef typename traits_type::bit_type bit_type; + typedef typename traits_type::value_type value_type; + + // virtual destructor + virtual ~sc_proxy() {} + + // casts + X &back_cast() { return static_cast<X &>(*this); } + + const X &back_cast() const { return static_cast<const X &>(*this); } + + // assignment operators + template <class Y> + X & + assign_(const sc_proxy<Y> &a) + { + assign_p_(*this, a); + return back_cast(); + } + + X &assign_(const char *a); + X &assign_(const bool *a); + X &assign_(const sc_logic *a); + + X & + assign_(const sc_unsigned &a) + { + assign_v_(*this, a); + return back_cast(); + } + + X & + assign_(const sc_signed &a) + { + assign_v_(*this, a); + return back_cast(); + } + + X &assign_(const sc_uint_base &a) { return assign_((uint64)a); } + X &assign_(const sc_int_base &a) { return assign_((int64)a); } + X &assign_(unsigned int a); + X &assign_(int a); + X &assign_(unsigned long a); + X &assign_(long a); + X &assign_(uint64 a); + X &assign_(int64 a); + + // bitwise operators and functions + + // bitwise complement + X &b_not(); + + const sc_lv_base operator ~ () const; + + // bitwise and + X &operator &= (const char *b); + X &operator &= (const bool *b); + X &operator &= (const sc_logic *b); + X &operator &= (const sc_unsigned &b); + X &operator &= (const sc_signed &b); + X &operator &= (const sc_uint_base &b) { return operator &= ((uint64)b); } + X &operator &= (const sc_int_base &b) { return operator &= ((int64)b); } + X &operator &= (unsigned long b); + X &operator &= (long b); + X &operator &= (unsigned int b) { return operator &= ((unsigned long)b); } + X &operator &= (int b) { return operator &= ((long)b); } + X &operator &= (uint64 b); + X &operator &= (int64 b); + + const sc_lv_base operator & (const char *b) const; + const sc_lv_base operator & (const bool *b) const; + const sc_lv_base operator & (const sc_logic *b) const; + const sc_lv_base operator & (const sc_unsigned &b) const; + const sc_lv_base operator & (const sc_signed &b) const; + const sc_lv_base operator & (const sc_uint_base &b) const; + const sc_lv_base operator & (const sc_int_base &b) const; + const sc_lv_base operator & (unsigned long b) const; + const sc_lv_base operator & (long b) const; + const sc_lv_base operator & (unsigned int b) const; + const sc_lv_base operator & (int b) const; + const sc_lv_base operator & (uint64 b) const; + const sc_lv_base operator & (int64 b) const; + + // bitwise or + X &operator |= (const char *b); + X &operator |= (const bool *b); + X &operator |= (const sc_logic *b); + X &operator |= (const sc_unsigned &b); + X &operator |= (const sc_signed &b); + X &operator |= (const sc_uint_base &b) { return operator |= ((uint64)b); } + X &operator |= (const sc_int_base &b) { return operator |= ((int64)b); } + X &operator |= (unsigned long b); + X &operator |= (long b); + X &operator |= (unsigned int b) { return operator |= ((unsigned long)b); } + X &operator |= (int b) { return operator |= ((long)b); } + X &operator |= (uint64 b); + X &operator |= (int64 b); + + const sc_lv_base operator | (const char *b) const; + const sc_lv_base operator | (const bool *b) const; + const sc_lv_base operator | (const sc_logic *b) const; + const sc_lv_base operator | (const sc_unsigned &b) const; + const sc_lv_base operator | (const sc_signed &b) const; + const sc_lv_base operator | (const sc_uint_base &b) const; + const sc_lv_base operator | (const sc_int_base &b) const; + const sc_lv_base operator | (unsigned long b) const; + const sc_lv_base operator | (long b) const; + const sc_lv_base operator | (unsigned int b) const; + const sc_lv_base operator | (int b) const; + const sc_lv_base operator | (uint64 b) const; + const sc_lv_base operator | (int64 b) const; + + // bitwise xor + X &operator ^= (const char *b); + X &operator ^= (const bool *b); + X &operator ^= (const sc_logic *b); + X &operator ^= (const sc_unsigned &b); + X &operator ^= (const sc_signed &b); + X &operator ^= (const sc_uint_base &b) { return operator ^= ((uint64)b); } + X &operator ^= (const sc_int_base &b) { return operator ^= ((int64)b); } + X &operator ^= (unsigned long b); + X &operator ^= (long b); + X &operator ^= (unsigned int b) { return operator ^= ((unsigned long)b); } + X &operator ^= (int b) { return operator ^= ((long)b); } + X &operator ^= (uint64 b); + X &operator ^= (int64 b); + + const sc_lv_base operator ^ (const char *b) const; + const sc_lv_base operator ^ (const bool *b) const; + const sc_lv_base operator ^ (const sc_logic *b) const; + const sc_lv_base operator ^ (const sc_unsigned &b) const; + const sc_lv_base operator ^ (const sc_signed &b) const; + const sc_lv_base operator ^ (const sc_uint_base &b) const; + const sc_lv_base operator ^ (const sc_int_base &b) const; + const sc_lv_base operator ^ (unsigned long b) const; + const sc_lv_base operator ^ (long b) const; + const sc_lv_base operator ^ (unsigned int b) const; + const sc_lv_base operator ^ (int b) const; + const sc_lv_base operator ^ (uint64 b) const; + const sc_lv_base operator ^ (int64 b) const; + + // bitwise left shift + X &operator <<= (int n); + const sc_lv_base operator << (int n) const; + + // bitwise right shift + X &operator >>= (int n); + const sc_lv_base operator >> (int n) const; + + // bitwise left rotate + X &lrotate(int n); + + // bitwise right rotate + X &rrotate(int n); + + // bitwise reverse + X &reverse(); + + // bit selection + sc_bitref<X> operator [] (int i) { return sc_bitref<X>(back_cast(), i); } + sc_bitref_r<X> + operator [] (int i) const + { + return sc_bitref_r<X>(back_cast(), i); + } + sc_bitref<X> bit(int i) { return sc_bitref<X>(back_cast(), i); } + sc_bitref_r<X> bit(int i) const { return sc_bitref_r<X>(back_cast(), i); } + + // part selection + sc_subref<X> + operator () (int hi, int lo) + { + return sc_subref<X>(back_cast(), hi, lo); + } + sc_subref_r<X> + operator () (int hi, int lo) const + { + return sc_subref_r<X>(back_cast(), hi, lo); + } + sc_subref<X> + range(int hi, int lo) + { + return sc_subref<X>(back_cast(), hi, lo); + } + sc_subref_r<X> + range(int hi, int lo) const + { + return sc_subref_r<X>(back_cast(), hi, lo); + } + + // reduce functions + value_type and_reduce() const; + value_type + nand_reduce() const + { + return sc_logic::not_table[and_reduce()]; + } + value_type or_reduce() const; + value_type nor_reduce() const { return sc_logic::not_table[or_reduce()]; } + value_type xor_reduce() const; + value_type + xnor_reduce() const + { + return sc_logic::not_table[xor_reduce()]; + } + + // relational operators + bool operator == (const char *b) const; + bool operator == (const bool *b) const; + bool operator == (const sc_logic *b) const; + bool operator == (const sc_unsigned &b) const; + bool operator == (const sc_signed &b) const; + bool operator == (const sc_uint_base &b) const; + bool operator == (const sc_int_base &b) const; + bool operator == (unsigned long b) const; + bool operator == (long b) const; + bool operator == (unsigned int b) const; + bool operator == (int b) const; + bool operator == (uint64 b) const; + bool operator == (int64 b) const; + + // explicit conversions to character string + const std::string to_string() const; + const std::string to_string(sc_numrep) const; + const std::string to_string(sc_numrep, bool) const; + + // explicit conversions + inline int64 to_int64() const { return to_anything_signed(); } + inline uint64 to_uint64() const; + int to_int() const { return (int)to_anything_signed(); } + + unsigned int + to_uint() const + { + return (unsigned int)to_anything_unsigned(); + } + + long to_long() const { return (long)to_anything_signed(); } + + unsigned long + to_ulong() const + { + return (unsigned long)to_anything_unsigned(); + } + + // other methods + void + print(::std::ostream &os=::std::cout) const + { + // The test below will force printing in binary if decimal is + // specified. + if (sc_io_base(os, SC_DEC) == SC_DEC) + os << to_string(); + else + os << to_string(sc_io_base(os, SC_BIN), sc_io_show_base(os)); + } + + void scan(::std::istream &is=::std::cin); + + protected: + void check_bounds(int n) const; // check if bit n accessible + void check_wbounds(int n) const; // check if word n accessible + + sc_digit to_anything_unsigned() const; + int64 to_anything_signed() const; +}; + + +// ---------------------------------------------------------------------------- + +// bitwise operators and functions + +// bitwise and + +template <class X, class Y> +inline X &operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py); + + +template <class X, class Y> +inline const sc_lv_base operator & ( + const sc_proxy<X> &px, const sc_proxy<Y> &py); + + +#define DECL_BITWISE_AND_OP_T(tp) \ +template <class X> \ +inline const sc_lv_base operator & (tp b, const sc_proxy<X> &px); + +DECL_BITWISE_AND_OP_T(const char *) +DECL_BITWISE_AND_OP_T(const bool *) +DECL_BITWISE_AND_OP_T(const sc_logic *) +DECL_BITWISE_AND_OP_T(const sc_unsigned &) +DECL_BITWISE_AND_OP_T(const sc_signed &) +DECL_BITWISE_AND_OP_T(const sc_uint_base &) +DECL_BITWISE_AND_OP_T(const sc_int_base &) +DECL_BITWISE_AND_OP_T(unsigned long) +DECL_BITWISE_AND_OP_T(long) +DECL_BITWISE_AND_OP_T(unsigned int) +DECL_BITWISE_AND_OP_T(int) +DECL_BITWISE_AND_OP_T(uint64) +DECL_BITWISE_AND_OP_T(int64) + +#undef DECL_BITWISE_AND_OP_T + +// bitwise or +template <class X, class Y> +inline X &operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py); + +template <class X, class Y> +inline const sc_lv_base operator | ( + const sc_proxy<X> &px, const sc_proxy<Y> &py); + + +#define DECL_BITWISE_OR_OP_T(tp) \ +template <class X> \ +inline const sc_lv_base operator | (tp a, const sc_proxy<X> &px); + +DECL_BITWISE_OR_OP_T(const char *) +DECL_BITWISE_OR_OP_T(const bool *) +DECL_BITWISE_OR_OP_T(const sc_logic *) +DECL_BITWISE_OR_OP_T(const sc_unsigned &) +DECL_BITWISE_OR_OP_T(const sc_signed &) +DECL_BITWISE_OR_OP_T(const sc_uint_base &) +DECL_BITWISE_OR_OP_T(const sc_int_base &) +DECL_BITWISE_OR_OP_T(unsigned long) +DECL_BITWISE_OR_OP_T(long) +DECL_BITWISE_OR_OP_T(unsigned int) +DECL_BITWISE_OR_OP_T(int) +DECL_BITWISE_OR_OP_T(uint64) +DECL_BITWISE_OR_OP_T(int64) + +#undef DECL_BITWISE_OR_OP_T + +// bitwise xor +template <class X, class Y> +inline X &operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py); + +template <class X, class Y> +inline const sc_lv_base operator ^ ( + const sc_proxy<X> &px, const sc_proxy<Y> &py); + +#define DECL_BITWISE_XOR_OP_T(tp) \ +template <class X> \ +inline const sc_lv_base operator ^ (tp a, const sc_proxy<X> &px); + +DECL_BITWISE_XOR_OP_T(const char *) +DECL_BITWISE_XOR_OP_T(const bool *) +DECL_BITWISE_XOR_OP_T(const sc_logic *) +DECL_BITWISE_XOR_OP_T(const sc_unsigned &) +DECL_BITWISE_XOR_OP_T(const sc_signed &) +DECL_BITWISE_XOR_OP_T(const sc_uint_base &) +DECL_BITWISE_XOR_OP_T(const sc_int_base &) +DECL_BITWISE_XOR_OP_T(unsigned long) +DECL_BITWISE_XOR_OP_T(long) +DECL_BITWISE_XOR_OP_T(unsigned int) +DECL_BITWISE_XOR_OP_T(int) +DECL_BITWISE_XOR_OP_T(uint64) +DECL_BITWISE_XOR_OP_T(int64) + +#undef DECL_BITWISE_XOR_OP_T + +// relational operators +template <class X, class Y> +inline bool operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py); + +template <class X, class Y> +inline bool operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py); + +#define DECL_REL_OP_T(tp) \ +template <class X> \ +inline bool operator == (tp b, const sc_proxy<X> &px); \ + \ +template <class X> \ +inline bool operator != (const sc_proxy<X> &px, tp b); \ + \ +template <class X> \ +inline bool operator != (tp b, const sc_proxy<X> &px); + +DECL_REL_OP_T(const char *) +DECL_REL_OP_T(const bool *) +DECL_REL_OP_T(const sc_logic *) +DECL_REL_OP_T(const sc_unsigned &) +DECL_REL_OP_T(const sc_signed &) +DECL_REL_OP_T(const sc_uint_base &) +DECL_REL_OP_T(const sc_int_base &) +DECL_REL_OP_T(unsigned long) +DECL_REL_OP_T(long) +DECL_REL_OP_T(unsigned int) +DECL_REL_OP_T(int) +DECL_REL_OP_T(uint64) +DECL_REL_OP_T(int64) + +#undef DECL_REL_OP_T + +// l-value concatenation + +// Due to the fact that temporary objects cannot be passed to non-const +// references, we have to enumerate, use call by value, and use dynamic +// memory allocation (and deallocation). + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +template <class X> +inline void +get_words_(const X &x, int wi, sc_digit &x_dw, sc_digit &x_cw) +{ + x_dw = x.get_word(wi); + x_cw = x.get_cword(wi); +} + +template <class X> +inline void +set_words_(X &x, int wi, sc_digit x_dw, sc_digit x_cw) +{ + x.set_word(wi, x_dw); + x.set_cword(wi, x_cw); +} + +template <class X> +inline void +extend_sign_w_(X &x, int wi, bool sign) +{ + int sz = x.size(); + unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO); + for (int i = wi; i < sz; ++i) { + set_words_(x, i, sgn, SC_DIGIT_ZERO); + } +} + +// assignment functions +template <class X, class Y> +inline void +assign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + if ((void *)&px != (void *)&py) { + X &x = px.back_cast(); + const Y &y = py.back_cast(); + int sz = x.size(); + int min_sz = sc_min(sz, y.size()); + int i = 0; + for (; i < min_sz; ++i) { + set_words_(x, i, y.get_word(i), y.get_cword(i)); + } + // extend with zeros + extend_sign_w_(x, i, false); + x.clean_tail(); + } +} + +// Vector types that are not derived from sc_proxy, sc_int_base, +// sc_uint_base, sc_signed, or sc_unsigned, must have a length() +// function and an operator []. The vector argument type must support +// accessing bits that are beyond the msb. The vector argument type +// decides what to do there (e.g. sign extension or zero padding). + +template <class X, class T> +inline void +assign_v_(sc_proxy<X> &px, const T &a) +{ + X &x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if (len_a > len_x) + len_a = len_x; + for (i = 0; i < len_a; ++i) { + x.set_bit(i, sc_logic_value_t((bool)a[i])); + } + for (; i < len_x; ++i) { + x.set_bit(i, sc_logic_value_t(false)); + } +} + +template <class X> +inline void +assign_v_(sc_proxy<X> &px, const sc_int_base &a) +{ + X &x = px.back_cast(); + int i; + bool sign = a < 0; + int len_x = x.length(); + int len_a = a.length(); + if ( len_a > len_x ) len_a = len_x; + for (i = 0; i < len_a; ++i) { + x.set_bit(i, sc_logic_value_t((bool)a[i])); + } + for (; i < len_x; ++i) { + x.set_bit(i, sc_logic_value_t(sign)); + } +} + +template <class X> +inline void +assign_v_(sc_proxy<X> &px, const sc_signed &a) +{ + X &x = px.back_cast(); + int i; + bool sign = a < 0; + int len_x = x.length(); + int len_a = a.length(); + if (len_a > len_x) + len_a = len_x; + for (i = 0; i < len_a; ++i) { + x.set_bit(i, sc_logic_value_t((bool)a[i])); + } + for (; i < len_x; ++i) { + x.set_bit(i, sc_logic_value_t(sign)); + } +} + +template <class X> +inline void +assign_v_(sc_proxy<X> &px, const sc_uint_base &a) +{ + X &x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if (len_a > len_x) + len_a = len_x; + for (i = 0; i < len_a; ++i) { + x.set_bit(i, sc_logic_value_t((bool)a[i])); + } + for (; i < len_x; ++i) { + x.set_bit(i, sc_logic_value_t(false)); + } +} + +template <class X> +inline void +assign_v_(sc_proxy<X> &px, const sc_unsigned &a) +{ + X &x = px.back_cast(); + int i; + int len_x = x.length(); + int len_a = a.length(); + if (len_a > len_x) + len_a = len_x; + for (i = 0; i < len_a; ++i) { + x.set_bit(i, sc_logic_value_t((bool)a[i])); + } + for (; i < len_x; ++i) { + x.set_bit(i, sc_logic_value_t(false)); + } +} + +// assignment operators +template <class X> +inline X & +sc_proxy<X>::assign_(const char *a) +{ + X &x = back_cast(); + std::string s = convert_to_bin(a); + int len = x.length(); + int s_len = s.length() - 1; + int min_len = sc_min(len, s_len); + int i = 0; + for (; i < min_len; ++i) { + char c = s[s_len - i - 1]; + x.set_bit(i, sc_logic::char_to_logic[(int)c]); + } + // if formatted, fill the rest with sign(s), otherwise fill with zeros + sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0') + : sc_logic_value_t(0)); + for (; i < len; ++i) { + x.set_bit(i, fill); + } + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(const bool *a) +{ + // the length of 'a' must be larger than or equal to the length of 'this' + X &x = back_cast(); + int len = x.length(); + for (int i = 0; i < len; ++i) { + x.set_bit(i, sc_logic_value_t(a[i])); + } + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(const sc_logic *a) +{ + // the length of 'a' must be larger than or equal to the length of 'this' + X &x = back_cast(); + int len = x.length(); + for (int i = 0; i < len; ++i) { + x.set_bit(i, a[i].value()); + } + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(unsigned int a) +{ + X &x = back_cast(); + set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); + // extend with zeros + extend_sign_w_(x, 1, false); + x.clean_tail(); + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(int a) +{ + X &x = back_cast(); + set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); + // extend with sign(a) + extend_sign_w_(x, 1, (a < 0)); + x.clean_tail(); + return x; +} + +#if defined(SC_LONG_64) +template <class X> +inline X & +sc_proxy<X>::assign_(unsigned long a) +{ + X &x = back_cast(); + set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); + if (x.size() > 1) { + set_words_(x, 1, ((sc_digit)(a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO); + // extend with zeros + extend_sign_w_(x, 2, false); + } + x.clean_tail(); + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(long a) +{ + X &x = back_cast(); + set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); + if (x.size() > 1) { + set_words_(x, 1, + ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO); + // extend with sign(a) + extend_sign_w_(x, 2, (a < 0)); + } + x.clean_tail(); + return x; +} + +#else + +template <class X> +inline X & +sc_proxy<X>::assign_(unsigned long a) +{ + X &x = back_cast(); + set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); + // extend with zeros + extend_sign_w_(x, 1, false); + x.clean_tail(); + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(long a) +{ + X &x = back_cast(); + set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO); + // extend with sign(a) + extend_sign_w_(x, 1, (a < 0)); + x.clean_tail(); + return x; +} + +#endif + +template <class X> +inline X & +sc_proxy<X>::assign_(uint64 a) +{ + X &x = back_cast(); + set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); + if (x.size() > 1) { + set_words_(x, 1, ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with zeros + extend_sign_w_(x, 2, false); + } + x.clean_tail(); + return x; +} + +template <class X> +inline X & +sc_proxy<X>::assign_(int64 a) +{ + X &x = back_cast(); + set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO); + if (x.size() > 1) { + set_words_(x, 1, + ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO), + SC_DIGIT_ZERO ); + // extend with sign(a) + extend_sign_w_(x, 2, (a < 0)); + } + x.clean_tail(); + return x; +} + +// bitwise operators and functions + +// bitwise complement +template <class X> +inline X & +sc_proxy<X>::b_not() +{ + X &x = back_cast(); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + sc_digit x_dw, x_cw; + get_words_(x, i, x_dw, x_cw); + x.set_word(i, x_cw | ~x_dw); + } + x.clean_tail(); + return x; +} + +// bitwise and +template <class X, class Y> +inline X & +b_and_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + X &x = px.back_cast(); + const Y &y = py.back_cast(); + sc_assert(x.length() == y.length()); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_(x, i, x_dw, x_cw); + get_words_(y, i, y_dw, y_cw); + sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw); + sc_digit dw = cw | (x_dw & y_dw); + set_words_(x, i, dw, cw); + } + // tail cleaning not needed + return x; +} + +// bitwise or +template <class X, class Y> +inline X & +b_or_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + X &x = px.back_cast(); + const Y &y = py.back_cast(); + sc_assert(x.length() == y.length()); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_(x, i, x_dw, x_cw); + get_words_(y, i, y_dw, y_cw); + sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw); + sc_digit dw = cw | x_dw | y_dw; + set_words_(x, i, dw, cw); + } + // tail cleaning not needed + return x; +} + +// bitwise xor +template <class X, class Y> +inline X & +b_xor_assign_(sc_proxy<X> &a, const sc_proxy<Y> &b) +{ + X &x = a.back_cast(); + const Y &y = b.back_cast(); + sc_assert(x.length() == y.length()); + int sz = x.size(); + for (int i = 0; i < sz; ++i) { + sc_digit x_dw, x_cw, y_dw, y_cw; + get_words_(x, i, x_dw, x_cw); + get_words_(y, i, y_dw, y_cw); + sc_digit cw = x_cw | y_cw; + sc_digit dw = cw | (x_dw ^ y_dw); + set_words_( x, i, dw, cw ); + } + // tail cleaning not needed + return x; +} + +// bitwise left shift +template <class X> +inline X & +sc_proxy<X>::operator <<= (int n) +{ + X &x = back_cast(); + if (n < 0) { + sc_proxy_out_of_bounds("left shift operation is only allowed with " + "positive shift values, shift value = ", n); + return x; + } + if (n >= x.length()) { + extend_sign_w_(x, 0, false); + // no tail cleaning needed + return x; + } + int sz = x.size(); + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if (wn != 0) { + // shift words + int i = sz - 1; + for (; i >= wn; --i) { + set_words_(x, i, x.get_word(i - wn), x.get_cword(i - wn)); + } + for (; i >= 0; --i) { + set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO); + } + } + if (bn != 0) { + // shift bits + for (int i = sz - 1; i >= 1; --i) { + sc_digit x_dw, x_cw; + get_words_(x, i, x_dw, x_cw); + x_dw <<= bn; + x_dw |= x.get_word(i - 1) >> (SC_DIGIT_SIZE - bn); + x_cw <<= bn; + x_cw |= x.get_cword(i - 1) >> (SC_DIGIT_SIZE - bn); + set_words_(x, i, x_dw, x_cw); + } + sc_digit x_dw, x_cw; + get_words_(x, 0, x_dw, x_cw); + x_dw <<= bn; + x_cw <<= bn; + set_words_(x, 0, x_dw, x_cw); + } + x.clean_tail(); + return x; +} + +// bitwise right shift +template <class X> +inline X & +sc_proxy<X>::operator >>= (int n) +{ + X &x = back_cast(); + if (n < 0) { + sc_proxy_out_of_bounds("right shift operation is only allowed with " + "positive shift values, shift value = ", n); + return x; + } + if (n >= x.length()) { + extend_sign_w_(x, 0, false); + // no tail cleaning needed + return x; + } + int sz = x.size(); + int wn = n / SC_DIGIT_SIZE; + int bn = n % SC_DIGIT_SIZE; + if (wn != 0) { + // shift words + int i = 0; + for (; i < (sz - wn); ++i) { + set_words_(x, i, x.get_word(i + wn), x.get_cword(i + wn)); + } + for (; i < sz; ++i) { + set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO); + } + } + if (bn != 0) { + // shift bits + for (int i = 0; i < (sz - 1); ++i) { + sc_digit x_dw, x_cw; + get_words_(x, i, x_dw, x_cw); + x_dw >>= bn; + x_dw |= x.get_word(i + 1) << (SC_DIGIT_SIZE - bn); + x_cw >>= bn; + x_cw |= x.get_cword(i + 1) << (SC_DIGIT_SIZE - bn); + set_words_(x, i, x_dw, x_cw); + } + sc_digit x_dw, x_cw; + get_words_(x, sz - 1, x_dw, x_cw); + x_dw >>= bn; + x_cw >>= bn; + set_words_(x, sz - 1, x_dw, x_cw); + } + x.clean_tail(); + return x; +} + +// bitwise left rotate +template <class X> +inline const sc_lv_base lrotate(const sc_proxy<X> &x, int n); + +// bitwise right rotate +template <class X> +inline const sc_lv_base rrotate(const sc_proxy<X>& x, int n); + +// bitwise reverse +template <class X> +inline X & +sc_proxy<X>::reverse() +{ + X &x = back_cast(); + int len = x.length(); + int half_len = len / 2; + for (int i = 0, j = len - 1; i < half_len; ++ i, --j) { + value_type t = x.get_bit(i); + x.set_bit(i, x.get_bit(j)); + x.set_bit(j, t); + } + return x; +} + +template <class X> +inline const sc_lv_base reverse(const sc_proxy<X> &a); + +// reduce functions +template <class X> +inline typename sc_proxy<X>::value_type +sc_proxy<X>::and_reduce() const +{ + const X &x = back_cast(); + value_type result = value_type(1); + int len = x.length(); + for (int i = 0; i < len; ++i) { + result = sc_logic::and_table[result][x.get_bit(i)]; + } + return result; +} + +template <class X> +inline typename sc_proxy<X>::value_type +sc_proxy<X>::or_reduce() const +{ + const X &x = back_cast(); + value_type result = value_type(0); + int len = x.length(); + for (int i = 0; i < len; ++i) { + result = sc_logic::or_table[result][x.get_bit(i)]; + } + return result; +} + +template <class X> +inline typename sc_proxy<X>::value_type +sc_proxy<X>::xor_reduce() const +{ + const X &x = back_cast(); + value_type result = value_type(0); + int len = x.length(); + for (int i = 0; i < len; ++i) { + result = sc_logic::xor_table[result][x.get_bit(i)]; + } + return result; +} + +// relational operators +template <class X, class Y> +inline bool +operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py) +{ + return !(px == py); +} + + +#define DEFN_REL_OP_T(tp) \ +template <class X> \ +inline bool operator == (tp b, const sc_proxy<X> &px) { return (px == b); } \ + \ +template <class X> \ +inline bool operator != (const sc_proxy<X> &px, tp b) { return !(px == b); } \ + \ +template <class X> \ +inline bool operator != (tp b, const sc_proxy<X> &px) { return !(px == b); } + +DEFN_REL_OP_T(const char *) +DEFN_REL_OP_T(const bool *) +DEFN_REL_OP_T(const sc_logic *) +DEFN_REL_OP_T(const sc_unsigned &) +DEFN_REL_OP_T(const sc_signed &) +DEFN_REL_OP_T(const sc_uint_base &) +DEFN_REL_OP_T(const sc_int_base &) +DEFN_REL_OP_T(unsigned long) +DEFN_REL_OP_T(long) +DEFN_REL_OP_T(unsigned int) +DEFN_REL_OP_T(int) +DEFN_REL_OP_T(uint64) +DEFN_REL_OP_T(int64) + +#undef DEFN_REL_OP_T + +// explicit conversions to character string +template <class X> +inline const std::string +sc_proxy<X>::to_string() const +{ + const X &x = back_cast(); + int len = x.length(); + std::string s; // (len + 1); + for (int i = 0; i < len; ++i) { + s += sc_logic::logic_to_char[x.get_bit(len - i - 1)]; + } + return s; +} + +template <class X> +inline const std::string +sc_proxy<X>::to_string(sc_numrep numrep) const +{ + return convert_to_fmt(to_string(), numrep, true); +} + +template <class X> +inline const std::string +sc_proxy<X>::to_string(sc_numrep numrep, bool w_prefix) const +{ + return convert_to_fmt(to_string(), numrep, w_prefix); +} + +// other methods +template <class X> +inline void +sc_proxy<X>::scan(::std::istream &is) +{ + std::string s; + is >> s; + back_cast() = s.c_str(); +} + +template <class X> +inline void +sc_proxy<X>::check_bounds(int n) const // check if bit n accessible +{ + if (n < 0 || n >= back_cast().length()) { + sc_proxy_out_of_bounds(NULL, n); + sc_core::sc_abort(); // can't recover from here + } +} + +template <class X> +inline void +sc_proxy<X>::check_wbounds(int n) const // check if word n accessible +{ + if (n < 0 || n >= back_cast().size()) { + sc_proxy_out_of_bounds(NULL, n); + sc_core::sc_abort(); // can't recover from here + } +} + +template <class X> +inline sc_digit +sc_proxy<X>::to_anything_unsigned() const +{ + // only 0 word is returned + // can't convert logic values other than 0 and 1 + const X &x = back_cast(); + int len = x.length(); + if (x.get_cword(0) != SC_DIGIT_ZERO) { + SC_REPORT_WARNING("vector contains 4-value logic", 0); + } + sc_digit w = x.get_word(0); + if (len >= SC_DIGIT_SIZE) { + return w; + } + return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len))); +} + +template <class X> +inline uint64 +sc_proxy<X>::to_uint64() const +{ + // words 1 and 0 returned. + // can't convert logic values other than 0 and 1 + const X &x = back_cast(); + int len = x.length(); + if (x.get_cword(0) != SC_DIGIT_ZERO) { + SC_REPORT_WARNING("vector contains 4-value logic", 0); + } + uint64 w = x.get_word(0); + if (len > SC_DIGIT_SIZE) { + if (x.get_cword(1) != SC_DIGIT_ZERO) { + SC_REPORT_WARNING("vector contains 4-value logic", 0); + } + uint64 w1 = x.get_word(1); + w = w | (w1 << SC_DIGIT_SIZE); + return w; + } else if (len == SC_DIGIT_SIZE) { + return w; + } else { + return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len))); + } +} + +template <class X> +inline int64 +sc_proxy<X>::to_anything_signed() const +{ + const X &x = back_cast(); + int len = x.length(); + int64 w = 0; + + if (len > SC_DIGIT_SIZE) { + if (x.get_cword(1) != SC_DIGIT_ZERO) + SC_REPORT_WARNING("vector contains 4-value logic", 0); + w = x.get_word(1); + } + if (x.get_cword(0) != SC_DIGIT_ZERO) + SC_REPORT_WARNING("vector contains 4-value logic", 0); + w = (w << SC_DIGIT_SIZE) | x.get_word(0); + if (len >= 64) { + return w; + } + + uint64 zero = 0; + value_type sgn = x.get_bit(len - 1); + if (sgn == 0) { + return (int64)(w & (~zero >> (64 - len))); + } else { + return (int64)(w | (~zero << len)); + } +} + + +// ---------------------------------------------------------------------------- + +// functional notation for the reduce methods +template <class X> +inline typename sc_proxy<X>::value_type +and_reduce(const sc_proxy<X> &a) +{ + return a.and_reduce(); +} + +template <class X> +inline typename sc_proxy<X>::value_type +nand_reduce(const sc_proxy<X> &a) +{ + return a.nand_reduce(); +} + +template <class X> +inline typename sc_proxy<X>::value_type +or_reduce(const sc_proxy<X> &a) +{ + return a.or_reduce(); +} + +template <class X> +inline typename sc_proxy<X>::value_type +nor_reduce(const sc_proxy<X> &a) +{ + return a.nor_reduce(); +} + +template <class X> +inline typename sc_proxy<X>::value_type +xor_reduce(const sc_proxy<X> &a) +{ + return a.xor_reduce(); +} + +template <class X> +inline typename sc_proxy<X>::value_type +xnor_reduce(const sc_proxy<X> &a) +{ + return a.xnor_reduce(); +} + +// ---------------------------------------------------------------------------- + +template <class X> +inline ::std::ostream & +operator << (::std::ostream &os, const sc_proxy<X> &a) +{ + a.print(os); + return os; +} + +template <class X> +inline ::std::istream & +operator >> (::std::istream &is, sc_proxy<X> &a) +{ + a.scan(is); + return is; +} + +} // namespace sc_dt + +#endif // __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__ |