diff options
Diffstat (limited to 'src/systemc/ext/dt/bit/sc_proxy.hh')
-rw-r--r-- | src/systemc/ext/dt/bit/sc_proxy.hh | 1394 |
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__ |