summaryrefslogtreecommitdiff
path: root/src/systemc/ext/dt/bit/sc_proxy.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/ext/dt/bit/sc_proxy.hh')
-rw-r--r--src/systemc/ext/dt/bit/sc_proxy.hh1394
1 files changed, 1394 insertions, 0 deletions
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__