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