112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  sc_proxy.h -- Proxy base class for vector data types.
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com                This class is created for several purposes:
2512853Sgabeblack@google.com                1) hiding operators from the global namespace that would be
2612853Sgabeblack@google.com                   otherwise found by Koenig lookup
2712853Sgabeblack@google.com                2) avoiding repeating the same operations in every class
2812853Sgabeblack@google.com                   including proxies that could also be achieved by common
2912853Sgabeblack@google.com                   base class, but this method allows
3012853Sgabeblack@google.com                3) improve performance by using non-virtual functions
3112853Sgabeblack@google.com
3212853Sgabeblack@google.com  Original Author: Gene Bushuyev, Synopsys, Inc.
3312853Sgabeblack@google.com
3412853Sgabeblack@google.com *****************************************************************************/
3512853Sgabeblack@google.com
3612853Sgabeblack@google.com/*****************************************************************************
3712853Sgabeblack@google.com
3812853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3912853Sgabeblack@google.com  changes you are making here.
4012853Sgabeblack@google.com
4112853Sgabeblack@google.com      Name, Affiliation, Date:
4212853Sgabeblack@google.com  Description of Modification:
4312853Sgabeblack@google.com
4412853Sgabeblack@google.com *****************************************************************************/
4512853Sgabeblack@google.com
4612853Sgabeblack@google.com// $Log: sc_proxy.h,v $
4712853Sgabeblack@google.com// Revision 1.3  2010/12/07 20:09:07  acg
4812853Sgabeblack@google.com// Andy Goodrich: Fix for returning enough data
4912853Sgabeblack@google.com//
5012853Sgabeblack@google.com// Revision 1.2  2009/02/28 00:26:14  acg
5112853Sgabeblack@google.com//  Andy Goodrich: bug fixes.
5212853Sgabeblack@google.com//
5312853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:31:36  acg
5412853Sgabeblack@google.com// SystemC 2.2
5512853Sgabeblack@google.com//
5612853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:53  acg
5712853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5812853Sgabeblack@google.com// the source.
5912853Sgabeblack@google.com//
6012853Sgabeblack@google.com
6112853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
6212853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
6312853Sgabeblack@google.com
6412853Sgabeblack@google.com#include <iostream>
6512853Sgabeblack@google.com
6612853Sgabeblack@google.com#include "../../utils/functions.hh"
6712853Sgabeblack@google.com#include "../int/sc_int_base.hh"
6812853Sgabeblack@google.com#include "../int/sc_signed.hh"
6912853Sgabeblack@google.com#include "../int/sc_uint_base.hh"
7012853Sgabeblack@google.com#include "../int/sc_unsigned.hh"
7113325Sgabeblack@google.com#include "messages.hh"
7212853Sgabeblack@google.com#include "sc_bit.hh"
7312853Sgabeblack@google.com#include "sc_logic.hh"
7412853Sgabeblack@google.com
7512853Sgabeblack@google.comnamespace sc_dt
7612853Sgabeblack@google.com{
7712853Sgabeblack@google.com
7812853Sgabeblack@google.com// classes defined in this module
7912853Sgabeblack@google.comtemplate <class X>
8012853Sgabeblack@google.comclass sc_proxy;
8112853Sgabeblack@google.com
8212853Sgabeblack@google.com// forward class declarations
8312853Sgabeblack@google.comclass sc_bv_base;
8412853Sgabeblack@google.comclass sc_lv_base;
8512853Sgabeblack@google.comtemplate <class X>
8612853Sgabeblack@google.comclass sc_bitref_r;
8712853Sgabeblack@google.comtemplate <class X>
8812853Sgabeblack@google.comclass sc_bitref;
8912853Sgabeblack@google.comtemplate <class X>
9012853Sgabeblack@google.comclass sc_subref_r;
9112853Sgabeblack@google.comtemplate <class X>
9212853Sgabeblack@google.comclass sc_subref;
9312853Sgabeblack@google.comtemplate <class X, class Y>
9412853Sgabeblack@google.comclass sc_concref_r;
9512853Sgabeblack@google.comtemplate <class X, class Y>
9612853Sgabeblack@google.comclass sc_concref;
9712853Sgabeblack@google.com
9812853Sgabeblack@google.comconst int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof(sc_digit);
9912853Sgabeblack@google.com
10012853Sgabeblack@google.comconst sc_digit SC_DIGIT_ZERO = (sc_digit)0;
10112853Sgabeblack@google.comconst sc_digit SC_DIGIT_ONE = (sc_digit)1;
10212853Sgabeblack@google.comconst sc_digit SC_DIGIT_TWO = (sc_digit)2;
10312853Sgabeblack@google.com
10412853Sgabeblack@google.comvoid sc_proxy_out_of_bounds(const char *msg=NULL, int64 val=0);
10512853Sgabeblack@google.com
10612853Sgabeblack@google.com// assignment functions; forward declarations
10712853Sgabeblack@google.com
10812853Sgabeblack@google.comtemplate <class X, class Y>
10912853Sgabeblack@google.cominline void assign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py);
11012853Sgabeblack@google.com
11112853Sgabeblack@google.com// Vector types that are not derived from sc_proxy must have a length()
11212853Sgabeblack@google.com// function and an operator [].
11312853Sgabeblack@google.com
11412853Sgabeblack@google.comtemplate <class X, class T>
11512853Sgabeblack@google.cominline void assign_v_(sc_proxy<X> &px, const T &a);
11612853Sgabeblack@google.com
11712853Sgabeblack@google.com// other functions; forward declarations
11812853Sgabeblack@google.comconst std::string convert_to_bin(const char *s);
11912853Sgabeblack@google.comconst std::string convert_to_fmt(const std::string &s, sc_numrep numrep, bool);
12012853Sgabeblack@google.com
12112853Sgabeblack@google.com// ----------------------------------------------------------------------------
12212853Sgabeblack@google.com//  CLASS TEMPLATE : sc_proxy_traits
12312853Sgabeblack@google.com//
12412853Sgabeblack@google.com// Template traits helper to select the correct bit/value/vector_types for
12512853Sgabeblack@google.com// sc_proxy-based vector classes.
12612853Sgabeblack@google.com//
12712853Sgabeblack@google.com// All types derived from/based on a bit-vector contain typedef to a plain
12812853Sgabeblack@google.com// bool, all others point to the sc_logic_value_t/sc_logic/sc_lv_base types.
12912853Sgabeblack@google.com// ----------------------------------------------------------------------------
13012853Sgabeblack@google.com
13112853Sgabeblack@google.comtemplate <typename X>
13212853Sgabeblack@google.comstruct sc_proxy_traits;
13312853Sgabeblack@google.com
13412853Sgabeblack@google.comtemplate <>
13512853Sgabeblack@google.comstruct sc_proxy_traits<sc_bv_base>
13612853Sgabeblack@google.com{
13712853Sgabeblack@google.com    typedef sc_proxy_traits<sc_bv_base> traits_type;
13812853Sgabeblack@google.com    typedef bool value_type;
13912853Sgabeblack@google.com    typedef sc_logic bit_type; // sc_logic needed for mixed expressions
14012853Sgabeblack@google.com    typedef sc_bv_base vector_type;
14112853Sgabeblack@google.com};
14212853Sgabeblack@google.com
14312853Sgabeblack@google.comtemplate <>
14412853Sgabeblack@google.comstruct sc_proxy_traits<sc_lv_base>
14512853Sgabeblack@google.com{
14612853Sgabeblack@google.com    typedef sc_proxy_traits<sc_lv_base> traits_type;
14712853Sgabeblack@google.com    typedef sc_logic_value_t value_type;
14812853Sgabeblack@google.com    typedef sc_logic bit_type;
14912853Sgabeblack@google.com    typedef sc_lv_base vector_type;
15012853Sgabeblack@google.com};
15112853Sgabeblack@google.com
15212853Sgabeblack@google.comtemplate <typename X>
15312853Sgabeblack@google.comstruct sc_proxy_traits<sc_bitref_r<X> > : sc_proxy_traits<X> {};
15412853Sgabeblack@google.com
15512853Sgabeblack@google.comtemplate <typename X>
15612853Sgabeblack@google.comstruct sc_proxy_traits<sc_bitref<X> > : sc_proxy_traits<X> {};
15712853Sgabeblack@google.com
15812853Sgabeblack@google.comtemplate <typename X>
15912853Sgabeblack@google.comstruct sc_proxy_traits<sc_subref_r<X> > : sc_proxy_traits<X> {};
16012853Sgabeblack@google.com
16112853Sgabeblack@google.comtemplate <typename X>
16212853Sgabeblack@google.comstruct sc_proxy_traits<sc_subref<X> > : sc_proxy_traits<X> {};
16312853Sgabeblack@google.com
16412853Sgabeblack@google.comtemplate <typename X>
16512853Sgabeblack@google.comstruct sc_proxy_traits<sc_proxy<X> > : sc_proxy_traits<X> {};
16612853Sgabeblack@google.com
16712853Sgabeblack@google.com
16812853Sgabeblack@google.comtemplate <typename X, typename Y>
16912853Sgabeblack@google.comstruct sc_mixed_proxy_traits_helper : sc_proxy_traits<sc_lv_base>
17012853Sgabeblack@google.com{}; // logic vector by default
17112853Sgabeblack@google.com
17212853Sgabeblack@google.comtemplate <typename X>
17312853Sgabeblack@google.comstruct sc_mixed_proxy_traits_helper<X, X> : X {};
17412853Sgabeblack@google.com
17512853Sgabeblack@google.comtemplate <typename X, typename Y>
17612853Sgabeblack@google.comstruct sc_proxy_traits<sc_concref_r<X, Y> > :
17712853Sgabeblack@google.com        sc_mixed_proxy_traits_helper<
17812853Sgabeblack@google.com            typename X::traits_type, typename Y::traits_type>
17912853Sgabeblack@google.com{};
18012853Sgabeblack@google.com
18112853Sgabeblack@google.comtemplate <typename X, typename Y>
18212853Sgabeblack@google.comstruct sc_proxy_traits<sc_concref<X, Y> > :
18312853Sgabeblack@google.com        sc_mixed_proxy_traits_helper<
18412853Sgabeblack@google.com            typename X::traits_type, typename Y::traits_type>
18512853Sgabeblack@google.com{};
18612853Sgabeblack@google.com
18712853Sgabeblack@google.com
18812853Sgabeblack@google.com// ----------------------------------------------------------------------------
18912853Sgabeblack@google.com//  CLASS TEMPLATE : sc_proxy
19012853Sgabeblack@google.com//
19112853Sgabeblack@google.com//  Base class template for bit/logic vector classes.
19212853Sgabeblack@google.com//  (Barton/Nackmann implementation)
19312853Sgabeblack@google.com// ----------------------------------------------------------------------------
19412853Sgabeblack@google.com
19512853Sgabeblack@google.comtemplate <class X>
19612853Sgabeblack@google.comclass sc_proxy // #### : public sc_value_base
19712853Sgabeblack@google.com{
19812853Sgabeblack@google.com  public:
19912853Sgabeblack@google.com    typedef typename sc_proxy_traits<X>::traits_type traits_type;
20012853Sgabeblack@google.com    typedef typename traits_type::bit_type bit_type;
20112853Sgabeblack@google.com    typedef typename traits_type::value_type value_type;
20212853Sgabeblack@google.com
20312853Sgabeblack@google.com    // virtual destructor
20412853Sgabeblack@google.com    virtual ~sc_proxy() {}
20512853Sgabeblack@google.com
20612853Sgabeblack@google.com    // casts
20712853Sgabeblack@google.com    X &back_cast() { return static_cast<X &>(*this); }
20812853Sgabeblack@google.com
20912853Sgabeblack@google.com    const X &back_cast() const { return static_cast<const X &>(*this); }
21012853Sgabeblack@google.com
21112853Sgabeblack@google.com    // assignment operators
21212853Sgabeblack@google.com    template <class Y>
21312853Sgabeblack@google.com    X &
21412853Sgabeblack@google.com    assign_(const sc_proxy<Y> &a)
21512853Sgabeblack@google.com    {
21612853Sgabeblack@google.com        assign_p_(*this, a);
21712853Sgabeblack@google.com        return back_cast();
21812853Sgabeblack@google.com    }
21912853Sgabeblack@google.com
22012853Sgabeblack@google.com    X &assign_(const char *a);
22112853Sgabeblack@google.com    X &assign_(const bool *a);
22212853Sgabeblack@google.com    X &assign_(const sc_logic *a);
22312853Sgabeblack@google.com
22412853Sgabeblack@google.com    X &
22512853Sgabeblack@google.com    assign_(const sc_unsigned &a)
22612853Sgabeblack@google.com    {
22712853Sgabeblack@google.com        assign_v_(*this, a);
22812853Sgabeblack@google.com        return back_cast();
22912853Sgabeblack@google.com    }
23012853Sgabeblack@google.com
23112853Sgabeblack@google.com    X &
23212853Sgabeblack@google.com    assign_(const sc_signed &a)
23312853Sgabeblack@google.com    {
23412853Sgabeblack@google.com        assign_v_(*this, a);
23512853Sgabeblack@google.com        return back_cast();
23612853Sgabeblack@google.com    }
23712853Sgabeblack@google.com
23812853Sgabeblack@google.com    X &assign_(const sc_uint_base &a) { return assign_((uint64)a); }
23912853Sgabeblack@google.com    X &assign_(const sc_int_base &a) { return assign_((int64)a); }
24012853Sgabeblack@google.com    X &assign_(unsigned int a);
24112853Sgabeblack@google.com    X &assign_(int a);
24212853Sgabeblack@google.com    X &assign_(unsigned long a);
24312853Sgabeblack@google.com    X &assign_(long a);
24412853Sgabeblack@google.com    X &assign_(uint64 a);
24512853Sgabeblack@google.com    X &assign_(int64 a);
24612853Sgabeblack@google.com
24712853Sgabeblack@google.com    // bitwise operators and functions
24812853Sgabeblack@google.com
24912853Sgabeblack@google.com    // bitwise complement
25012853Sgabeblack@google.com    X &b_not();
25112853Sgabeblack@google.com
25212853Sgabeblack@google.com    const sc_lv_base operator ~ () const;
25312853Sgabeblack@google.com
25412853Sgabeblack@google.com    // bitwise and
25512853Sgabeblack@google.com    X &operator &= (const char *b);
25612853Sgabeblack@google.com    X &operator &= (const bool *b);
25712853Sgabeblack@google.com    X &operator &= (const sc_logic *b);
25812853Sgabeblack@google.com    X &operator &= (const sc_unsigned &b);
25912853Sgabeblack@google.com    X &operator &= (const sc_signed &b);
26012853Sgabeblack@google.com    X &operator &= (const sc_uint_base &b) { return operator &= ((uint64)b); }
26112853Sgabeblack@google.com    X &operator &= (const sc_int_base &b) { return operator &= ((int64)b); }
26212853Sgabeblack@google.com    X &operator &= (unsigned long b);
26312853Sgabeblack@google.com    X &operator &= (long b);
26412853Sgabeblack@google.com    X &operator &= (unsigned int b) { return operator &= ((unsigned long)b); }
26512853Sgabeblack@google.com    X &operator &= (int b) { return operator &= ((long)b); }
26612853Sgabeblack@google.com    X &operator &= (uint64 b);
26712853Sgabeblack@google.com    X &operator &= (int64 b);
26812853Sgabeblack@google.com
26912853Sgabeblack@google.com    const sc_lv_base operator & (const char *b) const;
27012853Sgabeblack@google.com    const sc_lv_base operator & (const bool *b) const;
27112853Sgabeblack@google.com    const sc_lv_base operator & (const sc_logic *b) const;
27212853Sgabeblack@google.com    const sc_lv_base operator & (const sc_unsigned &b) const;
27312853Sgabeblack@google.com    const sc_lv_base operator & (const sc_signed &b) const;
27412853Sgabeblack@google.com    const sc_lv_base operator & (const sc_uint_base &b) const;
27512853Sgabeblack@google.com    const sc_lv_base operator & (const sc_int_base &b) const;
27612853Sgabeblack@google.com    const sc_lv_base operator & (unsigned long b) const;
27712853Sgabeblack@google.com    const sc_lv_base operator & (long b) const;
27812853Sgabeblack@google.com    const sc_lv_base operator & (unsigned int b) const;
27912853Sgabeblack@google.com    const sc_lv_base operator & (int b) const;
28012853Sgabeblack@google.com    const sc_lv_base operator & (uint64 b) const;
28112853Sgabeblack@google.com    const sc_lv_base operator & (int64 b) const;
28212853Sgabeblack@google.com
28312853Sgabeblack@google.com    // bitwise or
28412853Sgabeblack@google.com    X &operator |= (const char *b);
28512853Sgabeblack@google.com    X &operator |= (const bool *b);
28612853Sgabeblack@google.com    X &operator |= (const sc_logic *b);
28712853Sgabeblack@google.com    X &operator |= (const sc_unsigned &b);
28812853Sgabeblack@google.com    X &operator |= (const sc_signed &b);
28912853Sgabeblack@google.com    X &operator |= (const sc_uint_base &b) { return operator |= ((uint64)b); }
29012853Sgabeblack@google.com    X &operator |= (const sc_int_base &b) { return operator |= ((int64)b); }
29112853Sgabeblack@google.com    X &operator |= (unsigned long b);
29212853Sgabeblack@google.com    X &operator |= (long b);
29312853Sgabeblack@google.com    X &operator |= (unsigned int b) { return operator |= ((unsigned long)b); }
29412853Sgabeblack@google.com    X &operator |= (int b) { return operator |= ((long)b); }
29512853Sgabeblack@google.com    X &operator |= (uint64 b);
29612853Sgabeblack@google.com    X &operator |= (int64 b);
29712853Sgabeblack@google.com
29812853Sgabeblack@google.com    const sc_lv_base operator | (const char *b) const;
29912853Sgabeblack@google.com    const sc_lv_base operator | (const bool *b) const;
30012853Sgabeblack@google.com    const sc_lv_base operator | (const sc_logic *b) const;
30112853Sgabeblack@google.com    const sc_lv_base operator | (const sc_unsigned &b) const;
30212853Sgabeblack@google.com    const sc_lv_base operator | (const sc_signed &b) const;
30312853Sgabeblack@google.com    const sc_lv_base operator | (const sc_uint_base &b) const;
30412853Sgabeblack@google.com    const sc_lv_base operator | (const sc_int_base &b) const;
30512853Sgabeblack@google.com    const sc_lv_base operator | (unsigned long b) const;
30612853Sgabeblack@google.com    const sc_lv_base operator | (long b) const;
30712853Sgabeblack@google.com    const sc_lv_base operator | (unsigned int b) const;
30812853Sgabeblack@google.com    const sc_lv_base operator | (int b) const;
30912853Sgabeblack@google.com    const sc_lv_base operator | (uint64 b) const;
31012853Sgabeblack@google.com    const sc_lv_base operator | (int64 b) const;
31112853Sgabeblack@google.com
31212853Sgabeblack@google.com    // bitwise xor
31312853Sgabeblack@google.com    X &operator ^= (const char *b);
31412853Sgabeblack@google.com    X &operator ^= (const bool *b);
31512853Sgabeblack@google.com    X &operator ^= (const sc_logic *b);
31612853Sgabeblack@google.com    X &operator ^= (const sc_unsigned &b);
31712853Sgabeblack@google.com    X &operator ^= (const sc_signed &b);
31812853Sgabeblack@google.com    X &operator ^= (const sc_uint_base &b) { return operator ^= ((uint64)b); }
31912853Sgabeblack@google.com    X &operator ^= (const sc_int_base &b) { return operator ^= ((int64)b); }
32012853Sgabeblack@google.com    X &operator ^= (unsigned long b);
32112853Sgabeblack@google.com    X &operator ^= (long b);
32212853Sgabeblack@google.com    X &operator ^= (unsigned int b) { return operator ^= ((unsigned long)b); }
32312853Sgabeblack@google.com    X &operator ^= (int b) { return operator ^= ((long)b); }
32412853Sgabeblack@google.com    X &operator ^= (uint64 b);
32512853Sgabeblack@google.com    X &operator ^= (int64 b);
32612853Sgabeblack@google.com
32712853Sgabeblack@google.com    const sc_lv_base operator ^ (const char *b) const;
32812853Sgabeblack@google.com    const sc_lv_base operator ^ (const bool *b) const;
32912853Sgabeblack@google.com    const sc_lv_base operator ^ (const sc_logic *b) const;
33012853Sgabeblack@google.com    const sc_lv_base operator ^ (const sc_unsigned &b) const;
33112853Sgabeblack@google.com    const sc_lv_base operator ^ (const sc_signed &b) const;
33212853Sgabeblack@google.com    const sc_lv_base operator ^ (const sc_uint_base &b) const;
33312853Sgabeblack@google.com    const sc_lv_base operator ^ (const sc_int_base &b) const;
33412853Sgabeblack@google.com    const sc_lv_base operator ^ (unsigned long b) const;
33512853Sgabeblack@google.com    const sc_lv_base operator ^ (long b) const;
33612853Sgabeblack@google.com    const sc_lv_base operator ^ (unsigned int b) const;
33712853Sgabeblack@google.com    const sc_lv_base operator ^ (int b) const;
33812853Sgabeblack@google.com    const sc_lv_base operator ^ (uint64 b) const;
33912853Sgabeblack@google.com    const sc_lv_base operator ^ (int64 b) const;
34012853Sgabeblack@google.com
34112853Sgabeblack@google.com    // bitwise left shift
34212853Sgabeblack@google.com    X &operator <<= (int n);
34312853Sgabeblack@google.com    const sc_lv_base operator << (int n) const;
34412853Sgabeblack@google.com
34512853Sgabeblack@google.com    // bitwise right shift
34612853Sgabeblack@google.com    X &operator >>= (int n);
34712853Sgabeblack@google.com    const sc_lv_base operator >> (int n) const;
34812853Sgabeblack@google.com
34912853Sgabeblack@google.com    // bitwise left rotate
35012853Sgabeblack@google.com    X &lrotate(int n);
35112853Sgabeblack@google.com
35212853Sgabeblack@google.com    // bitwise right rotate
35312853Sgabeblack@google.com    X &rrotate(int n);
35412853Sgabeblack@google.com
35512853Sgabeblack@google.com    // bitwise reverse
35612853Sgabeblack@google.com    X &reverse();
35712853Sgabeblack@google.com
35812853Sgabeblack@google.com    // bit selection
35912853Sgabeblack@google.com    sc_bitref<X> operator [] (int i) { return sc_bitref<X>(back_cast(), i); }
36012853Sgabeblack@google.com    sc_bitref_r<X>
36112853Sgabeblack@google.com    operator [] (int i) const
36212853Sgabeblack@google.com    {
36312853Sgabeblack@google.com        return sc_bitref_r<X>(back_cast(), i);
36412853Sgabeblack@google.com    }
36512853Sgabeblack@google.com    sc_bitref<X> bit(int i) { return sc_bitref<X>(back_cast(), i); }
36612853Sgabeblack@google.com    sc_bitref_r<X> bit(int i) const { return sc_bitref_r<X>(back_cast(), i); }
36712853Sgabeblack@google.com
36812853Sgabeblack@google.com    // part selection
36912853Sgabeblack@google.com    sc_subref<X>
37012853Sgabeblack@google.com    operator () (int hi, int lo)
37112853Sgabeblack@google.com    {
37212853Sgabeblack@google.com        return sc_subref<X>(back_cast(), hi, lo);
37312853Sgabeblack@google.com    }
37412853Sgabeblack@google.com    sc_subref_r<X>
37512853Sgabeblack@google.com    operator () (int hi, int lo) const
37612853Sgabeblack@google.com    {
37712853Sgabeblack@google.com        return sc_subref_r<X>(back_cast(), hi, lo);
37812853Sgabeblack@google.com    }
37912853Sgabeblack@google.com    sc_subref<X>
38012853Sgabeblack@google.com    range(int hi, int lo)
38112853Sgabeblack@google.com    {
38212853Sgabeblack@google.com        return sc_subref<X>(back_cast(), hi, lo);
38312853Sgabeblack@google.com    }
38412853Sgabeblack@google.com    sc_subref_r<X>
38512853Sgabeblack@google.com    range(int hi, int lo) const
38612853Sgabeblack@google.com    {
38712853Sgabeblack@google.com        return sc_subref_r<X>(back_cast(), hi, lo);
38812853Sgabeblack@google.com    }
38912853Sgabeblack@google.com
39012853Sgabeblack@google.com    // reduce functions
39112853Sgabeblack@google.com    value_type and_reduce() const;
39212853Sgabeblack@google.com    value_type
39312853Sgabeblack@google.com    nand_reduce() const
39412853Sgabeblack@google.com    {
39512853Sgabeblack@google.com        return sc_logic::not_table[and_reduce()];
39612853Sgabeblack@google.com    }
39712853Sgabeblack@google.com    value_type or_reduce() const;
39812853Sgabeblack@google.com    value_type nor_reduce() const { return sc_logic::not_table[or_reduce()]; }
39912853Sgabeblack@google.com    value_type xor_reduce() const;
40012853Sgabeblack@google.com    value_type
40112853Sgabeblack@google.com    xnor_reduce() const
40212853Sgabeblack@google.com    {
40312853Sgabeblack@google.com        return sc_logic::not_table[xor_reduce()];
40412853Sgabeblack@google.com    }
40512853Sgabeblack@google.com
40612853Sgabeblack@google.com    // relational operators
40712853Sgabeblack@google.com    bool operator == (const char *b) const;
40812853Sgabeblack@google.com    bool operator == (const bool *b) const;
40912853Sgabeblack@google.com    bool operator == (const sc_logic *b) const;
41012853Sgabeblack@google.com    bool operator == (const sc_unsigned &b) const;
41112853Sgabeblack@google.com    bool operator == (const sc_signed &b) const;
41212853Sgabeblack@google.com    bool operator == (const sc_uint_base &b) const;
41312853Sgabeblack@google.com    bool operator == (const sc_int_base &b) const;
41412853Sgabeblack@google.com    bool operator == (unsigned long b) const;
41512853Sgabeblack@google.com    bool operator == (long b) const;
41612853Sgabeblack@google.com    bool operator == (unsigned int b) const;
41712853Sgabeblack@google.com    bool operator == (int b) const;
41812853Sgabeblack@google.com    bool operator == (uint64 b) const;
41912853Sgabeblack@google.com    bool operator == (int64 b) const;
42012853Sgabeblack@google.com
42112853Sgabeblack@google.com    // explicit conversions to character string
42212853Sgabeblack@google.com    const std::string to_string() const;
42312853Sgabeblack@google.com    const std::string to_string(sc_numrep) const;
42412853Sgabeblack@google.com    const std::string to_string(sc_numrep, bool) const;
42512853Sgabeblack@google.com
42612853Sgabeblack@google.com    // explicit conversions
42712853Sgabeblack@google.com    inline int64 to_int64() const { return to_anything_signed(); }
42812853Sgabeblack@google.com    inline uint64 to_uint64() const;
42912853Sgabeblack@google.com    int to_int() const { return (int)to_anything_signed(); }
43012853Sgabeblack@google.com
43112853Sgabeblack@google.com    unsigned int
43212853Sgabeblack@google.com    to_uint() const
43312853Sgabeblack@google.com    {
43412853Sgabeblack@google.com        return (unsigned int)to_anything_unsigned();
43512853Sgabeblack@google.com    }
43612853Sgabeblack@google.com
43712853Sgabeblack@google.com    long to_long() const { return (long)to_anything_signed(); }
43812853Sgabeblack@google.com
43912853Sgabeblack@google.com    unsigned long
44012853Sgabeblack@google.com    to_ulong() const
44112853Sgabeblack@google.com    {
44212853Sgabeblack@google.com        return (unsigned long)to_anything_unsigned();
44312853Sgabeblack@google.com    }
44412853Sgabeblack@google.com
44512853Sgabeblack@google.com    // other methods
44612853Sgabeblack@google.com    void
44712853Sgabeblack@google.com    print(::std::ostream &os=::std::cout) const
44812853Sgabeblack@google.com    {
44912853Sgabeblack@google.com        // The test below will force printing in binary if decimal is
45012853Sgabeblack@google.com        // specified.
45112853Sgabeblack@google.com        if (sc_io_base(os, SC_DEC) == SC_DEC)
45212853Sgabeblack@google.com            os << to_string();
45312853Sgabeblack@google.com        else
45412853Sgabeblack@google.com            os << to_string(sc_io_base(os, SC_BIN), sc_io_show_base(os));
45512853Sgabeblack@google.com    }
45612853Sgabeblack@google.com
45712853Sgabeblack@google.com    void scan(::std::istream &is=::std::cin);
45812853Sgabeblack@google.com
45912853Sgabeblack@google.com  protected:
46012853Sgabeblack@google.com    void check_bounds(int n) const; // check if bit n accessible
46112853Sgabeblack@google.com    void check_wbounds(int n) const; // check if word n accessible
46212853Sgabeblack@google.com
46312853Sgabeblack@google.com    sc_digit to_anything_unsigned() const;
46412853Sgabeblack@google.com    int64 to_anything_signed() const;
46512853Sgabeblack@google.com};
46612853Sgabeblack@google.com
46712853Sgabeblack@google.com
46812853Sgabeblack@google.com// ----------------------------------------------------------------------------
46912853Sgabeblack@google.com
47012853Sgabeblack@google.com// bitwise operators and functions
47112853Sgabeblack@google.com
47212853Sgabeblack@google.com// bitwise and
47312853Sgabeblack@google.com
47412853Sgabeblack@google.comtemplate <class X, class Y>
47512853Sgabeblack@google.cominline X &operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py);
47612853Sgabeblack@google.com
47712853Sgabeblack@google.com
47812853Sgabeblack@google.comtemplate <class X, class Y>
47912853Sgabeblack@google.cominline const sc_lv_base operator & (
48012853Sgabeblack@google.com        const sc_proxy<X> &px, const sc_proxy<Y> &py);
48112853Sgabeblack@google.com
48212853Sgabeblack@google.com
48312853Sgabeblack@google.com#define DECL_BITWISE_AND_OP_T(tp) \
48412853Sgabeblack@google.comtemplate <class X> \
48512853Sgabeblack@google.cominline const sc_lv_base operator & (tp b, const sc_proxy<X> &px);
48612853Sgabeblack@google.com
48712853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const char *)
48812853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const bool *)
48912853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const sc_logic *)
49012853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const sc_unsigned &)
49112853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const sc_signed &)
49212853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const sc_uint_base &)
49312853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(const sc_int_base &)
49412853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(unsigned long)
49512853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(long)
49612853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(unsigned int)
49712853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(int)
49812853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(uint64)
49912853Sgabeblack@google.comDECL_BITWISE_AND_OP_T(int64)
50012853Sgabeblack@google.com
50112853Sgabeblack@google.com#undef DECL_BITWISE_AND_OP_T
50212853Sgabeblack@google.com
50312853Sgabeblack@google.com// bitwise or
50412853Sgabeblack@google.comtemplate <class X, class Y>
50512853Sgabeblack@google.cominline X &operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py);
50612853Sgabeblack@google.com
50712853Sgabeblack@google.comtemplate <class X, class Y>
50812853Sgabeblack@google.cominline const sc_lv_base operator | (
50912853Sgabeblack@google.com        const sc_proxy<X> &px, const sc_proxy<Y> &py);
51012853Sgabeblack@google.com
51112853Sgabeblack@google.com
51212853Sgabeblack@google.com#define DECL_BITWISE_OR_OP_T(tp) \
51312853Sgabeblack@google.comtemplate <class X> \
51412853Sgabeblack@google.cominline const sc_lv_base operator | (tp a, const sc_proxy<X> &px);
51512853Sgabeblack@google.com
51612853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const char *)
51712853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const bool *)
51812853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const sc_logic *)
51912853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const sc_unsigned &)
52012853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const sc_signed &)
52112853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const sc_uint_base &)
52212853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(const sc_int_base &)
52312853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(unsigned long)
52412853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(long)
52512853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(unsigned int)
52612853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(int)
52712853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(uint64)
52812853Sgabeblack@google.comDECL_BITWISE_OR_OP_T(int64)
52912853Sgabeblack@google.com
53012853Sgabeblack@google.com#undef DECL_BITWISE_OR_OP_T
53112853Sgabeblack@google.com
53212853Sgabeblack@google.com// bitwise xor
53312853Sgabeblack@google.comtemplate <class X, class Y>
53412853Sgabeblack@google.cominline X &operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py);
53512853Sgabeblack@google.com
53612853Sgabeblack@google.comtemplate <class X, class Y>
53712853Sgabeblack@google.cominline const sc_lv_base operator ^ (
53812853Sgabeblack@google.com        const sc_proxy<X> &px, const sc_proxy<Y> &py);
53912853Sgabeblack@google.com
54012853Sgabeblack@google.com#define DECL_BITWISE_XOR_OP_T(tp) \
54112853Sgabeblack@google.comtemplate <class X> \
54212853Sgabeblack@google.cominline const sc_lv_base operator ^ (tp a, const sc_proxy<X> &px);
54312853Sgabeblack@google.com
54412853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const char *)
54512853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const bool *)
54612853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const sc_logic *)
54712853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const sc_unsigned &)
54812853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const sc_signed &)
54912853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const sc_uint_base &)
55012853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(const sc_int_base &)
55112853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(unsigned long)
55212853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(long)
55312853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(unsigned int)
55412853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(int)
55512853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(uint64)
55612853Sgabeblack@google.comDECL_BITWISE_XOR_OP_T(int64)
55712853Sgabeblack@google.com
55812853Sgabeblack@google.com#undef DECL_BITWISE_XOR_OP_T
55912853Sgabeblack@google.com
56012853Sgabeblack@google.com// relational operators
56112853Sgabeblack@google.comtemplate <class X, class Y>
56212853Sgabeblack@google.cominline bool operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py);
56312853Sgabeblack@google.com
56412853Sgabeblack@google.comtemplate <class X, class Y>
56512853Sgabeblack@google.cominline bool operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py);
56612853Sgabeblack@google.com
56712853Sgabeblack@google.com#define DECL_REL_OP_T(tp) \
56812853Sgabeblack@google.comtemplate <class X> \
56912853Sgabeblack@google.cominline bool operator == (tp b, const sc_proxy<X> &px); \
57012853Sgabeblack@google.com \
57112853Sgabeblack@google.comtemplate <class X> \
57212853Sgabeblack@google.cominline bool operator != (const sc_proxy<X> &px, tp b); \
57312853Sgabeblack@google.com \
57412853Sgabeblack@google.comtemplate <class X> \
57512853Sgabeblack@google.cominline bool operator != (tp b, const sc_proxy<X> &px);
57612853Sgabeblack@google.com
57712853Sgabeblack@google.comDECL_REL_OP_T(const char *)
57812853Sgabeblack@google.comDECL_REL_OP_T(const bool *)
57912853Sgabeblack@google.comDECL_REL_OP_T(const sc_logic *)
58012853Sgabeblack@google.comDECL_REL_OP_T(const sc_unsigned &)
58112853Sgabeblack@google.comDECL_REL_OP_T(const sc_signed &)
58212853Sgabeblack@google.comDECL_REL_OP_T(const sc_uint_base &)
58312853Sgabeblack@google.comDECL_REL_OP_T(const sc_int_base &)
58412853Sgabeblack@google.comDECL_REL_OP_T(unsigned long)
58512853Sgabeblack@google.comDECL_REL_OP_T(long)
58612853Sgabeblack@google.comDECL_REL_OP_T(unsigned int)
58712853Sgabeblack@google.comDECL_REL_OP_T(int)
58812853Sgabeblack@google.comDECL_REL_OP_T(uint64)
58912853Sgabeblack@google.comDECL_REL_OP_T(int64)
59012853Sgabeblack@google.com
59112853Sgabeblack@google.com#undef DECL_REL_OP_T
59212853Sgabeblack@google.com
59312853Sgabeblack@google.com// l-value concatenation
59412853Sgabeblack@google.com
59512853Sgabeblack@google.com// Due to the fact that temporary objects cannot be passed to non-const
59612853Sgabeblack@google.com// references, we have to enumerate, use call by value, and use dynamic
59712853Sgabeblack@google.com// memory allocation (and deallocation).
59812853Sgabeblack@google.com
59912853Sgabeblack@google.com
60012853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
60112853Sgabeblack@google.com
60212853Sgabeblack@google.comtemplate <class X>
60312853Sgabeblack@google.cominline void
60412853Sgabeblack@google.comget_words_(const X &x, int wi, sc_digit &x_dw, sc_digit &x_cw)
60512853Sgabeblack@google.com{
60612853Sgabeblack@google.com    x_dw = x.get_word(wi);
60712853Sgabeblack@google.com    x_cw = x.get_cword(wi);
60812853Sgabeblack@google.com}
60912853Sgabeblack@google.com
61012853Sgabeblack@google.comtemplate <class X>
61112853Sgabeblack@google.cominline void
61212853Sgabeblack@google.comset_words_(X &x, int wi, sc_digit x_dw, sc_digit x_cw)
61312853Sgabeblack@google.com{
61412853Sgabeblack@google.com    x.set_word(wi, x_dw);
61512853Sgabeblack@google.com    x.set_cword(wi, x_cw);
61612853Sgabeblack@google.com}
61712853Sgabeblack@google.com
61812853Sgabeblack@google.comtemplate <class X>
61912853Sgabeblack@google.cominline void
62012853Sgabeblack@google.comextend_sign_w_(X &x, int wi, bool sign)
62112853Sgabeblack@google.com{
62212853Sgabeblack@google.com    int sz = x.size();
62312853Sgabeblack@google.com    unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO);
62412853Sgabeblack@google.com    for (int i = wi; i < sz; ++i) {
62512853Sgabeblack@google.com        set_words_(x, i, sgn, SC_DIGIT_ZERO);
62612853Sgabeblack@google.com    }
62712853Sgabeblack@google.com}
62812853Sgabeblack@google.com
62912853Sgabeblack@google.com// assignment functions
63012853Sgabeblack@google.comtemplate <class X, class Y>
63112853Sgabeblack@google.cominline void
63212853Sgabeblack@google.comassign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py)
63312853Sgabeblack@google.com{
63412853Sgabeblack@google.com    if ((void *)&px != (void *)&py) {
63512853Sgabeblack@google.com        X &x = px.back_cast();
63612853Sgabeblack@google.com        const Y &y = py.back_cast();
63712853Sgabeblack@google.com        int sz = x.size();
63812853Sgabeblack@google.com        int min_sz = sc_min(sz, y.size());
63912853Sgabeblack@google.com        int i = 0;
64012853Sgabeblack@google.com        for (; i < min_sz; ++i) {
64112853Sgabeblack@google.com            set_words_(x, i, y.get_word(i), y.get_cword(i));
64212853Sgabeblack@google.com        }
64312853Sgabeblack@google.com        // extend with zeros
64412853Sgabeblack@google.com        extend_sign_w_(x, i, false);
64512853Sgabeblack@google.com        x.clean_tail();
64612853Sgabeblack@google.com    }
64712853Sgabeblack@google.com}
64812853Sgabeblack@google.com
64912853Sgabeblack@google.com// Vector types that are not derived from sc_proxy, sc_int_base,
65012853Sgabeblack@google.com// sc_uint_base, sc_signed, or sc_unsigned, must have a length()
65112853Sgabeblack@google.com// function and an operator []. The vector argument type must support
65212853Sgabeblack@google.com// accessing bits that are beyond the msb. The vector argument type
65312853Sgabeblack@google.com// decides what to do there (e.g. sign extension or zero padding).
65412853Sgabeblack@google.com
65512853Sgabeblack@google.comtemplate <class X, class T>
65612853Sgabeblack@google.cominline void
65712853Sgabeblack@google.comassign_v_(sc_proxy<X> &px, const T &a)
65812853Sgabeblack@google.com{
65912853Sgabeblack@google.com    X &x = px.back_cast();
66012853Sgabeblack@google.com    int i;
66112853Sgabeblack@google.com    int len_x = x.length();
66212853Sgabeblack@google.com    int len_a = a.length();
66312853Sgabeblack@google.com    if (len_a > len_x)
66412853Sgabeblack@google.com        len_a = len_x;
66512853Sgabeblack@google.com    for (i = 0; i < len_a; ++i) {
66612853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t((bool)a[i]));
66712853Sgabeblack@google.com    }
66812853Sgabeblack@google.com    for (; i < len_x; ++i) {
66912853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(false));
67012853Sgabeblack@google.com    }
67112853Sgabeblack@google.com}
67212853Sgabeblack@google.com
67312853Sgabeblack@google.comtemplate <class X>
67412853Sgabeblack@google.cominline void
67512853Sgabeblack@google.comassign_v_(sc_proxy<X> &px, const sc_int_base &a)
67612853Sgabeblack@google.com{
67712853Sgabeblack@google.com    X &x = px.back_cast();
67812853Sgabeblack@google.com    int i;
67912853Sgabeblack@google.com    bool sign = a < 0;
68012853Sgabeblack@google.com    int len_x = x.length();
68112853Sgabeblack@google.com    int len_a = a.length();
68212853Sgabeblack@google.com    if ( len_a > len_x ) len_a = len_x;
68312853Sgabeblack@google.com    for (i = 0; i < len_a; ++i) {
68412853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t((bool)a[i]));
68512853Sgabeblack@google.com    }
68612853Sgabeblack@google.com    for (; i < len_x; ++i) {
68712853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(sign));
68812853Sgabeblack@google.com    }
68912853Sgabeblack@google.com}
69012853Sgabeblack@google.com
69112853Sgabeblack@google.comtemplate <class X>
69212853Sgabeblack@google.cominline void
69312853Sgabeblack@google.comassign_v_(sc_proxy<X> &px, const sc_signed &a)
69412853Sgabeblack@google.com{
69512853Sgabeblack@google.com    X &x = px.back_cast();
69612853Sgabeblack@google.com    int i;
69712853Sgabeblack@google.com    bool sign = a < 0;
69812853Sgabeblack@google.com    int len_x = x.length();
69912853Sgabeblack@google.com    int len_a = a.length();
70012853Sgabeblack@google.com    if (len_a > len_x)
70112853Sgabeblack@google.com        len_a = len_x;
70212853Sgabeblack@google.com    for (i = 0; i < len_a; ++i) {
70312853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t((bool)a[i]));
70412853Sgabeblack@google.com    }
70512853Sgabeblack@google.com    for (; i < len_x; ++i) {
70612853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(sign));
70712853Sgabeblack@google.com    }
70812853Sgabeblack@google.com}
70912853Sgabeblack@google.com
71012853Sgabeblack@google.comtemplate <class X>
71112853Sgabeblack@google.cominline void
71212853Sgabeblack@google.comassign_v_(sc_proxy<X> &px, const sc_uint_base &a)
71312853Sgabeblack@google.com{
71412853Sgabeblack@google.com    X &x = px.back_cast();
71512853Sgabeblack@google.com    int i;
71612853Sgabeblack@google.com    int len_x = x.length();
71712853Sgabeblack@google.com    int len_a = a.length();
71812853Sgabeblack@google.com    if (len_a > len_x)
71912853Sgabeblack@google.com        len_a = len_x;
72012853Sgabeblack@google.com    for (i = 0; i < len_a; ++i) {
72112853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t((bool)a[i]));
72212853Sgabeblack@google.com    }
72312853Sgabeblack@google.com    for (; i < len_x; ++i) {
72412853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(false));
72512853Sgabeblack@google.com    }
72612853Sgabeblack@google.com}
72712853Sgabeblack@google.com
72812853Sgabeblack@google.comtemplate <class X>
72912853Sgabeblack@google.cominline void
73012853Sgabeblack@google.comassign_v_(sc_proxy<X> &px, const sc_unsigned &a)
73112853Sgabeblack@google.com{
73212853Sgabeblack@google.com    X &x = px.back_cast();
73312853Sgabeblack@google.com    int i;
73412853Sgabeblack@google.com    int len_x = x.length();
73512853Sgabeblack@google.com    int len_a = a.length();
73612853Sgabeblack@google.com    if (len_a > len_x)
73712853Sgabeblack@google.com        len_a = len_x;
73812853Sgabeblack@google.com    for (i = 0; i < len_a; ++i) {
73912853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t((bool)a[i]));
74012853Sgabeblack@google.com    }
74112853Sgabeblack@google.com    for (; i < len_x; ++i) {
74212853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(false));
74312853Sgabeblack@google.com    }
74412853Sgabeblack@google.com}
74512853Sgabeblack@google.com
74612853Sgabeblack@google.com// assignment operators
74712853Sgabeblack@google.comtemplate <class X>
74812853Sgabeblack@google.cominline X &
74912853Sgabeblack@google.comsc_proxy<X>::assign_(const char *a)
75012853Sgabeblack@google.com{
75112853Sgabeblack@google.com    X &x = back_cast();
75212853Sgabeblack@google.com    std::string s = convert_to_bin(a);
75312853Sgabeblack@google.com    int len = x.length();
75412853Sgabeblack@google.com    int s_len = s.length() - 1;
75512853Sgabeblack@google.com    int min_len = sc_min(len, s_len);
75612853Sgabeblack@google.com    int i = 0;
75712853Sgabeblack@google.com    for (; i < min_len; ++i) {
75812853Sgabeblack@google.com        char c = s[s_len - i - 1];
75912853Sgabeblack@google.com        x.set_bit(i, sc_logic::char_to_logic[(int)c]);
76012853Sgabeblack@google.com    }
76112853Sgabeblack@google.com    // if formatted, fill the rest with sign(s), otherwise fill with zeros
76212853Sgabeblack@google.com    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0')
76312853Sgabeblack@google.com                                             : sc_logic_value_t(0));
76412853Sgabeblack@google.com    for (; i < len; ++i) {
76512853Sgabeblack@google.com        x.set_bit(i, fill);
76612853Sgabeblack@google.com    }
76712853Sgabeblack@google.com    return x;
76812853Sgabeblack@google.com}
76912853Sgabeblack@google.com
77012853Sgabeblack@google.comtemplate <class X>
77112853Sgabeblack@google.cominline X &
77212853Sgabeblack@google.comsc_proxy<X>::assign_(const bool *a)
77312853Sgabeblack@google.com{
77412853Sgabeblack@google.com    // the length of 'a' must be larger than or equal to the length of 'this'
77512853Sgabeblack@google.com    X &x = back_cast();
77612853Sgabeblack@google.com    int len = x.length();
77712853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
77812853Sgabeblack@google.com        x.set_bit(i, sc_logic_value_t(a[i]));
77912853Sgabeblack@google.com    }
78012853Sgabeblack@google.com    return x;
78112853Sgabeblack@google.com}
78212853Sgabeblack@google.com
78312853Sgabeblack@google.comtemplate <class X>
78412853Sgabeblack@google.cominline X &
78512853Sgabeblack@google.comsc_proxy<X>::assign_(const sc_logic *a)
78612853Sgabeblack@google.com{
78712853Sgabeblack@google.com    // the length of 'a' must be larger than or equal to the length of 'this'
78812853Sgabeblack@google.com    X &x = back_cast();
78912853Sgabeblack@google.com    int len = x.length();
79012853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
79112853Sgabeblack@google.com        x.set_bit(i, a[i].value());
79212853Sgabeblack@google.com    }
79312853Sgabeblack@google.com    return x;
79412853Sgabeblack@google.com}
79512853Sgabeblack@google.com
79612853Sgabeblack@google.comtemplate <class X>
79712853Sgabeblack@google.cominline X &
79812853Sgabeblack@google.comsc_proxy<X>::assign_(unsigned int a)
79912853Sgabeblack@google.com{
80012853Sgabeblack@google.com    X &x = back_cast();
80112853Sgabeblack@google.com    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
80212853Sgabeblack@google.com    // extend with zeros
80312853Sgabeblack@google.com    extend_sign_w_(x, 1, false);
80412853Sgabeblack@google.com    x.clean_tail();
80512853Sgabeblack@google.com    return x;
80612853Sgabeblack@google.com}
80712853Sgabeblack@google.com
80812853Sgabeblack@google.comtemplate <class X>
80912853Sgabeblack@google.cominline X &
81012853Sgabeblack@google.comsc_proxy<X>::assign_(int a)
81112853Sgabeblack@google.com{
81212853Sgabeblack@google.com    X &x = back_cast();
81312853Sgabeblack@google.com    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
81412853Sgabeblack@google.com    // extend with sign(a)
81512853Sgabeblack@google.com    extend_sign_w_(x, 1, (a < 0));
81612853Sgabeblack@google.com    x.clean_tail();
81712853Sgabeblack@google.com    return x;
81812853Sgabeblack@google.com}
81912853Sgabeblack@google.com
82013197Sgabeblack@google.com#if SC_LONG_64
82112853Sgabeblack@google.comtemplate <class X>
82212853Sgabeblack@google.cominline X &
82312853Sgabeblack@google.comsc_proxy<X>::assign_(unsigned long a)
82412853Sgabeblack@google.com{
82512853Sgabeblack@google.com    X &x = back_cast();
82612853Sgabeblack@google.com    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
82712853Sgabeblack@google.com    if (x.size() > 1) {
82812853Sgabeblack@google.com        set_words_(x, 1, ((sc_digit)(a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
82912853Sgabeblack@google.com                   SC_DIGIT_ZERO);
83012853Sgabeblack@google.com        // extend with zeros
83112853Sgabeblack@google.com        extend_sign_w_(x, 2, false);
83212853Sgabeblack@google.com    }
83312853Sgabeblack@google.com    x.clean_tail();
83412853Sgabeblack@google.com    return x;
83512853Sgabeblack@google.com}
83612853Sgabeblack@google.com
83712853Sgabeblack@google.comtemplate <class X>
83812853Sgabeblack@google.cominline X &
83912853Sgabeblack@google.comsc_proxy<X>::assign_(long a)
84012853Sgabeblack@google.com{
84112853Sgabeblack@google.com    X &x = back_cast();
84212853Sgabeblack@google.com    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
84312853Sgabeblack@google.com    if (x.size() > 1) {
84412853Sgabeblack@google.com        set_words_(x, 1,
84512853Sgabeblack@google.com                   ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
84612853Sgabeblack@google.com                   SC_DIGIT_ZERO);
84712853Sgabeblack@google.com        // extend with sign(a)
84812853Sgabeblack@google.com        extend_sign_w_(x, 2, (a < 0));
84912853Sgabeblack@google.com    }
85012853Sgabeblack@google.com    x.clean_tail();
85112853Sgabeblack@google.com    return x;
85212853Sgabeblack@google.com}
85312853Sgabeblack@google.com
85412853Sgabeblack@google.com#else
85512853Sgabeblack@google.com
85612853Sgabeblack@google.comtemplate <class X>
85712853Sgabeblack@google.cominline X &
85812853Sgabeblack@google.comsc_proxy<X>::assign_(unsigned long a)
85912853Sgabeblack@google.com{
86012853Sgabeblack@google.com    X &x = back_cast();
86112853Sgabeblack@google.com    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
86212853Sgabeblack@google.com    // extend with zeros
86312853Sgabeblack@google.com    extend_sign_w_(x, 1, false);
86412853Sgabeblack@google.com    x.clean_tail();
86512853Sgabeblack@google.com    return x;
86612853Sgabeblack@google.com}
86712853Sgabeblack@google.com
86812853Sgabeblack@google.comtemplate <class X>
86912853Sgabeblack@google.cominline X &
87012853Sgabeblack@google.comsc_proxy<X>::assign_(long a)
87112853Sgabeblack@google.com{
87212853Sgabeblack@google.com    X &x = back_cast();
87312853Sgabeblack@google.com    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
87412853Sgabeblack@google.com    // extend with sign(a)
87512853Sgabeblack@google.com    extend_sign_w_(x, 1, (a < 0));
87612853Sgabeblack@google.com    x.clean_tail();
87712853Sgabeblack@google.com    return x;
87812853Sgabeblack@google.com}
87912853Sgabeblack@google.com
88012853Sgabeblack@google.com#endif
88112853Sgabeblack@google.com
88212853Sgabeblack@google.comtemplate <class X>
88312853Sgabeblack@google.cominline X &
88412853Sgabeblack@google.comsc_proxy<X>::assign_(uint64 a)
88512853Sgabeblack@google.com{
88612853Sgabeblack@google.com    X &x = back_cast();
88712853Sgabeblack@google.com    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
88812853Sgabeblack@google.com    if (x.size() > 1) {
88912853Sgabeblack@google.com        set_words_(x, 1, ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
89012853Sgabeblack@google.com                   SC_DIGIT_ZERO );
89112853Sgabeblack@google.com        // extend with zeros
89212853Sgabeblack@google.com        extend_sign_w_(x, 2, false);
89312853Sgabeblack@google.com    }
89412853Sgabeblack@google.com    x.clean_tail();
89512853Sgabeblack@google.com    return x;
89612853Sgabeblack@google.com}
89712853Sgabeblack@google.com
89812853Sgabeblack@google.comtemplate <class X>
89912853Sgabeblack@google.cominline X &
90012853Sgabeblack@google.comsc_proxy<X>::assign_(int64 a)
90112853Sgabeblack@google.com{
90212853Sgabeblack@google.com    X &x = back_cast();
90312853Sgabeblack@google.com    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
90412853Sgabeblack@google.com    if (x.size() > 1) {
90512853Sgabeblack@google.com        set_words_(x, 1,
90612853Sgabeblack@google.com                   ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
90712853Sgabeblack@google.com                   SC_DIGIT_ZERO );
90812853Sgabeblack@google.com        // extend with sign(a)
90912853Sgabeblack@google.com        extend_sign_w_(x, 2, (a < 0));
91012853Sgabeblack@google.com    }
91112853Sgabeblack@google.com    x.clean_tail();
91212853Sgabeblack@google.com    return x;
91312853Sgabeblack@google.com}
91412853Sgabeblack@google.com
91512853Sgabeblack@google.com// bitwise operators and functions
91612853Sgabeblack@google.com
91712853Sgabeblack@google.com// bitwise complement
91812853Sgabeblack@google.comtemplate <class X>
91912853Sgabeblack@google.cominline X &
92012853Sgabeblack@google.comsc_proxy<X>::b_not()
92112853Sgabeblack@google.com{
92212853Sgabeblack@google.com    X &x = back_cast();
92312853Sgabeblack@google.com    int sz = x.size();
92412853Sgabeblack@google.com    for (int i = 0; i < sz; ++i) {
92512853Sgabeblack@google.com        sc_digit x_dw, x_cw;
92612853Sgabeblack@google.com        get_words_(x, i, x_dw, x_cw);
92712853Sgabeblack@google.com        x.set_word(i, x_cw | ~x_dw);
92812853Sgabeblack@google.com    }
92912853Sgabeblack@google.com    x.clean_tail();
93012853Sgabeblack@google.com    return x;
93112853Sgabeblack@google.com}
93212853Sgabeblack@google.com
93312853Sgabeblack@google.com// bitwise and
93412853Sgabeblack@google.comtemplate <class X, class Y>
93512853Sgabeblack@google.cominline X &
93612853Sgabeblack@google.comb_and_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py)
93712853Sgabeblack@google.com{
93812853Sgabeblack@google.com    X &x = px.back_cast();
93912853Sgabeblack@google.com    const Y &y = py.back_cast();
94012853Sgabeblack@google.com    sc_assert(x.length() == y.length());
94112853Sgabeblack@google.com    int sz = x.size();
94212853Sgabeblack@google.com    for (int i = 0; i < sz; ++i) {
94312853Sgabeblack@google.com        sc_digit x_dw, x_cw, y_dw, y_cw;
94412853Sgabeblack@google.com        get_words_(x, i, x_dw, x_cw);
94512853Sgabeblack@google.com        get_words_(y, i, y_dw, y_cw);
94612853Sgabeblack@google.com        sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw);
94712853Sgabeblack@google.com        sc_digit dw = cw | (x_dw & y_dw);
94812853Sgabeblack@google.com        set_words_(x, i, dw, cw);
94912853Sgabeblack@google.com    }
95012853Sgabeblack@google.com    // tail cleaning not needed
95112853Sgabeblack@google.com    return x;
95212853Sgabeblack@google.com}
95312853Sgabeblack@google.com
95412853Sgabeblack@google.com// bitwise or
95512853Sgabeblack@google.comtemplate <class X, class Y>
95612853Sgabeblack@google.cominline X &
95712853Sgabeblack@google.comb_or_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py)
95812853Sgabeblack@google.com{
95912853Sgabeblack@google.com    X &x = px.back_cast();
96012853Sgabeblack@google.com    const Y &y = py.back_cast();
96112853Sgabeblack@google.com    sc_assert(x.length() == y.length());
96212853Sgabeblack@google.com    int sz = x.size();
96312853Sgabeblack@google.com    for (int i = 0; i < sz; ++i) {
96412853Sgabeblack@google.com        sc_digit x_dw, x_cw, y_dw, y_cw;
96512853Sgabeblack@google.com        get_words_(x, i, x_dw, x_cw);
96612853Sgabeblack@google.com        get_words_(y, i, y_dw, y_cw);
96712853Sgabeblack@google.com        sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw);
96812853Sgabeblack@google.com        sc_digit dw = cw | x_dw | y_dw;
96912853Sgabeblack@google.com        set_words_(x, i, dw, cw);
97012853Sgabeblack@google.com    }
97112853Sgabeblack@google.com    // tail cleaning not needed
97212853Sgabeblack@google.com    return x;
97312853Sgabeblack@google.com}
97412853Sgabeblack@google.com
97512853Sgabeblack@google.com// bitwise xor
97612853Sgabeblack@google.comtemplate <class X, class Y>
97712853Sgabeblack@google.cominline X &
97812853Sgabeblack@google.comb_xor_assign_(sc_proxy<X> &a, const sc_proxy<Y> &b)
97912853Sgabeblack@google.com{
98012853Sgabeblack@google.com    X &x = a.back_cast();
98112853Sgabeblack@google.com    const Y &y = b.back_cast();
98212853Sgabeblack@google.com    sc_assert(x.length() == y.length());
98312853Sgabeblack@google.com    int sz = x.size();
98412853Sgabeblack@google.com    for (int i = 0; i < sz; ++i) {
98512853Sgabeblack@google.com        sc_digit x_dw, x_cw, y_dw, y_cw;
98612853Sgabeblack@google.com        get_words_(x, i, x_dw, x_cw);
98712853Sgabeblack@google.com        get_words_(y, i, y_dw, y_cw);
98812853Sgabeblack@google.com        sc_digit cw = x_cw | y_cw;
98912853Sgabeblack@google.com        sc_digit dw = cw | (x_dw ^ y_dw);
99012853Sgabeblack@google.com        set_words_( x, i, dw, cw );
99112853Sgabeblack@google.com    }
99212853Sgabeblack@google.com    // tail cleaning not needed
99312853Sgabeblack@google.com    return x;
99412853Sgabeblack@google.com}
99512853Sgabeblack@google.com
99612853Sgabeblack@google.com// bitwise left shift
99712853Sgabeblack@google.comtemplate <class X>
99812853Sgabeblack@google.cominline X &
99912853Sgabeblack@google.comsc_proxy<X>::operator <<= (int n)
100012853Sgabeblack@google.com{
100112853Sgabeblack@google.com    X &x = back_cast();
100212853Sgabeblack@google.com    if (n < 0) {
100312853Sgabeblack@google.com        sc_proxy_out_of_bounds("left shift operation is only allowed with "
100412853Sgabeblack@google.com                               "positive shift values, shift value = ", n);
100512853Sgabeblack@google.com        return x;
100612853Sgabeblack@google.com    }
100712853Sgabeblack@google.com    if (n >= x.length()) {
100812853Sgabeblack@google.com        extend_sign_w_(x, 0, false);
100912853Sgabeblack@google.com        // no tail cleaning needed
101012853Sgabeblack@google.com        return x;
101112853Sgabeblack@google.com    }
101212853Sgabeblack@google.com    int sz = x.size();
101312853Sgabeblack@google.com    int wn = n / SC_DIGIT_SIZE;
101412853Sgabeblack@google.com    int bn = n % SC_DIGIT_SIZE;
101512853Sgabeblack@google.com    if (wn != 0) {
101612853Sgabeblack@google.com        // shift words
101712853Sgabeblack@google.com        int i = sz - 1;
101812853Sgabeblack@google.com        for (; i >= wn; --i) {
101912853Sgabeblack@google.com            set_words_(x, i, x.get_word(i - wn), x.get_cword(i - wn));
102012853Sgabeblack@google.com        }
102112853Sgabeblack@google.com        for (; i >= 0; --i) {
102212853Sgabeblack@google.com            set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO);
102312853Sgabeblack@google.com        }
102412853Sgabeblack@google.com    }
102512853Sgabeblack@google.com    if (bn != 0) {
102612853Sgabeblack@google.com        // shift bits
102712853Sgabeblack@google.com        for (int i = sz - 1; i >= 1; --i) {
102812853Sgabeblack@google.com            sc_digit x_dw, x_cw;
102912853Sgabeblack@google.com            get_words_(x, i, x_dw, x_cw);
103012853Sgabeblack@google.com            x_dw <<= bn;
103112853Sgabeblack@google.com            x_dw |= x.get_word(i - 1) >> (SC_DIGIT_SIZE - bn);
103212853Sgabeblack@google.com            x_cw <<= bn;
103312853Sgabeblack@google.com            x_cw |= x.get_cword(i - 1) >> (SC_DIGIT_SIZE - bn);
103412853Sgabeblack@google.com            set_words_(x, i, x_dw, x_cw);
103512853Sgabeblack@google.com        }
103612853Sgabeblack@google.com        sc_digit x_dw, x_cw;
103712853Sgabeblack@google.com        get_words_(x, 0, x_dw, x_cw);
103812853Sgabeblack@google.com        x_dw <<= bn;
103912853Sgabeblack@google.com        x_cw <<= bn;
104012853Sgabeblack@google.com        set_words_(x, 0, x_dw, x_cw);
104112853Sgabeblack@google.com    }
104212853Sgabeblack@google.com    x.clean_tail();
104312853Sgabeblack@google.com    return x;
104412853Sgabeblack@google.com}
104512853Sgabeblack@google.com
104612853Sgabeblack@google.com// bitwise right shift
104712853Sgabeblack@google.comtemplate <class X>
104812853Sgabeblack@google.cominline X &
104912853Sgabeblack@google.comsc_proxy<X>::operator >>= (int n)
105012853Sgabeblack@google.com{
105112853Sgabeblack@google.com    X &x = back_cast();
105212853Sgabeblack@google.com    if (n < 0) {
105312853Sgabeblack@google.com        sc_proxy_out_of_bounds("right shift operation is only allowed with "
105412853Sgabeblack@google.com                               "positive shift values, shift value = ", n);
105512853Sgabeblack@google.com        return x;
105612853Sgabeblack@google.com    }
105712853Sgabeblack@google.com    if (n >= x.length()) {
105812853Sgabeblack@google.com        extend_sign_w_(x, 0, false);
105912853Sgabeblack@google.com        // no tail cleaning needed
106012853Sgabeblack@google.com        return x;
106112853Sgabeblack@google.com    }
106212853Sgabeblack@google.com    int sz = x.size();
106312853Sgabeblack@google.com    int wn = n / SC_DIGIT_SIZE;
106412853Sgabeblack@google.com    int bn = n % SC_DIGIT_SIZE;
106512853Sgabeblack@google.com    if (wn != 0) {
106612853Sgabeblack@google.com        // shift words
106712853Sgabeblack@google.com        int i = 0;
106812853Sgabeblack@google.com        for (; i < (sz - wn); ++i) {
106912853Sgabeblack@google.com            set_words_(x, i, x.get_word(i + wn), x.get_cword(i + wn));
107012853Sgabeblack@google.com        }
107112853Sgabeblack@google.com        for (; i < sz; ++i) {
107212853Sgabeblack@google.com            set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO);
107312853Sgabeblack@google.com        }
107412853Sgabeblack@google.com    }
107512853Sgabeblack@google.com    if (bn != 0) {
107612853Sgabeblack@google.com        // shift bits
107712853Sgabeblack@google.com        for (int i = 0; i < (sz - 1); ++i) {
107812853Sgabeblack@google.com            sc_digit x_dw, x_cw;
107912853Sgabeblack@google.com            get_words_(x, i, x_dw, x_cw);
108012853Sgabeblack@google.com            x_dw >>= bn;
108112853Sgabeblack@google.com            x_dw |= x.get_word(i + 1) << (SC_DIGIT_SIZE - bn);
108212853Sgabeblack@google.com            x_cw >>= bn;
108312853Sgabeblack@google.com            x_cw |= x.get_cword(i + 1) << (SC_DIGIT_SIZE - bn);
108412853Sgabeblack@google.com            set_words_(x, i, x_dw, x_cw);
108512853Sgabeblack@google.com        }
108612853Sgabeblack@google.com        sc_digit x_dw, x_cw;
108712853Sgabeblack@google.com        get_words_(x, sz - 1, x_dw, x_cw);
108812853Sgabeblack@google.com        x_dw >>= bn;
108912853Sgabeblack@google.com        x_cw >>= bn;
109012853Sgabeblack@google.com        set_words_(x, sz - 1, x_dw, x_cw);
109112853Sgabeblack@google.com    }
109212853Sgabeblack@google.com    x.clean_tail();
109312853Sgabeblack@google.com    return x;
109412853Sgabeblack@google.com}
109512853Sgabeblack@google.com
109612853Sgabeblack@google.com// bitwise left rotate
109712853Sgabeblack@google.comtemplate <class X>
109812853Sgabeblack@google.cominline const sc_lv_base lrotate(const sc_proxy<X> &x, int n);
109912853Sgabeblack@google.com
110012853Sgabeblack@google.com// bitwise right rotate
110112853Sgabeblack@google.comtemplate <class X>
110212853Sgabeblack@google.cominline const sc_lv_base rrotate(const sc_proxy<X>& x, int n);
110312853Sgabeblack@google.com
110412853Sgabeblack@google.com// bitwise reverse
110512853Sgabeblack@google.comtemplate <class X>
110612853Sgabeblack@google.cominline X &
110712853Sgabeblack@google.comsc_proxy<X>::reverse()
110812853Sgabeblack@google.com{
110912853Sgabeblack@google.com    X &x = back_cast();
111012853Sgabeblack@google.com    int len = x.length();
111112853Sgabeblack@google.com    int half_len = len / 2;
111212853Sgabeblack@google.com    for (int i = 0, j = len - 1; i < half_len; ++ i, --j) {
111312853Sgabeblack@google.com        value_type t = x.get_bit(i);
111412853Sgabeblack@google.com        x.set_bit(i, x.get_bit(j));
111512853Sgabeblack@google.com        x.set_bit(j, t);
111612853Sgabeblack@google.com    }
111712853Sgabeblack@google.com    return x;
111812853Sgabeblack@google.com}
111912853Sgabeblack@google.com
112012853Sgabeblack@google.comtemplate <class X>
112112853Sgabeblack@google.cominline const sc_lv_base reverse(const sc_proxy<X> &a);
112212853Sgabeblack@google.com
112312853Sgabeblack@google.com// reduce functions
112412853Sgabeblack@google.comtemplate <class X>
112512853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
112612853Sgabeblack@google.comsc_proxy<X>::and_reduce() const
112712853Sgabeblack@google.com{
112812853Sgabeblack@google.com    const X &x = back_cast();
112912853Sgabeblack@google.com    value_type result = value_type(1);
113012853Sgabeblack@google.com    int len = x.length();
113112853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
113212853Sgabeblack@google.com        result = sc_logic::and_table[result][x.get_bit(i)];
113312853Sgabeblack@google.com    }
113412853Sgabeblack@google.com    return result;
113512853Sgabeblack@google.com}
113612853Sgabeblack@google.com
113712853Sgabeblack@google.comtemplate <class X>
113812853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
113912853Sgabeblack@google.comsc_proxy<X>::or_reduce() const
114012853Sgabeblack@google.com{
114112853Sgabeblack@google.com    const X &x = back_cast();
114212853Sgabeblack@google.com    value_type result = value_type(0);
114312853Sgabeblack@google.com    int len = x.length();
114412853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
114512853Sgabeblack@google.com        result = sc_logic::or_table[result][x.get_bit(i)];
114612853Sgabeblack@google.com    }
114712853Sgabeblack@google.com    return result;
114812853Sgabeblack@google.com}
114912853Sgabeblack@google.com
115012853Sgabeblack@google.comtemplate <class X>
115112853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
115212853Sgabeblack@google.comsc_proxy<X>::xor_reduce() const
115312853Sgabeblack@google.com{
115412853Sgabeblack@google.com    const X &x = back_cast();
115512853Sgabeblack@google.com    value_type result = value_type(0);
115612853Sgabeblack@google.com    int len = x.length();
115712853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
115812853Sgabeblack@google.com        result = sc_logic::xor_table[result][x.get_bit(i)];
115912853Sgabeblack@google.com    }
116012853Sgabeblack@google.com    return result;
116112853Sgabeblack@google.com}
116212853Sgabeblack@google.com
116312853Sgabeblack@google.com// relational operators
116412853Sgabeblack@google.comtemplate <class X, class Y>
116512853Sgabeblack@google.cominline bool
116612853Sgabeblack@google.comoperator != (const sc_proxy<X> &px, const sc_proxy<Y> &py)
116712853Sgabeblack@google.com{
116812853Sgabeblack@google.com    return !(px == py);
116912853Sgabeblack@google.com}
117012853Sgabeblack@google.com
117112853Sgabeblack@google.com
117212853Sgabeblack@google.com#define DEFN_REL_OP_T(tp) \
117312853Sgabeblack@google.comtemplate <class X> \
117412853Sgabeblack@google.cominline bool operator == (tp b, const sc_proxy<X> &px) { return (px == b); } \
117512853Sgabeblack@google.com \
117612853Sgabeblack@google.comtemplate <class X> \
117712853Sgabeblack@google.cominline bool operator != (const sc_proxy<X> &px, tp b) { return !(px == b); } \
117812853Sgabeblack@google.com \
117912853Sgabeblack@google.comtemplate <class X> \
118012853Sgabeblack@google.cominline bool operator != (tp b, const sc_proxy<X> &px) { return !(px == b); }
118112853Sgabeblack@google.com
118212853Sgabeblack@google.comDEFN_REL_OP_T(const char *)
118312853Sgabeblack@google.comDEFN_REL_OP_T(const bool *)
118412853Sgabeblack@google.comDEFN_REL_OP_T(const sc_logic *)
118512853Sgabeblack@google.comDEFN_REL_OP_T(const sc_unsigned &)
118612853Sgabeblack@google.comDEFN_REL_OP_T(const sc_signed &)
118712853Sgabeblack@google.comDEFN_REL_OP_T(const sc_uint_base &)
118812853Sgabeblack@google.comDEFN_REL_OP_T(const sc_int_base &)
118912853Sgabeblack@google.comDEFN_REL_OP_T(unsigned long)
119012853Sgabeblack@google.comDEFN_REL_OP_T(long)
119112853Sgabeblack@google.comDEFN_REL_OP_T(unsigned int)
119212853Sgabeblack@google.comDEFN_REL_OP_T(int)
119312853Sgabeblack@google.comDEFN_REL_OP_T(uint64)
119412853Sgabeblack@google.comDEFN_REL_OP_T(int64)
119512853Sgabeblack@google.com
119612853Sgabeblack@google.com#undef DEFN_REL_OP_T
119712853Sgabeblack@google.com
119812853Sgabeblack@google.com// explicit conversions to character string
119912853Sgabeblack@google.comtemplate <class X>
120012853Sgabeblack@google.cominline const std::string
120112853Sgabeblack@google.comsc_proxy<X>::to_string() const
120212853Sgabeblack@google.com{
120312853Sgabeblack@google.com    const X &x = back_cast();
120412853Sgabeblack@google.com    int len = x.length();
120512853Sgabeblack@google.com    std::string s; // (len + 1);
120612853Sgabeblack@google.com    for (int i = 0; i < len; ++i) {
120712853Sgabeblack@google.com        s += sc_logic::logic_to_char[x.get_bit(len - i - 1)];
120812853Sgabeblack@google.com    }
120912853Sgabeblack@google.com    return s;
121012853Sgabeblack@google.com}
121112853Sgabeblack@google.com
121212853Sgabeblack@google.comtemplate <class X>
121312853Sgabeblack@google.cominline const std::string
121412853Sgabeblack@google.comsc_proxy<X>::to_string(sc_numrep numrep) const
121512853Sgabeblack@google.com{
121612853Sgabeblack@google.com    return convert_to_fmt(to_string(), numrep, true);
121712853Sgabeblack@google.com}
121812853Sgabeblack@google.com
121912853Sgabeblack@google.comtemplate <class X>
122012853Sgabeblack@google.cominline const std::string
122112853Sgabeblack@google.comsc_proxy<X>::to_string(sc_numrep numrep, bool w_prefix) const
122212853Sgabeblack@google.com{
122312853Sgabeblack@google.com    return convert_to_fmt(to_string(), numrep, w_prefix);
122412853Sgabeblack@google.com}
122512853Sgabeblack@google.com
122612853Sgabeblack@google.com// other methods
122712853Sgabeblack@google.comtemplate <class X>
122812853Sgabeblack@google.cominline void
122912853Sgabeblack@google.comsc_proxy<X>::scan(::std::istream &is)
123012853Sgabeblack@google.com{
123112853Sgabeblack@google.com    std::string s;
123212853Sgabeblack@google.com    is >> s;
123312853Sgabeblack@google.com    back_cast() = s.c_str();
123412853Sgabeblack@google.com}
123512853Sgabeblack@google.com
123612853Sgabeblack@google.comtemplate <class X>
123712853Sgabeblack@google.cominline void
123812853Sgabeblack@google.comsc_proxy<X>::check_bounds(int n) const // check if bit n accessible
123912853Sgabeblack@google.com{
124012853Sgabeblack@google.com    if (n < 0 || n >= back_cast().length()) {
124112853Sgabeblack@google.com        sc_proxy_out_of_bounds(NULL, n);
124212853Sgabeblack@google.com        sc_core::sc_abort(); // can't recover from here
124312853Sgabeblack@google.com    }
124412853Sgabeblack@google.com}
124512853Sgabeblack@google.com
124612853Sgabeblack@google.comtemplate <class X>
124712853Sgabeblack@google.cominline void
124812853Sgabeblack@google.comsc_proxy<X>::check_wbounds(int n) const // check if word n accessible
124912853Sgabeblack@google.com{
125012853Sgabeblack@google.com    if (n < 0 || n >= back_cast().size()) {
125112853Sgabeblack@google.com        sc_proxy_out_of_bounds(NULL, n);
125212853Sgabeblack@google.com        sc_core::sc_abort(); // can't recover from here
125312853Sgabeblack@google.com    }
125412853Sgabeblack@google.com}
125512853Sgabeblack@google.com
125612853Sgabeblack@google.comtemplate <class X>
125712853Sgabeblack@google.cominline sc_digit
125812853Sgabeblack@google.comsc_proxy<X>::to_anything_unsigned() const
125912853Sgabeblack@google.com{
126012853Sgabeblack@google.com    // only 0 word is returned
126112853Sgabeblack@google.com    // can't convert logic values other than 0 and 1
126212853Sgabeblack@google.com    const X &x = back_cast();
126312853Sgabeblack@google.com    int len = x.length();
126412853Sgabeblack@google.com    if (x.get_cword(0) != SC_DIGIT_ZERO) {
126513325Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
126612853Sgabeblack@google.com    }
126712853Sgabeblack@google.com    sc_digit w = x.get_word(0);
126812853Sgabeblack@google.com    if (len >= SC_DIGIT_SIZE) {
126912853Sgabeblack@google.com        return w;
127012853Sgabeblack@google.com    }
127112853Sgabeblack@google.com    return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)));
127212853Sgabeblack@google.com}
127312853Sgabeblack@google.com
127412853Sgabeblack@google.comtemplate <class X>
127512853Sgabeblack@google.cominline uint64
127612853Sgabeblack@google.comsc_proxy<X>::to_uint64() const
127712853Sgabeblack@google.com{
127812853Sgabeblack@google.com    // words 1 and 0 returned.
127912853Sgabeblack@google.com    // can't convert logic values other than 0 and 1
128012853Sgabeblack@google.com    const X &x = back_cast();
128112853Sgabeblack@google.com    int len = x.length();
128212853Sgabeblack@google.com    if (x.get_cword(0) != SC_DIGIT_ZERO) {
128313325Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
128412853Sgabeblack@google.com    }
128512853Sgabeblack@google.com    uint64 w = x.get_word(0);
128612853Sgabeblack@google.com    if (len > SC_DIGIT_SIZE) {
128712853Sgabeblack@google.com        if (x.get_cword(1) != SC_DIGIT_ZERO) {
128813325Sgabeblack@google.com            SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
128912853Sgabeblack@google.com        }
129012853Sgabeblack@google.com        uint64 w1 = x.get_word(1);
129112853Sgabeblack@google.com        w = w | (w1 << SC_DIGIT_SIZE);
129212853Sgabeblack@google.com        return w;
129312853Sgabeblack@google.com    } else if (len == SC_DIGIT_SIZE) {
129412853Sgabeblack@google.com        return w;
129512853Sgabeblack@google.com    } else {
129612853Sgabeblack@google.com        return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)));
129712853Sgabeblack@google.com    }
129812853Sgabeblack@google.com}
129912853Sgabeblack@google.com
130012853Sgabeblack@google.comtemplate <class X>
130112853Sgabeblack@google.cominline int64
130212853Sgabeblack@google.comsc_proxy<X>::to_anything_signed() const
130312853Sgabeblack@google.com{
130412853Sgabeblack@google.com    const X &x = back_cast();
130512853Sgabeblack@google.com    int len = x.length();
130612853Sgabeblack@google.com    int64 w = 0;
130712853Sgabeblack@google.com
130812853Sgabeblack@google.com    if (len > SC_DIGIT_SIZE) {
130912853Sgabeblack@google.com        if (x.get_cword(1) != SC_DIGIT_ZERO)
131013325Sgabeblack@google.com            SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
131112853Sgabeblack@google.com        w = x.get_word(1);
131212853Sgabeblack@google.com    }
131312853Sgabeblack@google.com    if (x.get_cword(0) != SC_DIGIT_ZERO)
131413325Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
131512853Sgabeblack@google.com    w = (w << SC_DIGIT_SIZE) | x.get_word(0);
131612853Sgabeblack@google.com    if (len >= 64) {
131712853Sgabeblack@google.com        return w;
131812853Sgabeblack@google.com    }
131912853Sgabeblack@google.com
132012853Sgabeblack@google.com    uint64 zero = 0;
132112853Sgabeblack@google.com    value_type sgn = x.get_bit(len - 1);
132212853Sgabeblack@google.com    if (sgn == 0) {
132312853Sgabeblack@google.com        return (int64)(w & (~zero >> (64 - len)));
132412853Sgabeblack@google.com    } else {
132512853Sgabeblack@google.com        return (int64)(w | (~zero << len));
132612853Sgabeblack@google.com    }
132712853Sgabeblack@google.com}
132812853Sgabeblack@google.com
132912853Sgabeblack@google.com
133012853Sgabeblack@google.com// ----------------------------------------------------------------------------
133112853Sgabeblack@google.com
133212853Sgabeblack@google.com// functional notation for the reduce methods
133312853Sgabeblack@google.comtemplate <class X>
133412853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
133512853Sgabeblack@google.comand_reduce(const sc_proxy<X> &a)
133612853Sgabeblack@google.com{
133712853Sgabeblack@google.com    return a.and_reduce();
133812853Sgabeblack@google.com}
133912853Sgabeblack@google.com
134012853Sgabeblack@google.comtemplate <class X>
134112853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
134212853Sgabeblack@google.comnand_reduce(const sc_proxy<X> &a)
134312853Sgabeblack@google.com{
134412853Sgabeblack@google.com    return a.nand_reduce();
134512853Sgabeblack@google.com}
134612853Sgabeblack@google.com
134712853Sgabeblack@google.comtemplate <class X>
134812853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
134912853Sgabeblack@google.comor_reduce(const sc_proxy<X> &a)
135012853Sgabeblack@google.com{
135112853Sgabeblack@google.com    return a.or_reduce();
135212853Sgabeblack@google.com}
135312853Sgabeblack@google.com
135412853Sgabeblack@google.comtemplate <class X>
135512853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
135612853Sgabeblack@google.comnor_reduce(const sc_proxy<X> &a)
135712853Sgabeblack@google.com{
135812853Sgabeblack@google.com    return a.nor_reduce();
135912853Sgabeblack@google.com}
136012853Sgabeblack@google.com
136112853Sgabeblack@google.comtemplate <class X>
136212853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
136312853Sgabeblack@google.comxor_reduce(const sc_proxy<X> &a)
136412853Sgabeblack@google.com{
136512853Sgabeblack@google.com    return a.xor_reduce();
136612853Sgabeblack@google.com}
136712853Sgabeblack@google.com
136812853Sgabeblack@google.comtemplate <class X>
136912853Sgabeblack@google.cominline typename sc_proxy<X>::value_type
137012853Sgabeblack@google.comxnor_reduce(const sc_proxy<X> &a)
137112853Sgabeblack@google.com{
137212853Sgabeblack@google.com    return a.xnor_reduce();
137312853Sgabeblack@google.com}
137412853Sgabeblack@google.com
137512853Sgabeblack@google.com// ----------------------------------------------------------------------------
137612853Sgabeblack@google.com
137712853Sgabeblack@google.comtemplate <class X>
137812853Sgabeblack@google.cominline ::std::ostream &
137912853Sgabeblack@google.comoperator << (::std::ostream &os, const sc_proxy<X> &a)
138012853Sgabeblack@google.com{
138112853Sgabeblack@google.com    a.print(os);
138212853Sgabeblack@google.com    return os;
138312853Sgabeblack@google.com}
138412853Sgabeblack@google.com
138512853Sgabeblack@google.comtemplate <class X>
138612853Sgabeblack@google.cominline ::std::istream &
138712853Sgabeblack@google.comoperator >> (::std::istream &is, sc_proxy<X> &a)
138812853Sgabeblack@google.com{
138912853Sgabeblack@google.com    a.scan(is);
139012853Sgabeblack@google.com    return is;
139112853Sgabeblack@google.com}
139212853Sgabeblack@google.com
139312853Sgabeblack@google.com} // namespace sc_dt
139412853Sgabeblack@google.com
139512853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
1396