sc_proxy.hh revision 13325
12SN/A/*****************************************************************************
21762SN/A
32SN/A  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
42SN/A  more contributor license agreements.  See the NOTICE file distributed
52SN/A  with this work for additional information regarding copyright ownership.
62SN/A  Accellera licenses this file to you under the Apache License, Version 2.0
72SN/A  (the "License"); you may not use this file except in compliance with the
82SN/A  License.  You may obtain a copy of the License at
92SN/A
102SN/A    http://www.apache.org/licenses/LICENSE-2.0
112SN/A
122SN/A  Unless required by applicable law or agreed to in writing, software
132SN/A  distributed under the License is distributed on an "AS IS" BASIS,
142SN/A  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152SN/A  implied.  See the License for the specific language governing
162SN/A  permissions and limitations under the License.
172SN/A
182SN/A *****************************************************************************/
192SN/A
202SN/A/*****************************************************************************
212SN/A
222SN/A  sc_proxy.h -- Proxy base class for vector data types.
232SN/A
242SN/A                This class is created for several purposes:
252SN/A                1) hiding operators from the global namespace that would be
262SN/A                   otherwise found by Koenig lookup
272665Ssaidi@eecs.umich.edu                2) avoiding repeating the same operations in every class
282665Ssaidi@eecs.umich.edu                   including proxies that could also be achieved by common
292665Ssaidi@eecs.umich.edu                   base class, but this method allows
302665Ssaidi@eecs.umich.edu                3) improve performance by using non-virtual functions
312665Ssaidi@eecs.umich.edu
322SN/A  Original Author: Gene Bushuyev, Synopsys, Inc.
332SN/A
342SN/A *****************************************************************************/
352SN/A
363506Ssaidi@eecs.umich.edu/*****************************************************************************
373506Ssaidi@eecs.umich.edu
382SN/A  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
392973Sgblack@eecs.umich.edu  changes you are making here.
403584Ssaidi@eecs.umich.edu
4156SN/A      Name, Affiliation, Date:
423614Sgblack@eecs.umich.edu  Description of Modification:
431717SN/A
442518SN/A *****************************************************************************/
4556SN/A
462518SN/A// $Log: sc_proxy.h,v $
472518SN/A// Revision 1.3  2010/12/07 20:09:07  acg
482SN/A// Andy Goodrich: Fix for returning enough data
493614Sgblack@eecs.umich.edu//
503614Sgblack@eecs.umich.edu// Revision 1.2  2009/02/28 00:26:14  acg
513614Sgblack@eecs.umich.edu//  Andy Goodrich: bug fixes.
523614Sgblack@eecs.umich.edu//
533065Sgblack@eecs.umich.edu// Revision 1.1.1.1  2006/12/15 20:31:36  acg
543065Sgblack@eecs.umich.edu// SystemC 2.2
553506Ssaidi@eecs.umich.edu//
563065Sgblack@eecs.umich.edu// Revision 1.3  2006/01/13 18:53:53  acg
572SN/A// Andy Goodrich: added $Log command so that CVS comments are reproduced in
582973Sgblack@eecs.umich.edu// the source.
592SN/A//
603840Shsul@eecs.umich.edu
613825Ssaidi@eecs.umich.edu#ifndef __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
623903Ssaidi@eecs.umich.edu#define __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
633840Shsul@eecs.umich.edu
643825Ssaidi@eecs.umich.edu#include <iostream>
653506Ssaidi@eecs.umich.edu
663506Ssaidi@eecs.umich.edu#include "../../utils/functions.hh"
674054Sbinkertn@umich.edu#include "../int/sc_int_base.hh"
684054Sbinkertn@umich.edu#include "../int/sc_signed.hh"
694054Sbinkertn@umich.edu#include "../int/sc_uint_base.hh"
704054Sbinkertn@umich.edu#include "../int/sc_unsigned.hh"
714054Sbinkertn@umich.edu#include "messages.hh"
724054Sbinkertn@umich.edu#include "sc_bit.hh"
734054Sbinkertn@umich.edu#include "sc_logic.hh"
744054Sbinkertn@umich.edu
754054Sbinkertn@umich.edunamespace sc_dt
764054Sbinkertn@umich.edu{
774054Sbinkertn@umich.edu
784054Sbinkertn@umich.edu// classes defined in this module
794054Sbinkertn@umich.edutemplate <class X>
804054Sbinkertn@umich.educlass sc_proxy;
814054Sbinkertn@umich.edu
824054Sbinkertn@umich.edu// forward class declarations
834054Sbinkertn@umich.educlass sc_bv_base;
844054Sbinkertn@umich.educlass sc_lv_base;
854054Sbinkertn@umich.edutemplate <class X>
864054Sbinkertn@umich.educlass sc_bitref_r;
874054Sbinkertn@umich.edutemplate <class X>
883506Ssaidi@eecs.umich.educlass sc_bitref;
893506Ssaidi@eecs.umich.edutemplate <class X>
902SN/Aclass sc_subref_r;
912SN/Atemplate <class X>
922SN/Aclass sc_subref;
932SN/Atemplate <class X, class Y>
942SN/Aclass sc_concref_r;
953748Sgblack@eecs.umich.edutemplate <class X, class Y>
963748Sgblack@eecs.umich.educlass sc_concref;
973748Sgblack@eecs.umich.edu
983748Sgblack@eecs.umich.educonst int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof(sc_digit);
993748Sgblack@eecs.umich.edu
1003748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_ZERO = (sc_digit)0;
1013748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_ONE = (sc_digit)1;
1023748Sgblack@eecs.umich.educonst sc_digit SC_DIGIT_TWO = (sc_digit)2;
1033748Sgblack@eecs.umich.edu
1043748Sgblack@eecs.umich.eduvoid sc_proxy_out_of_bounds(const char *msg=NULL, int64 val=0);
1053748Sgblack@eecs.umich.edu
1063748Sgblack@eecs.umich.edu// assignment functions; forward declarations
1073748Sgblack@eecs.umich.edu
1083748Sgblack@eecs.umich.edutemplate <class X, class Y>
1093748Sgblack@eecs.umich.eduinline void assign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py);
1103748Sgblack@eecs.umich.edu
1113748Sgblack@eecs.umich.edu// Vector types that are not derived from sc_proxy must have a length()
1123748Sgblack@eecs.umich.edu// function and an operator [].
1133748Sgblack@eecs.umich.edu
1143748Sgblack@eecs.umich.edutemplate <class X, class T>
1153748Sgblack@eecs.umich.eduinline void assign_v_(sc_proxy<X> &px, const T &a);
1163748Sgblack@eecs.umich.edu
1173748Sgblack@eecs.umich.edu// other functions; forward declarations
1183748Sgblack@eecs.umich.educonst std::string convert_to_bin(const char *s);
1193748Sgblack@eecs.umich.educonst std::string convert_to_fmt(const std::string &s, sc_numrep numrep, bool);
1203748Sgblack@eecs.umich.edu
1213748Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
1223748Sgblack@eecs.umich.edu//  CLASS TEMPLATE : sc_proxy_traits
1233748Sgblack@eecs.umich.edu//
1243748Sgblack@eecs.umich.edu// Template traits helper to select the correct bit/value/vector_types for
1253748Sgblack@eecs.umich.edu// sc_proxy-based vector classes.
1263748Sgblack@eecs.umich.edu//
1273748Sgblack@eecs.umich.edu// All types derived from/based on a bit-vector contain typedef to a plain
1283748Sgblack@eecs.umich.edu// bool, all others point to the sc_logic_value_t/sc_logic/sc_lv_base types.
1293748Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
1303748Sgblack@eecs.umich.edu
1313748Sgblack@eecs.umich.edutemplate <typename X>
1323748Sgblack@eecs.umich.edustruct sc_proxy_traits;
1333748Sgblack@eecs.umich.edu
1343748Sgblack@eecs.umich.edutemplate <>
1353748Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bv_base>
1363748Sgblack@eecs.umich.edu{
1373748Sgblack@eecs.umich.edu    typedef sc_proxy_traits<sc_bv_base> traits_type;
1383748Sgblack@eecs.umich.edu    typedef bool value_type;
1393748Sgblack@eecs.umich.edu    typedef sc_logic bit_type; // sc_logic needed for mixed expressions
1403748Sgblack@eecs.umich.edu    typedef sc_bv_base vector_type;
1413748Sgblack@eecs.umich.edu};
1423748Sgblack@eecs.umich.edu
1433748Sgblack@eecs.umich.edutemplate <>
1443748Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_lv_base>
1452SN/A{
1462SN/A    typedef sc_proxy_traits<sc_lv_base> traits_type;
1474046Sbinkertn@umich.edu    typedef sc_logic_value_t value_type;
1482SN/A    typedef sc_logic bit_type;
1494046Sbinkertn@umich.edu    typedef sc_lv_base vector_type;
1504046Sbinkertn@umich.edu};
1513903Ssaidi@eecs.umich.edu
1524054Sbinkertn@umich.edutemplate <typename X>
1532973Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bitref_r<X> > : sc_proxy_traits<X> {};
1543065Sgblack@eecs.umich.edu
1553380Sgblack@eecs.umich.edutemplate <typename X>
1563380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_bitref<X> > : sc_proxy_traits<X> {};
1573380Sgblack@eecs.umich.edu
1583380Sgblack@eecs.umich.edutemplate <typename X>
1593380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_subref_r<X> > : sc_proxy_traits<X> {};
1603380Sgblack@eecs.umich.edu
1613380Sgblack@eecs.umich.edutemplate <typename X>
1623380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_subref<X> > : sc_proxy_traits<X> {};
1633380Sgblack@eecs.umich.edu
1643380Sgblack@eecs.umich.edutemplate <typename X>
1653380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_proxy<X> > : sc_proxy_traits<X> {};
1663380Sgblack@eecs.umich.edu
1673380Sgblack@eecs.umich.edu
1683380Sgblack@eecs.umich.edutemplate <typename X, typename Y>
1693065Sgblack@eecs.umich.edustruct sc_mixed_proxy_traits_helper : sc_proxy_traits<sc_lv_base>
1703588Sgblack@eecs.umich.edu{}; // logic vector by default
1713588Sgblack@eecs.umich.edu
1723588Sgblack@eecs.umich.edutemplate <typename X>
1733790Sgblack@eecs.umich.edustruct sc_mixed_proxy_traits_helper<X, X> : X {};
1743790Sgblack@eecs.umich.edu
1753380Sgblack@eecs.umich.edutemplate <typename X, typename Y>
1763059Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_concref_r<X, Y> > :
1773588Sgblack@eecs.umich.edu        sc_mixed_proxy_traits_helper<
1783380Sgblack@eecs.umich.edu            typename X::traits_type, typename Y::traits_type>
1793380Sgblack@eecs.umich.edu{};
1803790Sgblack@eecs.umich.edu
1813790Sgblack@eecs.umich.edutemplate <typename X, typename Y>
1823380Sgblack@eecs.umich.edustruct sc_proxy_traits<sc_concref<X, Y> > :
1833380Sgblack@eecs.umich.edu        sc_mixed_proxy_traits_helper<
1843588Sgblack@eecs.umich.edu            typename X::traits_type, typename Y::traits_type>
1853380Sgblack@eecs.umich.edu{};
1863380Sgblack@eecs.umich.edu
1873380Sgblack@eecs.umich.edu
1883380Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
1893380Sgblack@eecs.umich.edu//  CLASS TEMPLATE : sc_proxy
1903059Sgblack@eecs.umich.edu//
1913380Sgblack@eecs.umich.edu//  Base class template for bit/logic vector classes.
1923380Sgblack@eecs.umich.edu//  (Barton/Nackmann implementation)
1933380Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
1943380Sgblack@eecs.umich.edu
1953588Sgblack@eecs.umich.edutemplate <class X>
1963380Sgblack@eecs.umich.educlass sc_proxy // #### : public sc_value_base
1973380Sgblack@eecs.umich.edu{
1983059Sgblack@eecs.umich.edu  public:
1993059Sgblack@eecs.umich.edu    typedef typename sc_proxy_traits<X>::traits_type traits_type;
2003380Sgblack@eecs.umich.edu    typedef typename traits_type::bit_type bit_type;
2013380Sgblack@eecs.umich.edu    typedef typename traits_type::value_type value_type;
2023380Sgblack@eecs.umich.edu
2033380Sgblack@eecs.umich.edu    // virtual destructor
2043380Sgblack@eecs.umich.edu    virtual ~sc_proxy() {}
2053588Sgblack@eecs.umich.edu
2063380Sgblack@eecs.umich.edu    // casts
2073380Sgblack@eecs.umich.edu    X &back_cast() { return static_cast<X &>(*this); }
2083380Sgblack@eecs.umich.edu
2093588Sgblack@eecs.umich.edu    const X &back_cast() const { return static_cast<const X &>(*this); }
2103059Sgblack@eecs.umich.edu
2113065Sgblack@eecs.umich.edu    // assignment operators
2122973Sgblack@eecs.umich.edu    template <class Y>
2134054Sbinkertn@umich.edu    X &
2144054Sbinkertn@umich.edu    assign_(const sc_proxy<Y> &a)
2154054Sbinkertn@umich.edu    {
2164054Sbinkertn@umich.edu        assign_p_(*this, a);
2174054Sbinkertn@umich.edu        return back_cast();
2184054Sbinkertn@umich.edu    }
2194054Sbinkertn@umich.edu
2201904SN/A    X &assign_(const char *a);
2214054Sbinkertn@umich.edu    X &assign_(const bool *a);
2221904SN/A    X &assign_(const sc_logic *a);
2234054Sbinkertn@umich.edu
2244046Sbinkertn@umich.edu    X &
225452SN/A    assign_(const sc_unsigned &a)
2263064Sgblack@eecs.umich.edu    {
2272SN/A        assign_v_(*this, a);
2284054Sbinkertn@umich.edu        return back_cast();
2291904SN/A    }
2302SN/A
2314054Sbinkertn@umich.edu    X &
2323064Sgblack@eecs.umich.edu    assign_(const sc_signed &a)
2332SN/A    {
2342SN/A        assign_v_(*this, a);
2351904SN/A        return back_cast();
2361904SN/A    }
2371904SN/A
2382299SN/A    X &assign_(const sc_uint_base &a) { return assign_((uint64)a); }
2394054Sbinkertn@umich.edu    X &assign_(const sc_int_base &a) { return assign_((int64)a); }
2401904SN/A    X &assign_(unsigned int a);
2411904SN/A    X &assign_(int a);
2421904SN/A    X &assign_(unsigned long a);
2431904SN/A    X &assign_(long a);
2441904SN/A    X &assign_(uint64 a);
2451904SN/A    X &assign_(int64 a);
2461904SN/A
247452SN/A    // bitwise operators and functions
2481904SN/A
2491904SN/A    // bitwise complement
2501904SN/A    X &b_not();
2512SN/A
2522SN/A    const sc_lv_base operator ~ () const;
2531904SN/A
2541904SN/A    // bitwise and
2551904SN/A    X &operator &= (const char *b);
2561904SN/A    X &operator &= (const bool *b);
2571904SN/A    X &operator &= (const sc_logic *b);
2581904SN/A    X &operator &= (const sc_unsigned &b);
2592SN/A    X &operator &= (const sc_signed &b);
2601904SN/A    X &operator &= (const sc_uint_base &b) { return operator &= ((uint64)b); }
2612SN/A    X &operator &= (const sc_int_base &b) { return operator &= ((int64)b); }
2622SN/A    X &operator &= (unsigned long b);
2631904SN/A    X &operator &= (long b);
2642SN/A    X &operator &= (unsigned int b) { return operator &= ((unsigned long)b); }
2654054Sbinkertn@umich.edu    X &operator &= (int b) { return operator &= ((long)b); }
2661904SN/A    X &operator &= (uint64 b);
2671904SN/A    X &operator &= (int64 b);
2681904SN/A
2694054Sbinkertn@umich.edu    const sc_lv_base operator & (const char *b) const;
2701904SN/A    const sc_lv_base operator & (const bool *b) const;
2711904SN/A    const sc_lv_base operator & (const sc_logic *b) const;
2721904SN/A    const sc_lv_base operator & (const sc_unsigned &b) const;
2731904SN/A    const sc_lv_base operator & (const sc_signed &b) const;
2741904SN/A    const sc_lv_base operator & (const sc_uint_base &b) const;
2751904SN/A    const sc_lv_base operator & (const sc_int_base &b) const;
2761904SN/A    const sc_lv_base operator & (unsigned long b) const;
2771904SN/A    const sc_lv_base operator & (long b) const;
2781904SN/A    const sc_lv_base operator & (unsigned int b) const;
2791904SN/A    const sc_lv_base operator & (int b) const;
2801904SN/A    const sc_lv_base operator & (uint64 b) const;
2814054Sbinkertn@umich.edu    const sc_lv_base operator & (int64 b) const;
2821904SN/A
2831904SN/A    // bitwise or
2844054Sbinkertn@umich.edu    X &operator |= (const char *b);
2852525SN/A    X &operator |= (const bool *b);
2861904SN/A    X &operator |= (const sc_logic *b);
2872525SN/A    X &operator |= (const sc_unsigned &b);
2882525SN/A    X &operator |= (const sc_signed &b);
2892525SN/A    X &operator |= (const sc_uint_base &b) { return operator |= ((uint64)b); }
2901904SN/A    X &operator |= (const sc_int_base &b) { return operator |= ((int64)b); }
2911904SN/A    X &operator |= (unsigned long b);
2921904SN/A    X &operator |= (long b);
2934054Sbinkertn@umich.edu    X &operator |= (unsigned int b) { return operator |= ((unsigned long)b); }
2941904SN/A    X &operator |= (int b) { return operator |= ((long)b); }
2951904SN/A    X &operator |= (uint64 b);
2964054Sbinkertn@umich.edu    X &operator |= (int64 b);
2971904SN/A
2981967SN/A    const sc_lv_base operator | (const char *b) const;
2991967SN/A    const sc_lv_base operator | (const bool *b) const;
3001967SN/A    const sc_lv_base operator | (const sc_logic *b) const;
3011967SN/A    const sc_lv_base operator | (const sc_unsigned &b) const;
3021967SN/A    const sc_lv_base operator | (const sc_signed &b) const;
3032SN/A    const sc_lv_base operator | (const sc_uint_base &b) const;
3043817Ssaidi@eecs.umich.edu    const sc_lv_base operator | (const sc_int_base &b) const;
3053506Ssaidi@eecs.umich.edu    const sc_lv_base operator | (unsigned long b) const;
3064054Sbinkertn@umich.edu    const sc_lv_base operator | (long b) const;
3073506Ssaidi@eecs.umich.edu    const sc_lv_base operator | (unsigned int b) const;
3083506Ssaidi@eecs.umich.edu    const sc_lv_base operator | (int b) const;
3093506Ssaidi@eecs.umich.edu    const sc_lv_base operator | (uint64 b) const;
3103814Ssaidi@eecs.umich.edu    const sc_lv_base operator | (int64 b) const;
3113506Ssaidi@eecs.umich.edu
3123931Ssaidi@eecs.umich.edu    // bitwise xor
3133931Ssaidi@eecs.umich.edu    X &operator ^= (const char *b);
3143748Sgblack@eecs.umich.edu    X &operator ^= (const bool *b);
3153748Sgblack@eecs.umich.edu    X &operator ^= (const sc_logic *b);
3163748Sgblack@eecs.umich.edu    X &operator ^= (const sc_unsigned &b);
3173748Sgblack@eecs.umich.edu    X &operator ^= (const sc_signed &b);
3183748Sgblack@eecs.umich.edu    X &operator ^= (const sc_uint_base &b) { return operator ^= ((uint64)b); }
3193748Sgblack@eecs.umich.edu    X &operator ^= (const sc_int_base &b) { return operator ^= ((int64)b); }
3203748Sgblack@eecs.umich.edu    X &operator ^= (unsigned long b);
3213748Sgblack@eecs.umich.edu    X &operator ^= (long b);
3223748Sgblack@eecs.umich.edu    X &operator ^= (unsigned int b) { return operator ^= ((unsigned long)b); }
3233748Sgblack@eecs.umich.edu    X &operator ^= (int b) { return operator ^= ((long)b); }
3244001Ssaidi@eecs.umich.edu    X &operator ^= (uint64 b);
3253748Sgblack@eecs.umich.edu    X &operator ^= (int64 b);
3263748Sgblack@eecs.umich.edu
3273748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const char *b) const;
3283748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const bool *b) const;
3293748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const sc_logic *b) const;
3303748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const sc_unsigned &b) const;
3313748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const sc_signed &b) const;
3323748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const sc_uint_base &b) const;
3333748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (const sc_int_base &b) const;
3343748Sgblack@eecs.umich.edu    const sc_lv_base operator ^ (unsigned long b) const;
3353880Ssaidi@eecs.umich.edu    const sc_lv_base operator ^ (long b) const;
3363603Ssaidi@eecs.umich.edu    const sc_lv_base operator ^ (unsigned int b) const;
3373603Ssaidi@eecs.umich.edu    const sc_lv_base operator ^ (int b) const;
3384054Sbinkertn@umich.edu    const sc_lv_base operator ^ (uint64 b) const;
3394054Sbinkertn@umich.edu    const sc_lv_base operator ^ (int64 b) const;
3404054Sbinkertn@umich.edu
3413903Ssaidi@eecs.umich.edu    // bitwise left shift
3423903Ssaidi@eecs.umich.edu    X &operator <<= (int n);
3433903Ssaidi@eecs.umich.edu    const sc_lv_base operator << (int n) const;
3444046Sbinkertn@umich.edu
3453903Ssaidi@eecs.umich.edu    // bitwise right shift
3463903Ssaidi@eecs.umich.edu    X &operator >>= (int n);
3473903Ssaidi@eecs.umich.edu    const sc_lv_base operator >> (int n) const;
3483903Ssaidi@eecs.umich.edu
3493903Ssaidi@eecs.umich.edu    // bitwise left rotate
3503903Ssaidi@eecs.umich.edu    X &lrotate(int n);
3513903Ssaidi@eecs.umich.edu
3523903Ssaidi@eecs.umich.edu    // bitwise right rotate
3533903Ssaidi@eecs.umich.edu    X &rrotate(int n);
3543903Ssaidi@eecs.umich.edu
3553903Ssaidi@eecs.umich.edu    // bitwise reverse
3563903Ssaidi@eecs.umich.edu    X &reverse();
3573903Ssaidi@eecs.umich.edu
3583903Ssaidi@eecs.umich.edu    // bit selection
3593506Ssaidi@eecs.umich.edu    sc_bitref<X> operator [] (int i) { return sc_bitref<X>(back_cast(), i); }
3603584Ssaidi@eecs.umich.edu    sc_bitref_r<X>
3613584Ssaidi@eecs.umich.edu    operator [] (int i) const
3623584Ssaidi@eecs.umich.edu    {
3633748Sgblack@eecs.umich.edu        return sc_bitref_r<X>(back_cast(), i);
3643928Ssaidi@eecs.umich.edu    }
3653928Ssaidi@eecs.umich.edu    sc_bitref<X> bit(int i) { return sc_bitref<X>(back_cast(), i); }
3663928Ssaidi@eecs.umich.edu    sc_bitref_r<X> bit(int i) const { return sc_bitref_r<X>(back_cast(), i); }
3673748Sgblack@eecs.umich.edu
3683603Ssaidi@eecs.umich.edu    // part selection
3693584Ssaidi@eecs.umich.edu    sc_subref<X>
3703814Ssaidi@eecs.umich.edu    operator () (int hi, int lo)
3713814Ssaidi@eecs.umich.edu    {
3723814Ssaidi@eecs.umich.edu        return sc_subref<X>(back_cast(), hi, lo);
3733814Ssaidi@eecs.umich.edu    }
3743814Ssaidi@eecs.umich.edu    sc_subref_r<X>
3753743Sgblack@eecs.umich.edu    operator () (int hi, int lo) const
3763743Sgblack@eecs.umich.edu    {
3773584Ssaidi@eecs.umich.edu        return sc_subref_r<X>(back_cast(), hi, lo);
3783743Sgblack@eecs.umich.edu    }
3793989Ssaidi@eecs.umich.edu    sc_subref<X>
3803989Ssaidi@eecs.umich.edu    range(int hi, int lo)
3813603Ssaidi@eecs.umich.edu    {
3823931Ssaidi@eecs.umich.edu        return sc_subref<X>(back_cast(), hi, lo);
3833603Ssaidi@eecs.umich.edu    }
3843584Ssaidi@eecs.umich.edu    sc_subref_r<X>
3853931Ssaidi@eecs.umich.edu    range(int hi, int lo) const
3863945Ssaidi@eecs.umich.edu    {
3873931Ssaidi@eecs.umich.edu        return sc_subref_r<X>(back_cast(), hi, lo);
3883931Ssaidi@eecs.umich.edu    }
3893931Ssaidi@eecs.umich.edu
3903931Ssaidi@eecs.umich.edu    // reduce functions
3913748Sgblack@eecs.umich.edu    value_type and_reduce() const;
3923748Sgblack@eecs.umich.edu    value_type
3933748Sgblack@eecs.umich.edu    nand_reduce() const
3943748Sgblack@eecs.umich.edu    {
3953748Sgblack@eecs.umich.edu        return sc_logic::not_table[and_reduce()];
3963815Ssaidi@eecs.umich.edu    }
3973748Sgblack@eecs.umich.edu    value_type or_reduce() const;
3983748Sgblack@eecs.umich.edu    value_type nor_reduce() const { return sc_logic::not_table[or_reduce()]; }
3993815Ssaidi@eecs.umich.edu    value_type xor_reduce() const;
4003748Sgblack@eecs.umich.edu    value_type
4013748Sgblack@eecs.umich.edu    xnor_reduce() const
4023815Ssaidi@eecs.umich.edu    {
4033748Sgblack@eecs.umich.edu        return sc_logic::not_table[xor_reduce()];
4043748Sgblack@eecs.umich.edu    }
4053815Ssaidi@eecs.umich.edu
4063748Sgblack@eecs.umich.edu    // relational operators
4073748Sgblack@eecs.umich.edu    bool operator == (const char *b) const;
4083815Ssaidi@eecs.umich.edu    bool operator == (const bool *b) const;
4093748Sgblack@eecs.umich.edu    bool operator == (const sc_logic *b) const;
4103748Sgblack@eecs.umich.edu    bool operator == (const sc_unsigned &b) const;
4113748Sgblack@eecs.umich.edu    bool operator == (const sc_signed &b) const;
4123584Ssaidi@eecs.umich.edu    bool operator == (const sc_uint_base &b) const;
4133748Sgblack@eecs.umich.edu    bool operator == (const sc_int_base &b) const;
4143748Sgblack@eecs.umich.edu    bool operator == (unsigned long b) const;
4153748Sgblack@eecs.umich.edu    bool operator == (long b) const;
4163748Sgblack@eecs.umich.edu    bool operator == (unsigned int b) const;
4173748Sgblack@eecs.umich.edu    bool operator == (int b) const;
4183748Sgblack@eecs.umich.edu    bool operator == (uint64 b) const;
4193748Sgblack@eecs.umich.edu    bool operator == (int64 b) const;
4203748Sgblack@eecs.umich.edu
4213748Sgblack@eecs.umich.edu    // explicit conversions to character string
4223748Sgblack@eecs.umich.edu    const std::string to_string() const;
4233748Sgblack@eecs.umich.edu    const std::string to_string(sc_numrep) const;
4243748Sgblack@eecs.umich.edu    const std::string to_string(sc_numrep, bool) const;
4253748Sgblack@eecs.umich.edu
4263748Sgblack@eecs.umich.edu    // explicit conversions
4273790Sgblack@eecs.umich.edu    inline int64 to_int64() const { return to_anything_signed(); }
4283790Sgblack@eecs.umich.edu    inline uint64 to_uint64() const;
4293790Sgblack@eecs.umich.edu    int to_int() const { return (int)to_anything_signed(); }
4303748Sgblack@eecs.umich.edu
4314011Ssaidi@eecs.umich.edu    unsigned int
4324001Ssaidi@eecs.umich.edu    to_uint() const
4334011Ssaidi@eecs.umich.edu    {
4344011Ssaidi@eecs.umich.edu        return (unsigned int)to_anything_unsigned();
4354011Ssaidi@eecs.umich.edu    }
4364011Ssaidi@eecs.umich.edu
4374011Ssaidi@eecs.umich.edu    long to_long() const { return (long)to_anything_signed(); }
4384011Ssaidi@eecs.umich.edu
4393790Sgblack@eecs.umich.edu    unsigned long
4403790Sgblack@eecs.umich.edu    to_ulong() const
4413790Sgblack@eecs.umich.edu    {
4423748Sgblack@eecs.umich.edu        return (unsigned long)to_anything_unsigned();
4433748Sgblack@eecs.umich.edu    }
4443748Sgblack@eecs.umich.edu
4453748Sgblack@eecs.umich.edu    // other methods
4463748Sgblack@eecs.umich.edu    void
4473748Sgblack@eecs.umich.edu    print(::std::ostream &os=::std::cout) const
4483748Sgblack@eecs.umich.edu    {
4493748Sgblack@eecs.umich.edu        // The test below will force printing in binary if decimal is
4503748Sgblack@eecs.umich.edu        // specified.
4513790Sgblack@eecs.umich.edu        if (sc_io_base(os, SC_DEC) == SC_DEC)
4523790Sgblack@eecs.umich.edu            os << to_string();
4533790Sgblack@eecs.umich.edu        else
4543748Sgblack@eecs.umich.edu            os << to_string(sc_io_base(os, SC_BIN), sc_io_show_base(os));
4553790Sgblack@eecs.umich.edu    }
4563790Sgblack@eecs.umich.edu
4573748Sgblack@eecs.umich.edu    void scan(::std::istream &is=::std::cin);
4583989Ssaidi@eecs.umich.edu
4593748Sgblack@eecs.umich.edu  protected:
4603790Sgblack@eecs.umich.edu    void check_bounds(int n) const; // check if bit n accessible
4613790Sgblack@eecs.umich.edu    void check_wbounds(int n) const; // check if word n accessible
4623989Ssaidi@eecs.umich.edu
4633748Sgblack@eecs.umich.edu    sc_digit to_anything_unsigned() const;
4643790Sgblack@eecs.umich.edu    int64 to_anything_signed() const;
4653790Sgblack@eecs.umich.edu};
4663989Ssaidi@eecs.umich.edu
4673748Sgblack@eecs.umich.edu
4683748Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
4693880Ssaidi@eecs.umich.edu
4703880Ssaidi@eecs.umich.edu// bitwise operators and functions
4713880Ssaidi@eecs.umich.edu
4723880Ssaidi@eecs.umich.edu// bitwise and
4733880Ssaidi@eecs.umich.edu
4743880Ssaidi@eecs.umich.edutemplate <class X, class Y>
4753880Ssaidi@eecs.umich.eduinline X &operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py);
4764008Ssaidi@eecs.umich.edu
4773931Ssaidi@eecs.umich.edu
4783931Ssaidi@eecs.umich.edutemplate <class X, class Y>
4794001Ssaidi@eecs.umich.eduinline const sc_lv_base operator & (
4804001Ssaidi@eecs.umich.edu        const sc_proxy<X> &px, const sc_proxy<Y> &py);
4813931Ssaidi@eecs.umich.edu
4824008Ssaidi@eecs.umich.edu
4833863Ssaidi@eecs.umich.edu#define DECL_BITWISE_AND_OP_T(tp) \
4843584Ssaidi@eecs.umich.edutemplate <class X> \
4853584Ssaidi@eecs.umich.eduinline const sc_lv_base operator & (tp b, const sc_proxy<X> &px);
4863584Ssaidi@eecs.umich.edu
4873814Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const char *)
4883814Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const bool *)
4893584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_logic *)
4903584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_unsigned &)
4913931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_signed &)
4923584Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_uint_base &)
4933931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(const sc_int_base &)
4943931Ssaidi@eecs.umich.eduDECL_BITWISE_AND_OP_T(unsigned long)
4953748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(long)
4963748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(unsigned int)
4973748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(int)
4983748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(uint64)
4993748Sgblack@eecs.umich.eduDECL_BITWISE_AND_OP_T(int64)
5003748Sgblack@eecs.umich.edu
5013748Sgblack@eecs.umich.edu#undef DECL_BITWISE_AND_OP_T
5023748Sgblack@eecs.umich.edu
5033748Sgblack@eecs.umich.edu// bitwise or
5043748Sgblack@eecs.umich.edutemplate <class X, class Y>
5053748Sgblack@eecs.umich.eduinline X &operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py);
5063748Sgblack@eecs.umich.edu
5073748Sgblack@eecs.umich.edutemplate <class X, class Y>
5083748Sgblack@eecs.umich.eduinline const sc_lv_base operator | (
5093748Sgblack@eecs.umich.edu        const sc_proxy<X> &px, const sc_proxy<Y> &py);
5103748Sgblack@eecs.umich.edu
5113748Sgblack@eecs.umich.edu
5123748Sgblack@eecs.umich.edu#define DECL_BITWISE_OR_OP_T(tp) \
5134001Ssaidi@eecs.umich.edutemplate <class X> \
5144001Ssaidi@eecs.umich.eduinline const sc_lv_base operator | (tp a, const sc_proxy<X> &px);
5153748Sgblack@eecs.umich.edu
5163748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const char *)
5173748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const bool *)
5183748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_logic *)
5193748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_unsigned &)
5203748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_signed &)
5213748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_uint_base &)
5223748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(const sc_int_base &)
5233748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(unsigned long)
5243748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(long)
5253748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(unsigned int)
5263748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(int)
5273748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(uint64)
5283748Sgblack@eecs.umich.eduDECL_BITWISE_OR_OP_T(int64)
5293748Sgblack@eecs.umich.edu
5303748Sgblack@eecs.umich.edu#undef DECL_BITWISE_OR_OP_T
5313748Sgblack@eecs.umich.edu
5323748Sgblack@eecs.umich.edu// bitwise xor
5333748Sgblack@eecs.umich.edutemplate <class X, class Y>
5343748Sgblack@eecs.umich.eduinline X &operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py);
5353880Ssaidi@eecs.umich.edu
5363880Ssaidi@eecs.umich.edutemplate <class X, class Y>
5373603Ssaidi@eecs.umich.eduinline const sc_lv_base operator ^ (
5383584Ssaidi@eecs.umich.edu        const sc_proxy<X> &px, const sc_proxy<Y> &py);
5393603Ssaidi@eecs.umich.edu
5403584Ssaidi@eecs.umich.edu#define DECL_BITWISE_XOR_OP_T(tp) \
5413603Ssaidi@eecs.umich.edutemplate <class X> \
5423584Ssaidi@eecs.umich.eduinline const sc_lv_base operator ^ (tp a, const sc_proxy<X> &px);
5433584Ssaidi@eecs.umich.edu
5443603Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const char *)
5453584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const bool *)
5463814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_logic *)
5473814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_unsigned &)
5483814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_signed &)
5493814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_uint_base &)
5503814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(const sc_int_base &)
5513814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(unsigned long)
5523814Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(long)
5533584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(unsigned int)
5543584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(int)
5553584Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(uint64)
5563603Ssaidi@eecs.umich.eduDECL_BITWISE_XOR_OP_T(int64)
5573584Ssaidi@eecs.umich.edu
5583584Ssaidi@eecs.umich.edu#undef DECL_BITWISE_XOR_OP_T
5593748Sgblack@eecs.umich.edu
5603748Sgblack@eecs.umich.edu// relational operators
5613748Sgblack@eecs.umich.edutemplate <class X, class Y>
5623584Ssaidi@eecs.umich.eduinline bool operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py);
5633584Ssaidi@eecs.umich.edu
5643584Ssaidi@eecs.umich.edutemplate <class X, class Y>
5653584Ssaidi@eecs.umich.eduinline bool operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py);
5663603Ssaidi@eecs.umich.edu
5673748Sgblack@eecs.umich.edu#define DECL_REL_OP_T(tp) \
5683584Ssaidi@eecs.umich.edutemplate <class X> \
5693748Sgblack@eecs.umich.eduinline bool operator == (tp b, const sc_proxy<X> &px); \
5703748Sgblack@eecs.umich.edu \
5713748Sgblack@eecs.umich.edutemplate <class X> \
5723748Sgblack@eecs.umich.eduinline bool operator != (const sc_proxy<X> &px, tp b); \
5733748Sgblack@eecs.umich.edu \
5743748Sgblack@eecs.umich.edutemplate <class X> \
5753748Sgblack@eecs.umich.eduinline bool operator != (tp b, const sc_proxy<X> &px);
5763748Sgblack@eecs.umich.edu
5773748Sgblack@eecs.umich.eduDECL_REL_OP_T(const char *)
5783748Sgblack@eecs.umich.eduDECL_REL_OP_T(const bool *)
5793748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_logic *)
5803748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_unsigned &)
5813790Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_signed &)
5823989Ssaidi@eecs.umich.eduDECL_REL_OP_T(const sc_uint_base &)
5833748Sgblack@eecs.umich.eduDECL_REL_OP_T(const sc_int_base &)
5844001Ssaidi@eecs.umich.eduDECL_REL_OP_T(unsigned long)
5854001Ssaidi@eecs.umich.eduDECL_REL_OP_T(long)
5864001Ssaidi@eecs.umich.eduDECL_REL_OP_T(unsigned int)
5873748Sgblack@eecs.umich.eduDECL_REL_OP_T(int)
5883790Sgblack@eecs.umich.eduDECL_REL_OP_T(uint64)
5893989Ssaidi@eecs.umich.eduDECL_REL_OP_T(int64)
5903748Sgblack@eecs.umich.edu
5913748Sgblack@eecs.umich.edu#undef DECL_REL_OP_T
5923748Sgblack@eecs.umich.edu
5933748Sgblack@eecs.umich.edu// l-value concatenation
5943748Sgblack@eecs.umich.edu
5953748Sgblack@eecs.umich.edu// Due to the fact that temporary objects cannot be passed to non-const
5963748Sgblack@eecs.umich.edu// references, we have to enumerate, use call by value, and use dynamic
5973748Sgblack@eecs.umich.edu// memory allocation (and deallocation).
5983748Sgblack@eecs.umich.edu
5993748Sgblack@eecs.umich.edu
6003748Sgblack@eecs.umich.edu// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
6013748Sgblack@eecs.umich.edu
6023748Sgblack@eecs.umich.edutemplate <class X>
6033748Sgblack@eecs.umich.eduinline void
6043748Sgblack@eecs.umich.eduget_words_(const X &x, int wi, sc_digit &x_dw, sc_digit &x_cw)
6053748Sgblack@eecs.umich.edu{
6063748Sgblack@eecs.umich.edu    x_dw = x.get_word(wi);
6073790Sgblack@eecs.umich.edu    x_cw = x.get_cword(wi);
6083790Sgblack@eecs.umich.edu}
6093748Sgblack@eecs.umich.edu
6103748Sgblack@eecs.umich.edutemplate <class X>
6113790Sgblack@eecs.umich.eduinline void
6123790Sgblack@eecs.umich.eduset_words_(X &x, int wi, sc_digit x_dw, sc_digit x_cw)
6133748Sgblack@eecs.umich.edu{
6143748Sgblack@eecs.umich.edu    x.set_word(wi, x_dw);
6153790Sgblack@eecs.umich.edu    x.set_cword(wi, x_cw);
6163989Ssaidi@eecs.umich.edu}
6173748Sgblack@eecs.umich.edu
6183748Sgblack@eecs.umich.edutemplate <class X>
6193790Sgblack@eecs.umich.eduinline void
6203989Ssaidi@eecs.umich.eduextend_sign_w_(X &x, int wi, bool sign)
6213748Sgblack@eecs.umich.edu{
6223748Sgblack@eecs.umich.edu    int sz = x.size();
6233748Sgblack@eecs.umich.edu    unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO);
6243748Sgblack@eecs.umich.edu    for (int i = wi; i < sz; ++i) {
6253748Sgblack@eecs.umich.edu        set_words_(x, i, sgn, SC_DIGIT_ZERO);
6263748Sgblack@eecs.umich.edu    }
6273748Sgblack@eecs.umich.edu}
6283748Sgblack@eecs.umich.edu
6293815Ssaidi@eecs.umich.edu// assignment functions
6303748Sgblack@eecs.umich.edutemplate <class X, class Y>
6313748Sgblack@eecs.umich.eduinline void
6323815Ssaidi@eecs.umich.eduassign_p_(sc_proxy<X> &px, const sc_proxy<Y> &py)
6333748Sgblack@eecs.umich.edu{
6343748Sgblack@eecs.umich.edu    if ((void *)&px != (void *)&py) {
6353815Ssaidi@eecs.umich.edu        X &x = px.back_cast();
6363748Sgblack@eecs.umich.edu        const Y &y = py.back_cast();
6373748Sgblack@eecs.umich.edu        int sz = x.size();
6383815Ssaidi@eecs.umich.edu        int min_sz = sc_min(sz, y.size());
6393748Sgblack@eecs.umich.edu        int i = 0;
6403748Sgblack@eecs.umich.edu        for (; i < min_sz; ++i) {
6413815Ssaidi@eecs.umich.edu            set_words_(x, i, y.get_word(i), y.get_cword(i));
6423748Sgblack@eecs.umich.edu        }
6433748Sgblack@eecs.umich.edu        // extend with zeros
6443584Ssaidi@eecs.umich.edu        extend_sign_w_(x, i, false);
6453584Ssaidi@eecs.umich.edu        x.clean_tail();
6463748Sgblack@eecs.umich.edu    }
6473584Ssaidi@eecs.umich.edu}
6483931Ssaidi@eecs.umich.edu
6493931Ssaidi@eecs.umich.edu// Vector types that are not derived from sc_proxy, sc_int_base,
6503748Sgblack@eecs.umich.edu// sc_uint_base, sc_signed, or sc_unsigned, must have a length()
6513748Sgblack@eecs.umich.edu// function and an operator []. The vector argument type must support
6523748Sgblack@eecs.umich.edu// accessing bits that are beyond the msb. The vector argument type
6533748Sgblack@eecs.umich.edu// decides what to do there (e.g. sign extension or zero padding).
6543748Sgblack@eecs.umich.edu
6553931Ssaidi@eecs.umich.edutemplate <class X, class T>
6563931Ssaidi@eecs.umich.eduinline void
6573931Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const T &a)
6583931Ssaidi@eecs.umich.edu{
6593931Ssaidi@eecs.umich.edu    X &x = px.back_cast();
6603931Ssaidi@eecs.umich.edu    int i;
6613931Ssaidi@eecs.umich.edu    int len_x = x.length();
6624008Ssaidi@eecs.umich.edu    int len_a = a.length();
6633931Ssaidi@eecs.umich.edu    if (len_a > len_x)
6643584Ssaidi@eecs.umich.edu        len_a = len_x;
6653584Ssaidi@eecs.umich.edu    for (i = 0; i < len_a; ++i) {
6663903Ssaidi@eecs.umich.edu        x.set_bit(i, sc_logic_value_t((bool)a[i]));
6673903Ssaidi@eecs.umich.edu    }
6683903Ssaidi@eecs.umich.edu    for (; i < len_x; ++i) {
6693903Ssaidi@eecs.umich.edu        x.set_bit(i, sc_logic_value_t(false));
6703903Ssaidi@eecs.umich.edu    }
6713903Ssaidi@eecs.umich.edu}
6723903Ssaidi@eecs.umich.edu
6733903Ssaidi@eecs.umich.edutemplate <class X>
6743903Ssaidi@eecs.umich.eduinline void
6753903Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const sc_int_base &a)
6763880Ssaidi@eecs.umich.edu{
6773903Ssaidi@eecs.umich.edu    X &x = px.back_cast();
6783903Ssaidi@eecs.umich.edu    int i;
6793903Ssaidi@eecs.umich.edu    bool sign = a < 0;
6803903Ssaidi@eecs.umich.edu    int len_x = x.length();
6813903Ssaidi@eecs.umich.edu    int len_a = a.length();
6823903Ssaidi@eecs.umich.edu    if ( len_a > len_x ) len_a = len_x;
6833903Ssaidi@eecs.umich.edu    for (i = 0; i < len_a; ++i) {
6843903Ssaidi@eecs.umich.edu        x.set_bit(i, sc_logic_value_t((bool)a[i]));
6853903Ssaidi@eecs.umich.edu    }
6863903Ssaidi@eecs.umich.edu    for (; i < len_x; ++i) {
6873880Ssaidi@eecs.umich.edu        x.set_bit(i, sc_logic_value_t(sign));
6883826Ssaidi@eecs.umich.edu    }
6893825Ssaidi@eecs.umich.edu}
6904011Ssaidi@eecs.umich.edu
6913825Ssaidi@eecs.umich.edutemplate <class X>
6923892Ssaidi@eecs.umich.eduinline void
6933892Ssaidi@eecs.umich.eduassign_v_(sc_proxy<X> &px, const sc_signed &a)
6943584Ssaidi@eecs.umich.edu{
6953584Ssaidi@eecs.umich.edu    X &x = px.back_cast();
6963584Ssaidi@eecs.umich.edu    int i;
6973506Ssaidi@eecs.umich.edu    bool sign = a < 0;
6983584Ssaidi@eecs.umich.edu    int len_x = x.length();
6993584Ssaidi@eecs.umich.edu    int len_a = a.length();
7003506Ssaidi@eecs.umich.edu    if (len_a > len_x)
7013584Ssaidi@eecs.umich.edu        len_a = len_x;
7022SN/A    for (i = 0; i < len_a; ++i) {
7032SN/A        x.set_bit(i, sc_logic_value_t((bool)a[i]));
7044054Sbinkertn@umich.edu    }
705    for (; i < len_x; ++i) {
706        x.set_bit(i, sc_logic_value_t(sign));
707    }
708}
709
710template <class X>
711inline void
712assign_v_(sc_proxy<X> &px, const sc_uint_base &a)
713{
714    X &x = px.back_cast();
715    int i;
716    int len_x = x.length();
717    int len_a = a.length();
718    if (len_a > len_x)
719        len_a = len_x;
720    for (i = 0; i < len_a; ++i) {
721        x.set_bit(i, sc_logic_value_t((bool)a[i]));
722    }
723    for (; i < len_x; ++i) {
724        x.set_bit(i, sc_logic_value_t(false));
725    }
726}
727
728template <class X>
729inline void
730assign_v_(sc_proxy<X> &px, const sc_unsigned &a)
731{
732    X &x = px.back_cast();
733    int i;
734    int len_x = x.length();
735    int len_a = a.length();
736    if (len_a > len_x)
737        len_a = len_x;
738    for (i = 0; i < len_a; ++i) {
739        x.set_bit(i, sc_logic_value_t((bool)a[i]));
740    }
741    for (; i < len_x; ++i) {
742        x.set_bit(i, sc_logic_value_t(false));
743    }
744}
745
746// assignment operators
747template <class X>
748inline X &
749sc_proxy<X>::assign_(const char *a)
750{
751    X &x = back_cast();
752    std::string s = convert_to_bin(a);
753    int len = x.length();
754    int s_len = s.length() - 1;
755    int min_len = sc_min(len, s_len);
756    int i = 0;
757    for (; i < min_len; ++i) {
758        char c = s[s_len - i - 1];
759        x.set_bit(i, sc_logic::char_to_logic[(int)c]);
760    }
761    // if formatted, fill the rest with sign(s), otherwise fill with zeros
762    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t(s[0] - '0')
763                                             : sc_logic_value_t(0));
764    for (; i < len; ++i) {
765        x.set_bit(i, fill);
766    }
767    return x;
768}
769
770template <class X>
771inline X &
772sc_proxy<X>::assign_(const bool *a)
773{
774    // the length of 'a' must be larger than or equal to the length of 'this'
775    X &x = back_cast();
776    int len = x.length();
777    for (int i = 0; i < len; ++i) {
778        x.set_bit(i, sc_logic_value_t(a[i]));
779    }
780    return x;
781}
782
783template <class X>
784inline X &
785sc_proxy<X>::assign_(const sc_logic *a)
786{
787    // the length of 'a' must be larger than or equal to the length of 'this'
788    X &x = back_cast();
789    int len = x.length();
790    for (int i = 0; i < len; ++i) {
791        x.set_bit(i, a[i].value());
792    }
793    return x;
794}
795
796template <class X>
797inline X &
798sc_proxy<X>::assign_(unsigned int a)
799{
800    X &x = back_cast();
801    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
802    // extend with zeros
803    extend_sign_w_(x, 1, false);
804    x.clean_tail();
805    return x;
806}
807
808template <class X>
809inline X &
810sc_proxy<X>::assign_(int a)
811{
812    X &x = back_cast();
813    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
814    // extend with sign(a)
815    extend_sign_w_(x, 1, (a < 0));
816    x.clean_tail();
817    return x;
818}
819
820#if SC_LONG_64
821template <class X>
822inline X &
823sc_proxy<X>::assign_(unsigned long a)
824{
825    X &x = back_cast();
826    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
827    if (x.size() > 1) {
828        set_words_(x, 1, ((sc_digit)(a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
829                   SC_DIGIT_ZERO);
830        // extend with zeros
831        extend_sign_w_(x, 2, false);
832    }
833    x.clean_tail();
834    return x;
835}
836
837template <class X>
838inline X &
839sc_proxy<X>::assign_(long a)
840{
841    X &x = back_cast();
842    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
843    if (x.size() > 1) {
844        set_words_(x, 1,
845                   ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
846                   SC_DIGIT_ZERO);
847        // extend with sign(a)
848        extend_sign_w_(x, 2, (a < 0));
849    }
850    x.clean_tail();
851    return x;
852}
853
854#else
855
856template <class X>
857inline X &
858sc_proxy<X>::assign_(unsigned long a)
859{
860    X &x = back_cast();
861    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
862    // extend with zeros
863    extend_sign_w_(x, 1, false);
864    x.clean_tail();
865    return x;
866}
867
868template <class X>
869inline X &
870sc_proxy<X>::assign_(long a)
871{
872    X &x = back_cast();
873    set_words_(x, 0, (sc_digit)a, SC_DIGIT_ZERO);
874    // extend with sign(a)
875    extend_sign_w_(x, 1, (a < 0));
876    x.clean_tail();
877    return x;
878}
879
880#endif
881
882template <class X>
883inline X &
884sc_proxy<X>::assign_(uint64 a)
885{
886    X &x = back_cast();
887    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
888    if (x.size() > 1) {
889        set_words_(x, 1, ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
890                   SC_DIGIT_ZERO );
891        // extend with zeros
892        extend_sign_w_(x, 2, false);
893    }
894    x.clean_tail();
895    return x;
896}
897
898template <class X>
899inline X &
900sc_proxy<X>::assign_(int64 a)
901{
902    X &x = back_cast();
903    set_words_(x, 0, ((sc_digit)a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO);
904    if (x.size() > 1) {
905        set_words_(x, 1,
906                   ((sc_digit)((uint64)a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
907                   SC_DIGIT_ZERO );
908        // extend with sign(a)
909        extend_sign_w_(x, 2, (a < 0));
910    }
911    x.clean_tail();
912    return x;
913}
914
915// bitwise operators and functions
916
917// bitwise complement
918template <class X>
919inline X &
920sc_proxy<X>::b_not()
921{
922    X &x = back_cast();
923    int sz = x.size();
924    for (int i = 0; i < sz; ++i) {
925        sc_digit x_dw, x_cw;
926        get_words_(x, i, x_dw, x_cw);
927        x.set_word(i, x_cw | ~x_dw);
928    }
929    x.clean_tail();
930    return x;
931}
932
933// bitwise and
934template <class X, class Y>
935inline X &
936b_and_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py)
937{
938    X &x = px.back_cast();
939    const Y &y = py.back_cast();
940    sc_assert(x.length() == y.length());
941    int sz = x.size();
942    for (int i = 0; i < sz; ++i) {
943        sc_digit x_dw, x_cw, y_dw, y_cw;
944        get_words_(x, i, x_dw, x_cw);
945        get_words_(y, i, y_dw, y_cw);
946        sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw);
947        sc_digit dw = cw | (x_dw & y_dw);
948        set_words_(x, i, dw, cw);
949    }
950    // tail cleaning not needed
951    return x;
952}
953
954// bitwise or
955template <class X, class Y>
956inline X &
957b_or_assign_(sc_proxy<X> &px, const sc_proxy<Y> &py)
958{
959    X &x = px.back_cast();
960    const Y &y = py.back_cast();
961    sc_assert(x.length() == y.length());
962    int sz = x.size();
963    for (int i = 0; i < sz; ++i) {
964        sc_digit x_dw, x_cw, y_dw, y_cw;
965        get_words_(x, i, x_dw, x_cw);
966        get_words_(y, i, y_dw, y_cw);
967        sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw);
968        sc_digit dw = cw | x_dw | y_dw;
969        set_words_(x, i, dw, cw);
970    }
971    // tail cleaning not needed
972    return x;
973}
974
975// bitwise xor
976template <class X, class Y>
977inline X &
978b_xor_assign_(sc_proxy<X> &a, const sc_proxy<Y> &b)
979{
980    X &x = a.back_cast();
981    const Y &y = b.back_cast();
982    sc_assert(x.length() == y.length());
983    int sz = x.size();
984    for (int i = 0; i < sz; ++i) {
985        sc_digit x_dw, x_cw, y_dw, y_cw;
986        get_words_(x, i, x_dw, x_cw);
987        get_words_(y, i, y_dw, y_cw);
988        sc_digit cw = x_cw | y_cw;
989        sc_digit dw = cw | (x_dw ^ y_dw);
990        set_words_( x, i, dw, cw );
991    }
992    // tail cleaning not needed
993    return x;
994}
995
996// bitwise left shift
997template <class X>
998inline X &
999sc_proxy<X>::operator <<= (int n)
1000{
1001    X &x = back_cast();
1002    if (n < 0) {
1003        sc_proxy_out_of_bounds("left shift operation is only allowed with "
1004                               "positive shift values, shift value = ", n);
1005        return x;
1006    }
1007    if (n >= x.length()) {
1008        extend_sign_w_(x, 0, false);
1009        // no tail cleaning needed
1010        return x;
1011    }
1012    int sz = x.size();
1013    int wn = n / SC_DIGIT_SIZE;
1014    int bn = n % SC_DIGIT_SIZE;
1015    if (wn != 0) {
1016        // shift words
1017        int i = sz - 1;
1018        for (; i >= wn; --i) {
1019            set_words_(x, i, x.get_word(i - wn), x.get_cword(i - wn));
1020        }
1021        for (; i >= 0; --i) {
1022            set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO);
1023        }
1024    }
1025    if (bn != 0) {
1026        // shift bits
1027        for (int i = sz - 1; i >= 1; --i) {
1028            sc_digit x_dw, x_cw;
1029            get_words_(x, i, x_dw, x_cw);
1030            x_dw <<= bn;
1031            x_dw |= x.get_word(i - 1) >> (SC_DIGIT_SIZE - bn);
1032            x_cw <<= bn;
1033            x_cw |= x.get_cword(i - 1) >> (SC_DIGIT_SIZE - bn);
1034            set_words_(x, i, x_dw, x_cw);
1035        }
1036        sc_digit x_dw, x_cw;
1037        get_words_(x, 0, x_dw, x_cw);
1038        x_dw <<= bn;
1039        x_cw <<= bn;
1040        set_words_(x, 0, x_dw, x_cw);
1041    }
1042    x.clean_tail();
1043    return x;
1044}
1045
1046// bitwise right shift
1047template <class X>
1048inline X &
1049sc_proxy<X>::operator >>= (int n)
1050{
1051    X &x = back_cast();
1052    if (n < 0) {
1053        sc_proxy_out_of_bounds("right shift operation is only allowed with "
1054                               "positive shift values, shift value = ", n);
1055        return x;
1056    }
1057    if (n >= x.length()) {
1058        extend_sign_w_(x, 0, false);
1059        // no tail cleaning needed
1060        return x;
1061    }
1062    int sz = x.size();
1063    int wn = n / SC_DIGIT_SIZE;
1064    int bn = n % SC_DIGIT_SIZE;
1065    if (wn != 0) {
1066        // shift words
1067        int i = 0;
1068        for (; i < (sz - wn); ++i) {
1069            set_words_(x, i, x.get_word(i + wn), x.get_cword(i + wn));
1070        }
1071        for (; i < sz; ++i) {
1072            set_words_(x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO);
1073        }
1074    }
1075    if (bn != 0) {
1076        // shift bits
1077        for (int i = 0; i < (sz - 1); ++i) {
1078            sc_digit x_dw, x_cw;
1079            get_words_(x, i, x_dw, x_cw);
1080            x_dw >>= bn;
1081            x_dw |= x.get_word(i + 1) << (SC_DIGIT_SIZE - bn);
1082            x_cw >>= bn;
1083            x_cw |= x.get_cword(i + 1) << (SC_DIGIT_SIZE - bn);
1084            set_words_(x, i, x_dw, x_cw);
1085        }
1086        sc_digit x_dw, x_cw;
1087        get_words_(x, sz - 1, x_dw, x_cw);
1088        x_dw >>= bn;
1089        x_cw >>= bn;
1090        set_words_(x, sz - 1, x_dw, x_cw);
1091    }
1092    x.clean_tail();
1093    return x;
1094}
1095
1096// bitwise left rotate
1097template <class X>
1098inline const sc_lv_base lrotate(const sc_proxy<X> &x, int n);
1099
1100// bitwise right rotate
1101template <class X>
1102inline const sc_lv_base rrotate(const sc_proxy<X>& x, int n);
1103
1104// bitwise reverse
1105template <class X>
1106inline X &
1107sc_proxy<X>::reverse()
1108{
1109    X &x = back_cast();
1110    int len = x.length();
1111    int half_len = len / 2;
1112    for (int i = 0, j = len - 1; i < half_len; ++ i, --j) {
1113        value_type t = x.get_bit(i);
1114        x.set_bit(i, x.get_bit(j));
1115        x.set_bit(j, t);
1116    }
1117    return x;
1118}
1119
1120template <class X>
1121inline const sc_lv_base reverse(const sc_proxy<X> &a);
1122
1123// reduce functions
1124template <class X>
1125inline typename sc_proxy<X>::value_type
1126sc_proxy<X>::and_reduce() const
1127{
1128    const X &x = back_cast();
1129    value_type result = value_type(1);
1130    int len = x.length();
1131    for (int i = 0; i < len; ++i) {
1132        result = sc_logic::and_table[result][x.get_bit(i)];
1133    }
1134    return result;
1135}
1136
1137template <class X>
1138inline typename sc_proxy<X>::value_type
1139sc_proxy<X>::or_reduce() const
1140{
1141    const X &x = back_cast();
1142    value_type result = value_type(0);
1143    int len = x.length();
1144    for (int i = 0; i < len; ++i) {
1145        result = sc_logic::or_table[result][x.get_bit(i)];
1146    }
1147    return result;
1148}
1149
1150template <class X>
1151inline typename sc_proxy<X>::value_type
1152sc_proxy<X>::xor_reduce() const
1153{
1154    const X &x = back_cast();
1155    value_type result = value_type(0);
1156    int len = x.length();
1157    for (int i = 0; i < len; ++i) {
1158        result = sc_logic::xor_table[result][x.get_bit(i)];
1159    }
1160    return result;
1161}
1162
1163// relational operators
1164template <class X, class Y>
1165inline bool
1166operator != (const sc_proxy<X> &px, const sc_proxy<Y> &py)
1167{
1168    return !(px == py);
1169}
1170
1171
1172#define DEFN_REL_OP_T(tp) \
1173template <class X> \
1174inline bool operator == (tp b, const sc_proxy<X> &px) { return (px == b); } \
1175 \
1176template <class X> \
1177inline bool operator != (const sc_proxy<X> &px, tp b) { return !(px == b); } \
1178 \
1179template <class X> \
1180inline bool operator != (tp b, const sc_proxy<X> &px) { return !(px == b); }
1181
1182DEFN_REL_OP_T(const char *)
1183DEFN_REL_OP_T(const bool *)
1184DEFN_REL_OP_T(const sc_logic *)
1185DEFN_REL_OP_T(const sc_unsigned &)
1186DEFN_REL_OP_T(const sc_signed &)
1187DEFN_REL_OP_T(const sc_uint_base &)
1188DEFN_REL_OP_T(const sc_int_base &)
1189DEFN_REL_OP_T(unsigned long)
1190DEFN_REL_OP_T(long)
1191DEFN_REL_OP_T(unsigned int)
1192DEFN_REL_OP_T(int)
1193DEFN_REL_OP_T(uint64)
1194DEFN_REL_OP_T(int64)
1195
1196#undef DEFN_REL_OP_T
1197
1198// explicit conversions to character string
1199template <class X>
1200inline const std::string
1201sc_proxy<X>::to_string() const
1202{
1203    const X &x = back_cast();
1204    int len = x.length();
1205    std::string s; // (len + 1);
1206    for (int i = 0; i < len; ++i) {
1207        s += sc_logic::logic_to_char[x.get_bit(len - i - 1)];
1208    }
1209    return s;
1210}
1211
1212template <class X>
1213inline const std::string
1214sc_proxy<X>::to_string(sc_numrep numrep) const
1215{
1216    return convert_to_fmt(to_string(), numrep, true);
1217}
1218
1219template <class X>
1220inline const std::string
1221sc_proxy<X>::to_string(sc_numrep numrep, bool w_prefix) const
1222{
1223    return convert_to_fmt(to_string(), numrep, w_prefix);
1224}
1225
1226// other methods
1227template <class X>
1228inline void
1229sc_proxy<X>::scan(::std::istream &is)
1230{
1231    std::string s;
1232    is >> s;
1233    back_cast() = s.c_str();
1234}
1235
1236template <class X>
1237inline void
1238sc_proxy<X>::check_bounds(int n) const // check if bit n accessible
1239{
1240    if (n < 0 || n >= back_cast().length()) {
1241        sc_proxy_out_of_bounds(NULL, n);
1242        sc_core::sc_abort(); // can't recover from here
1243    }
1244}
1245
1246template <class X>
1247inline void
1248sc_proxy<X>::check_wbounds(int n) const // check if word n accessible
1249{
1250    if (n < 0 || n >= back_cast().size()) {
1251        sc_proxy_out_of_bounds(NULL, n);
1252        sc_core::sc_abort(); // can't recover from here
1253    }
1254}
1255
1256template <class X>
1257inline sc_digit
1258sc_proxy<X>::to_anything_unsigned() const
1259{
1260    // only 0 word is returned
1261    // can't convert logic values other than 0 and 1
1262    const X &x = back_cast();
1263    int len = x.length();
1264    if (x.get_cword(0) != SC_DIGIT_ZERO) {
1265        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
1266    }
1267    sc_digit w = x.get_word(0);
1268    if (len >= SC_DIGIT_SIZE) {
1269        return w;
1270    }
1271    return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)));
1272}
1273
1274template <class X>
1275inline uint64
1276sc_proxy<X>::to_uint64() const
1277{
1278    // words 1 and 0 returned.
1279    // can't convert logic values other than 0 and 1
1280    const X &x = back_cast();
1281    int len = x.length();
1282    if (x.get_cword(0) != SC_DIGIT_ZERO) {
1283        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
1284    }
1285    uint64 w = x.get_word(0);
1286    if (len > SC_DIGIT_SIZE) {
1287        if (x.get_cword(1) != SC_DIGIT_ZERO) {
1288            SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
1289        }
1290        uint64 w1 = x.get_word(1);
1291        w = w | (w1 << SC_DIGIT_SIZE);
1292        return w;
1293    } else if (len == SC_DIGIT_SIZE) {
1294        return w;
1295    } else {
1296        return (w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)));
1297    }
1298}
1299
1300template <class X>
1301inline int64
1302sc_proxy<X>::to_anything_signed() const
1303{
1304    const X &x = back_cast();
1305    int len = x.length();
1306    int64 w = 0;
1307
1308    if (len > SC_DIGIT_SIZE) {
1309        if (x.get_cword(1) != SC_DIGIT_ZERO)
1310            SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
1311        w = x.get_word(1);
1312    }
1313    if (x.get_cword(0) != SC_DIGIT_ZERO)
1314        SC_REPORT_WARNING(sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0);
1315    w = (w << SC_DIGIT_SIZE) | x.get_word(0);
1316    if (len >= 64) {
1317        return w;
1318    }
1319
1320    uint64 zero = 0;
1321    value_type sgn = x.get_bit(len - 1);
1322    if (sgn == 0) {
1323        return (int64)(w & (~zero >> (64 - len)));
1324    } else {
1325        return (int64)(w | (~zero << len));
1326    }
1327}
1328
1329
1330// ----------------------------------------------------------------------------
1331
1332// functional notation for the reduce methods
1333template <class X>
1334inline typename sc_proxy<X>::value_type
1335and_reduce(const sc_proxy<X> &a)
1336{
1337    return a.and_reduce();
1338}
1339
1340template <class X>
1341inline typename sc_proxy<X>::value_type
1342nand_reduce(const sc_proxy<X> &a)
1343{
1344    return a.nand_reduce();
1345}
1346
1347template <class X>
1348inline typename sc_proxy<X>::value_type
1349or_reduce(const sc_proxy<X> &a)
1350{
1351    return a.or_reduce();
1352}
1353
1354template <class X>
1355inline typename sc_proxy<X>::value_type
1356nor_reduce(const sc_proxy<X> &a)
1357{
1358    return a.nor_reduce();
1359}
1360
1361template <class X>
1362inline typename sc_proxy<X>::value_type
1363xor_reduce(const sc_proxy<X> &a)
1364{
1365    return a.xor_reduce();
1366}
1367
1368template <class X>
1369inline typename sc_proxy<X>::value_type
1370xnor_reduce(const sc_proxy<X> &a)
1371{
1372    return a.xnor_reduce();
1373}
1374
1375// ----------------------------------------------------------------------------
1376
1377template <class X>
1378inline ::std::ostream &
1379operator << (::std::ostream &os, const sc_proxy<X> &a)
1380{
1381    a.print(os);
1382    return os;
1383}
1384
1385template <class X>
1386inline ::std::istream &
1387operator >> (::std::istream &is, sc_proxy<X> &a)
1388{
1389    a.scan(is);
1390    return is;
1391}
1392
1393} // namespace sc_dt
1394
1395#endif // __SYSTEMC_EXT_DT_BIT_SC_PROXY_HH__
1396