sc_unsigned.hh revision 12853
16717Sgblack@eecs.umich.edu/*****************************************************************************
26717Sgblack@eecs.umich.edu
36717Sgblack@eecs.umich.edu  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
46717Sgblack@eecs.umich.edu  more contributor license agreements.  See the NOTICE file distributed
56717Sgblack@eecs.umich.edu  with this work for additional information regarding copyright ownership.
66717Sgblack@eecs.umich.edu  Accellera licenses this file to you under the Apache License, Version 2.0
76717Sgblack@eecs.umich.edu  (the "License"); you may not use this file except in compliance with the
86717Sgblack@eecs.umich.edu  License.  You may obtain a copy of the License at
96717Sgblack@eecs.umich.edu
106717Sgblack@eecs.umich.edu    http://www.apache.org/licenses/LICENSE-2.0
116717Sgblack@eecs.umich.edu
126717Sgblack@eecs.umich.edu  Unless required by applicable law or agreed to in writing, software
136717Sgblack@eecs.umich.edu  distributed under the License is distributed on an "AS IS" BASIS,
146717Sgblack@eecs.umich.edu  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
156717Sgblack@eecs.umich.edu  implied.  See the License for the specific language governing
166717Sgblack@eecs.umich.edu  permissions and limitations under the License.
176717Sgblack@eecs.umich.edu
186717Sgblack@eecs.umich.edu *****************************************************************************/
196717Sgblack@eecs.umich.edu
206717Sgblack@eecs.umich.edu/*****************************************************************************
216717Sgblack@eecs.umich.edu
226717Sgblack@eecs.umich.edu  sc_unsigned.h -- Arbitrary precision unsigned arithmetic.
236717Sgblack@eecs.umich.edu
246717Sgblack@eecs.umich.edu    This file includes the definitions of sc_unsigned_bitref,
256717Sgblack@eecs.umich.edu    sc_unsigned_subref, and sc_unsigned classes. The first two classes
266717Sgblack@eecs.umich.edu    are proxy classes to reference one bit and a range of bits of a
276717Sgblack@eecs.umich.edu    sc_unsigned number, respectively.
286717Sgblack@eecs.umich.edu
296717Sgblack@eecs.umich.edu    An sc_signed number has the sign-magnitude representation
306717Sgblack@eecs.umich.edu    internally. However, its interface guarantees a 2's-complement
316717Sgblack@eecs.umich.edu    representation. The sign-magnitude representation is chosen
326717Sgblack@eecs.umich.edu    because of its efficiency: The sc_signed and sc_unsigned types are
336717Sgblack@eecs.umich.edu    optimized for arithmetic rather than bitwise operations. For
346717Sgblack@eecs.umich.edu    arithmetic operations, the sign-magnitude representation performs
356717Sgblack@eecs.umich.edu    better.
366717Sgblack@eecs.umich.edu
376717Sgblack@eecs.umich.edu    It is also important to note that an sc_unsigned number with n
386717Sgblack@eecs.umich.edu    bits is equivalent to an sc_signed non-negative number with n + 1
396717Sgblack@eecs.umich.edu    bits.
406717Sgblack@eecs.umich.edu
416717Sgblack@eecs.umich.edu    The implementations of sc_signed and sc_unsigned classes are
426717Sgblack@eecs.umich.edu    almost identical: Most of the member and friend functions are
436717Sgblack@eecs.umich.edu    defined in sc_nbcommon.cpp and sc_nbfriends.cpp so that they can
446717Sgblack@eecs.umich.edu    be shared by both of these classes. These functions are chosed by
456717Sgblack@eecs.umich.edu    defining a few macros before including them such as IF_SC_SIGNED
466717Sgblack@eecs.umich.edu    and CLASS_TYPE. Our implementation choices are mostly dictated by
476717Sgblack@eecs.umich.edu    performance considerations in that we tried to provide the most
486717Sgblack@eecs.umich.edu    efficient sc_signed and sc_unsigned types without compromising
496717Sgblack@eecs.umich.edu    their interface.
506717Sgblack@eecs.umich.edu
516717Sgblack@eecs.umich.edu    For the behavior of operators, we have two semantics: the old and
526717Sgblack@eecs.umich.edu    new. The most important difference between these two semantics is
536717Sgblack@eecs.umich.edu    that the old semantics is closer to C/C++ semantics in that the
546717Sgblack@eecs.umich.edu    result type of a binary operator on unsigned and signed arguments
556717Sgblack@eecs.umich.edu    is unsigned; the new semantics, on the other hand, requires the
566717Sgblack@eecs.umich.edu    result type be signed. The new semantics is required by the VSIA
576717Sgblack@eecs.umich.edu    C/C++ data types standard. We have implemented the new semantics.
586717Sgblack@eecs.umich.edu
596717Sgblack@eecs.umich.edu  Original Author: Ali Dasdan, Synopsys, Inc.
606717Sgblack@eecs.umich.edu
616717Sgblack@eecs.umich.edu *****************************************************************************/
626717Sgblack@eecs.umich.edu
636717Sgblack@eecs.umich.edu/*****************************************************************************
646717Sgblack@eecs.umich.edu
656717Sgblack@eecs.umich.edu  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
666717Sgblack@eecs.umich.edu  changes you are making here.
676717Sgblack@eecs.umich.edu
686717Sgblack@eecs.umich.edu      Name, Affiliation, Date:
696717Sgblack@eecs.umich.edu  Description of Modification:
706717Sgblack@eecs.umich.edu
716717Sgblack@eecs.umich.edu *****************************************************************************/
726717Sgblack@eecs.umich.edu
736717Sgblack@eecs.umich.edu// $Log: sc_unsigned.h,v $
746717Sgblack@eecs.umich.edu// Revision 1.4  2011/08/24 22:05:46  acg
756717Sgblack@eecs.umich.edu//  Torsten Maehne: initialization changes to remove warnings.
766717Sgblack@eecs.umich.edu//
776717Sgblack@eecs.umich.edu// Revision 1.3  2011/02/18 20:19:15  acg
786717Sgblack@eecs.umich.edu//  Andy Goodrich: updating Copyright notice.
796717Sgblack@eecs.umich.edu//
806717Sgblack@eecs.umich.edu// Revision 1.2  2009/02/28 00:26:26  acg
816717Sgblack@eecs.umich.edu//  Andy Goodrich: bug fixes.
826717Sgblack@eecs.umich.edu//
836717Sgblack@eecs.umich.edu// Revision 1.1.1.1  2006/12/15 20:20:05  acg
846717Sgblack@eecs.umich.edu// SystemC 2.3
856717Sgblack@eecs.umich.edu//
866717Sgblack@eecs.umich.edu// Revision 1.5  2006/05/08 17:50:02  acg
876717Sgblack@eecs.umich.edu//   Andy Goodrich: Added David Long's declarations for friend operators,
886717Sgblack@eecs.umich.edu//   functions, and methods, to keep the Microsoft compiler happy.
896717Sgblack@eecs.umich.edu//
906717Sgblack@eecs.umich.edu// Revision 1.4  2006/03/13 20:25:27  acg
916717Sgblack@eecs.umich.edu//  Andy Goodrich: Addition of function declarations, e.g., xor_signed_friend()
926717Sgblack@eecs.umich.edu//  to keep gcc 4.x happy.
936717Sgblack@eecs.umich.edu//
946717Sgblack@eecs.umich.edu// Revision 1.3  2006/01/13 18:49:32  acg
956717Sgblack@eecs.umich.edu// Added $Log command so that CVS check in comments are reproduced in the
966717Sgblack@eecs.umich.edu// source.
976717Sgblack@eecs.umich.edu//
986717Sgblack@eecs.umich.edu
996717Sgblack@eecs.umich.edu#ifndef __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__
1006717Sgblack@eecs.umich.edu#define __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__
1016717Sgblack@eecs.umich.edu
1026717Sgblack@eecs.umich.edu#include <iostream>
1036717Sgblack@eecs.umich.edu
1046717Sgblack@eecs.umich.edu#include "../misc/sc_value_base.hh"
1056721Sgblack@eecs.umich.edu#include "../sc_temporary.hh"
1066721Sgblack@eecs.umich.edu#include "sc_length_param.hh"
1076717Sgblack@eecs.umich.edu#include "sc_nbdefs.hh"
1086717Sgblack@eecs.umich.edu#include "sc_nbexterns.hh"
1096717Sgblack@eecs.umich.edu#include "sc_nbutils.hh"
1106717Sgblack@eecs.umich.edu
1116717Sgblack@eecs.umich.edunamespace sc_dt
1126717Sgblack@eecs.umich.edu{
1136717Sgblack@eecs.umich.edu
1146717Sgblack@eecs.umich.edu// classes defined in this module
1156717Sgblack@eecs.umich.educlass sc_unsigned_bitref_r;
1166717Sgblack@eecs.umich.educlass sc_unsigned_bitref;
1176717Sgblack@eecs.umich.educlass sc_unsigned_subref_r;
1186717Sgblack@eecs.umich.educlass sc_unsigned_subref;
1196717Sgblack@eecs.umich.educlass sc_concatref;
1206717Sgblack@eecs.umich.educlass sc_unsigned;
1216717Sgblack@eecs.umich.edu
1226717Sgblack@eecs.umich.edu// forward class declarations
1236717Sgblack@eecs.umich.educlass sc_bv_base;
1246717Sgblack@eecs.umich.educlass sc_lv_base;
1256717Sgblack@eecs.umich.educlass sc_int_base;
1266717Sgblack@eecs.umich.educlass sc_uint_base;
1276717Sgblack@eecs.umich.educlass sc_int_subref_r;
1286717Sgblack@eecs.umich.educlass sc_uint_subref_r;
1296717Sgblack@eecs.umich.educlass sc_signed;
1306717Sgblack@eecs.umich.educlass sc_signed_subref_r;
1316717Sgblack@eecs.umich.educlass sc_fxval;
1326717Sgblack@eecs.umich.educlass sc_fxval_fast;
1336717Sgblack@eecs.umich.educlass sc_fxnum;
1346717Sgblack@eecs.umich.educlass sc_fxnum_fast;
1356717Sgblack@eecs.umich.edu
1366717Sgblack@eecs.umich.edu} // namespace sc_dt
1376717Sgblack@eecs.umich.edu
1386717Sgblack@eecs.umich.edu// extern template instantiations
1396717Sgblack@eecs.umich.edunamespace sc_core
1406717Sgblack@eecs.umich.edu{
1416717Sgblack@eecs.umich.edu
1426717Sgblack@eecs.umich.eduextern template class sc_vpool<sc_dt::sc_unsigned_bitref>;
1436717Sgblack@eecs.umich.eduextern template class sc_vpool<sc_dt::sc_unsigned_subref>;
1446717Sgblack@eecs.umich.eduextern template class sc_vpool<sc_dt::sc_unsigned>;
1456717Sgblack@eecs.umich.edu
1466717Sgblack@eecs.umich.edu} // namespace sc_core
1476717Sgblack@eecs.umich.edu
1486717Sgblack@eecs.umich.edunamespace sc_dt
1496717Sgblack@eecs.umich.edu{
1506717Sgblack@eecs.umich.edu
1516717Sgblack@eecs.umich.edu// Helper function declarions
1526717Sgblack@eecs.umich.eduint compare_unsigned(small_type us, int unb, int und, const sc_digit *ud,
1536717Sgblack@eecs.umich.edu                     small_type vs, int vnb, int vnd, const sc_digit *vd,
1546717Sgblack@eecs.umich.edu                     small_type if_u_signed=0, small_type if_v_signed=0);
1556717Sgblack@eecs.umich.edu
1566717Sgblack@eecs.umich.edusc_unsigned add_unsigned_friend(
1576717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1586717Sgblack@eecs.umich.edu        small_type vs, int vnb, int vnd, const sc_digit *vd);
1596717Sgblack@eecs.umich.edu
1606717Sgblack@eecs.umich.edusc_unsigned sub_unsigned_friend(
1616717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1626717Sgblack@eecs.umich.edu        small_type vs, int vnb, int vnd, const sc_digit *vd);
1636717Sgblack@eecs.umich.edu
1646717Sgblack@eecs.umich.edusc_unsigned mul_unsigned_friend(
1656717Sgblack@eecs.umich.edu        small_type s, int unb, int und, const sc_digit *ud,
1666717Sgblack@eecs.umich.edu        int vnb, int vnd, const sc_digit *vd);
1676717Sgblack@eecs.umich.edu
1686717Sgblack@eecs.umich.edusc_unsigned div_unsigned_friend(
1696717Sgblack@eecs.umich.edu        small_type s, int unb, int und, const sc_digit *ud,
1706717Sgblack@eecs.umich.edu        int vnb, int vnd, const sc_digit *vd);
1716717Sgblack@eecs.umich.edu
1726717Sgblack@eecs.umich.edusc_unsigned mod_unsigned_friend(
1736717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1746717Sgblack@eecs.umich.edu        int vnb, int vnd, const sc_digit *vd);
1756717Sgblack@eecs.umich.edu
1766717Sgblack@eecs.umich.edusc_unsigned and_unsigned_friend(
1776717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1786717Sgblack@eecs.umich.edu        small_type vs, int vnb, int vnd, const sc_digit *vd);
1796717Sgblack@eecs.umich.edu
1806717Sgblack@eecs.umich.edu
1816717Sgblack@eecs.umich.edusc_unsigned or_unsigned_friend(
1826717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1836717Sgblack@eecs.umich.edu        small_type vs, int vnb, int vnd, const sc_digit *vd);
1846717Sgblack@eecs.umich.edu
1856717Sgblack@eecs.umich.edusc_unsigned xor_unsigned_friend(
1866717Sgblack@eecs.umich.edu        small_type us, int unb, int und, const sc_digit *ud,
1876717Sgblack@eecs.umich.edu        small_type vs, int vnb, int vnd, const sc_digit *vd);
1886717Sgblack@eecs.umich.edu
1896717Sgblack@eecs.umich.edu
1906717Sgblack@eecs.umich.edu/*
1916717Sgblack@eecs.umich.edu * friend operator declarations
1926717Sgblack@eecs.umich.edu */
1936717Sgblack@eecs.umich.edu
1946717Sgblack@eecs.umich.edu// ARITHMETIC OPERATORS:
1956717Sgblack@eecs.umich.edu
1966717Sgblack@eecs.umich.edu// ADDition operators:
1976717Sgblack@eecs.umich.edusc_signed operator + (const sc_unsigned &u, const sc_signed &v);
1986717Sgblack@eecs.umich.edusc_signed operator + (const sc_signed &u, const sc_unsigned &v);
1996717Sgblack@eecs.umich.edu
2006717Sgblack@eecs.umich.edusc_unsigned operator + (const sc_unsigned &u, const sc_unsigned &v);
2016717Sgblack@eecs.umich.edusc_signed operator + (const sc_unsigned &u, int64 v);
2026717Sgblack@eecs.umich.edusc_unsigned operator + (const sc_unsigned &u, uint64 v);
2036717Sgblack@eecs.umich.edusc_signed operator + (const sc_unsigned &u, long v);
2046717Sgblack@eecs.umich.edusc_unsigned operator + (const sc_unsigned &u, unsigned long v);
2056717Sgblack@eecs.umich.edusc_signed operator + (const sc_unsigned &u, int v);
2066717Sgblack@eecs.umich.eduinline sc_unsigned operator + (const sc_unsigned &u, unsigned int v);
2076717Sgblack@eecs.umich.edu
2086717Sgblack@eecs.umich.edusc_signed operator + (int64 u, const sc_unsigned &v);
2096717Sgblack@eecs.umich.edusc_unsigned operator + (uint64 u, const sc_unsigned &v);
2106717Sgblack@eecs.umich.edusc_signed operator + (long u, const sc_unsigned &v);
2116717Sgblack@eecs.umich.edusc_unsigned operator + (unsigned long u, const sc_unsigned &v);
2126717Sgblack@eecs.umich.edusc_signed operator + (int u, const sc_unsigned &v);
2136717Sgblack@eecs.umich.eduinline sc_unsigned operator + (unsigned int u, const sc_unsigned &v);
2146717Sgblack@eecs.umich.edu
2156717Sgblack@eecs.umich.edusc_unsigned operator + (const sc_unsigned &u, const sc_uint_base &v);
2166717Sgblack@eecs.umich.edusc_signed operator + (const sc_unsigned &u, const sc_int_base &v);
2176717Sgblack@eecs.umich.edusc_unsigned operator + (const sc_uint_base &u, const sc_unsigned &v);
2186717Sgblack@eecs.umich.edusc_signed operator + (const sc_int_base &u, const sc_unsigned &v);
2196717Sgblack@eecs.umich.edu
2206717Sgblack@eecs.umich.edu// SUBtraction operators:
2216717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, const sc_signed &v);
2226717Sgblack@eecs.umich.edusc_signed operator - (const sc_signed &u, const sc_unsigned &v);
2236717Sgblack@eecs.umich.edu
2246717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, const sc_unsigned &v);
2256717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, int64 v);
2266717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, uint64 v);
2276717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, long v);
2286717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, unsigned long v);
2296717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, int v);
2306717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, unsigned int v);
2316717Sgblack@eecs.umich.edu
2326717Sgblack@eecs.umich.edusc_signed operator - (int64 u, const sc_unsigned &v);
2336717Sgblack@eecs.umich.edusc_signed operator - (uint64 u, const sc_unsigned &v);
2346717Sgblack@eecs.umich.edusc_signed operator - (long u, const sc_unsigned &v);
2356717Sgblack@eecs.umich.edusc_signed operator - (unsigned long u, const sc_unsigned &v);
2366717Sgblack@eecs.umich.edusc_signed operator - (int u, const sc_unsigned &v);
2376717Sgblack@eecs.umich.edusc_signed operator - (unsigned int u, const sc_unsigned &v);
2386717Sgblack@eecs.umich.edu
2396717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, const sc_uint_base &v);
2406717Sgblack@eecs.umich.edusc_signed operator - (const sc_unsigned &u, const sc_int_base &v);
2416717Sgblack@eecs.umich.edusc_signed operator - (const sc_uint_base &u, const sc_unsigned &v);
2426717Sgblack@eecs.umich.edusc_signed operator - (const sc_int_base &u, const sc_unsigned &v);
2436717Sgblack@eecs.umich.edu
2446717Sgblack@eecs.umich.edu// MULtiplication operators:
2456717Sgblack@eecs.umich.edusc_signed operator * (const sc_unsigned &u, const sc_signed &v);
2466717Sgblack@eecs.umich.edusc_signed operator * (const sc_signed &u, const sc_unsigned &v);
2476717Sgblack@eecs.umich.edu
2486717Sgblack@eecs.umich.edusc_unsigned operator * (const sc_unsigned &u, const sc_unsigned &v);
2496717Sgblack@eecs.umich.edusc_signed operator * (const sc_unsigned &u, int64 v);
2506717Sgblack@eecs.umich.edusc_unsigned operator * (const sc_unsigned &u, uint64 v);
2516717Sgblack@eecs.umich.edusc_signed operator * (const sc_unsigned &u, long v);
2526717Sgblack@eecs.umich.edusc_unsigned operator * (const sc_unsigned &u, unsigned long v);
2536717Sgblack@eecs.umich.edusc_signed operator * (const sc_unsigned &u, int v);
2546717Sgblack@eecs.umich.eduinline sc_unsigned operator * (const sc_unsigned &u, unsigned int v);
2556717Sgblack@eecs.umich.edu
2566717Sgblack@eecs.umich.edusc_signed operator * (int64 u, const sc_unsigned &v);
2576717Sgblack@eecs.umich.edusc_unsigned operator * (uint64 u, const sc_unsigned &v);
2586717Sgblack@eecs.umich.edusc_signed operator * (long u, const sc_unsigned &v);
2596717Sgblack@eecs.umich.edusc_unsigned operator * (unsigned long u, const sc_unsigned &v);
2606717Sgblack@eecs.umich.edusc_signed operator * (int u, const sc_unsigned &v);
2616717Sgblack@eecs.umich.eduinline sc_unsigned operator * (unsigned int u, const sc_unsigned &v);
2626717Sgblack@eecs.umich.edu
2636717Sgblack@eecs.umich.edusc_unsigned operator * (const sc_unsigned &u, const sc_uint_base &v);
2646717Sgblack@eecs.umich.edusc_signed operator * (const sc_unsigned &u, const sc_int_base &v);
2656717Sgblack@eecs.umich.edusc_unsigned operator * (const sc_uint_base &u, const sc_unsigned &v);
2666717Sgblack@eecs.umich.edusc_signed operator * (const sc_int_base &u, const sc_unsigned &v);
2676717Sgblack@eecs.umich.edu
2686717Sgblack@eecs.umich.edu// DIVision operators:
2696717Sgblack@eecs.umich.edusc_signed operator / (const sc_unsigned &u, const sc_signed &v);
2706717Sgblack@eecs.umich.edusc_signed operator / (const sc_signed &u, const sc_unsigned &v);
2716717Sgblack@eecs.umich.edu
2726717Sgblack@eecs.umich.edusc_unsigned operator / (const sc_unsigned &u, const sc_unsigned &v);
2736717Sgblack@eecs.umich.edusc_signed operator / (const sc_unsigned &u, int64 v);
2746717Sgblack@eecs.umich.edusc_unsigned operator / (const sc_unsigned &u, uint64 v);
2756717Sgblack@eecs.umich.edusc_signed operator / (const sc_unsigned &u, long v);
2766717Sgblack@eecs.umich.edusc_unsigned operator / (const sc_unsigned &u, unsigned long v);
2776717Sgblack@eecs.umich.edusc_signed operator / (const sc_unsigned &u, int v);
2786717Sgblack@eecs.umich.eduinline sc_unsigned operator / (const sc_unsigned &u, unsigned int v);
2796717Sgblack@eecs.umich.edu
2806717Sgblack@eecs.umich.edusc_signed operator / (int64 u, const sc_unsigned &v);
2816717Sgblack@eecs.umich.edusc_unsigned operator / (uint64 u, const sc_unsigned &v);
2826717Sgblack@eecs.umich.edusc_signed operator / (long u, const sc_unsigned &v);
2836717Sgblack@eecs.umich.edusc_unsigned operator / (unsigned long u, const sc_unsigned &v);
2846717Sgblack@eecs.umich.edusc_signed operator / (int u, const sc_unsigned &v);
2856717Sgblack@eecs.umich.eduinline sc_unsigned operator / (unsigned int u, const sc_unsigned &v);
2866717Sgblack@eecs.umich.edu
2876717Sgblack@eecs.umich.edusc_unsigned operator / (const sc_unsigned &u, const sc_uint_base &v);
2886717Sgblack@eecs.umich.edusc_signed operator / (const sc_unsigned &u, const sc_int_base &v);
2896717Sgblack@eecs.umich.edusc_unsigned operator / (const sc_uint_base &u, const sc_unsigned &v);
2906717Sgblack@eecs.umich.edusc_signed operator / (const sc_int_base &u, const sc_unsigned &v);
2916717Sgblack@eecs.umich.edu
2926717Sgblack@eecs.umich.edu// MODulo operators:
2936717Sgblack@eecs.umich.edusc_signed operator % (const sc_unsigned &u, const sc_signed &v);
2946717Sgblack@eecs.umich.edusc_signed operator % (const sc_signed &u, const sc_unsigned &v);
2956717Sgblack@eecs.umich.edu
2966717Sgblack@eecs.umich.edusc_unsigned operator % (const sc_unsigned &u, const sc_unsigned &v);
2976717Sgblack@eecs.umich.edusc_signed operator % (const sc_unsigned &u, int64 v);
2986717Sgblack@eecs.umich.edusc_unsigned operator % (const sc_unsigned &u, uint64 v);
2996717Sgblack@eecs.umich.edusc_signed operator % (const sc_unsigned &u, long v);
3006717Sgblack@eecs.umich.edusc_unsigned operator % (const sc_unsigned &u, unsigned long v);
3016717Sgblack@eecs.umich.edusc_signed operator % (const sc_unsigned &u, int v);
3026717Sgblack@eecs.umich.eduinline sc_unsigned operator % (const sc_unsigned &u, unsigned int v);
3036717Sgblack@eecs.umich.edu
3046717Sgblack@eecs.umich.edusc_signed operator % (int64 u, const sc_unsigned &v);
3056717Sgblack@eecs.umich.edusc_unsigned operator % (uint64 u, const sc_unsigned &v);
3066717Sgblack@eecs.umich.edusc_signed operator % (long u, const sc_unsigned &v);
3076717Sgblack@eecs.umich.edusc_unsigned operator % (unsigned long u, const sc_unsigned &v);
3086717Sgblack@eecs.umich.edusc_signed operator % (int u, const sc_unsigned &v);
3096717Sgblack@eecs.umich.eduinline sc_unsigned operator % (unsigned int u, const sc_unsigned &v);
3106717Sgblack@eecs.umich.edu
3116717Sgblack@eecs.umich.edusc_unsigned operator % (const sc_unsigned &u, const sc_uint_base &v);
3126717Sgblack@eecs.umich.edusc_signed operator % (const sc_unsigned &u, const sc_int_base &v);
3136717Sgblack@eecs.umich.edusc_unsigned operator % (const sc_uint_base &u, const sc_unsigned &v);
3146717Sgblack@eecs.umich.edusc_signed operator % (const sc_int_base &u, const sc_unsigned &v);
3156717Sgblack@eecs.umich.edu
3166717Sgblack@eecs.umich.edu// BITWISE OPERATORS:
3176717Sgblack@eecs.umich.edu
3186717Sgblack@eecs.umich.edu// Bitwise AND operators:
3196717Sgblack@eecs.umich.edusc_signed operator & (const sc_unsigned &u, const sc_signed &v);
3206717Sgblack@eecs.umich.edusc_signed operator & (const sc_signed &u, const sc_unsigned &v);
3216717Sgblack@eecs.umich.edu
3226717Sgblack@eecs.umich.edusc_unsigned operator & (const sc_unsigned &u, const sc_unsigned &v);
3236717Sgblack@eecs.umich.edusc_signed operator & (const sc_unsigned &u, int64 v);
3246717Sgblack@eecs.umich.edusc_unsigned operator & (const sc_unsigned &u, uint64 v);
3256717Sgblack@eecs.umich.edusc_signed operator & (const sc_unsigned &u, long v);
3266717Sgblack@eecs.umich.edusc_unsigned operator & (const sc_unsigned &u, unsigned long v);
3276717Sgblack@eecs.umich.edusc_signed operator & (const sc_unsigned &u, int v);
3286717Sgblack@eecs.umich.eduinline sc_unsigned operator & (const sc_unsigned &u, unsigned int v);
329
330sc_signed operator & (int64 u, const sc_unsigned &v);
331sc_unsigned operator & (uint64 u, const sc_unsigned &v);
332sc_signed operator & (long u, const sc_unsigned &v);
333sc_unsigned operator & (unsigned long u, const sc_unsigned &v);
334sc_signed operator & (int u, const sc_unsigned &v);
335inline sc_unsigned operator & (unsigned int u, const sc_unsigned &v);
336
337sc_unsigned operator & (const sc_unsigned &u, const sc_uint_base &v);
338sc_signed operator & (const sc_unsigned &u, const sc_int_base &v);
339sc_unsigned operator & (const sc_uint_base &u, const sc_unsigned &v);
340sc_signed operator & (const sc_int_base &u, const sc_unsigned &v);
341
342// Bitwise OR operators:
343sc_signed operator | (const sc_unsigned &u, const sc_signed &v);
344sc_signed operator | (const sc_signed &u, const sc_unsigned &v);
345
346sc_unsigned operator | (const sc_unsigned &u, const sc_unsigned &v);
347sc_signed operator | (const sc_unsigned &u, int64 v);
348sc_unsigned operator | (const sc_unsigned &u, uint64 v);
349sc_signed operator | (const sc_unsigned &u, long v);
350sc_unsigned operator | (const sc_unsigned &u, unsigned long v);
351sc_signed operator | (const sc_unsigned &u, int v);
352inline sc_unsigned operator | (const sc_unsigned &u, unsigned int v);
353
354sc_signed operator | (int64 u, const sc_unsigned &v);
355sc_unsigned operator | (uint64 u, const sc_unsigned &v);
356sc_signed operator | (long u, const sc_unsigned &v);
357sc_unsigned operator | (unsigned long u, const sc_unsigned &v);
358sc_signed operator | (int u, const sc_unsigned &v);
359inline sc_unsigned operator | (unsigned int u, const sc_unsigned &v);
360
361sc_unsigned operator | (const sc_unsigned &u, const sc_uint_base &v);
362sc_signed operator | (const sc_unsigned &u, const sc_int_base &v);
363sc_unsigned operator | (const sc_uint_base &u, const sc_unsigned &v);
364sc_signed operator | (const sc_int_base &u, const sc_unsigned &v);
365
366// Bitwise XOR operators:
367sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v);
368sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v);
369
370sc_unsigned operator ^ (const sc_unsigned &u, const sc_unsigned &v);
371sc_signed operator ^ (const sc_unsigned &u, int64 v);
372sc_unsigned operator ^ (const sc_unsigned &u, uint64 v);
373sc_signed operator ^ (const sc_unsigned &u, long v);
374sc_unsigned operator ^ (const sc_unsigned &u, unsigned long v);
375sc_signed operator ^ (const sc_unsigned &u, int v);
376inline sc_unsigned operator ^ (const sc_unsigned &u, unsigned int v);
377
378sc_signed operator ^ (int64 u, const sc_unsigned &v);
379sc_unsigned operator ^ (uint64 u, const sc_unsigned &v);
380sc_signed operator ^ (long u, const sc_unsigned &v);
381sc_unsigned operator ^ (unsigned long u, const sc_unsigned &v);
382sc_signed operator ^ (int u, const sc_unsigned &v);
383inline sc_unsigned operator ^ (unsigned int u, const sc_unsigned &v);
384
385sc_unsigned operator ^ (const sc_unsigned &u, const sc_uint_base &v);
386sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v);
387sc_unsigned operator ^ (const sc_uint_base &u, const sc_unsigned &v);
388sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v);
389
390// SHIFT OPERATORS:
391
392// LEFT SHIFT operators:
393sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v);
394sc_signed operator << (const sc_signed &u, const sc_unsigned &v);
395
396sc_unsigned operator << (const sc_unsigned &u, const sc_unsigned &v);
397sc_unsigned operator << (const sc_unsigned &u, int64 v);
398sc_unsigned operator << (const sc_unsigned &u, uint64 v);
399sc_unsigned operator << (const sc_unsigned &u, long v);
400sc_unsigned operator << (const sc_unsigned &u, unsigned long v);
401inline sc_unsigned operator << (const sc_unsigned &u, int v);
402inline sc_unsigned operator << (const sc_unsigned &u, unsigned int v);
403
404sc_unsigned operator << (const sc_unsigned &u, const sc_uint_base &v);
405sc_unsigned operator << (const sc_unsigned &u, const sc_int_base &v);
406
407// RIGHT SHIFT operators:
408sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v);
409sc_signed operator >> (const sc_signed &u, const sc_unsigned &v);
410
411sc_unsigned operator >> (const sc_unsigned &u, const sc_unsigned &v);
412sc_unsigned operator >> (const sc_unsigned &u, int64 v);
413sc_unsigned operator >> (const sc_unsigned &u, uint64 v);
414sc_unsigned operator >> (const sc_unsigned &u, long v);
415sc_unsigned operator >> (const sc_unsigned &u, unsigned long v);
416inline sc_unsigned operator >> (const sc_unsigned &u, int v);
417inline sc_unsigned operator >> (const sc_unsigned &u, unsigned int v);
418
419sc_unsigned operator >> ( const sc_unsigned &, const sc_uint_base &);
420sc_unsigned operator >> ( const sc_unsigned&, const sc_int_base &);
421
422// Unary arithmetic operators
423sc_unsigned operator + (const sc_unsigned &u);
424sc_signed operator - (const sc_unsigned &u);
425
426// LOGICAL OPERATORS:
427
428// Logical EQUAL operators:
429bool operator == (const sc_unsigned &u, const sc_signed &v);
430bool operator == (const sc_signed &u, const sc_unsigned &v);
431
432bool operator == (const sc_unsigned &u, const sc_unsigned &v);
433bool operator == (const sc_unsigned &u, int64 v);
434bool operator == (const sc_unsigned &u, uint64 v);
435bool operator == (const sc_unsigned &u, long v);
436bool operator == (const sc_unsigned &u, unsigned long v);
437inline bool operator == (const sc_unsigned &u, int v);
438inline bool operator == (const sc_unsigned &u, unsigned int v);
439
440bool operator == (int64 u, const sc_unsigned &v);
441bool operator == (uint64 u, const sc_unsigned &v);
442bool operator == (long u, const sc_unsigned &v);
443bool operator == (unsigned long u, const sc_unsigned &v);
444inline bool operator == (int u, const sc_unsigned &v);
445inline bool operator == (unsigned int u, const sc_unsigned &v) ;
446
447bool operator == (const sc_unsigned &u, const sc_uint_base &v);
448bool operator == (const sc_unsigned &u, const sc_int_base &v);
449bool operator == (const sc_uint_base &u, const sc_unsigned &v);
450bool operator == (const sc_int_base &u, const sc_unsigned &v);
451
452// Logical NOT_EQUAL operators:
453bool operator != (const sc_unsigned &u, const sc_signed &v);
454bool operator != (const sc_signed &u, const sc_unsigned &v);
455
456bool operator != (const sc_unsigned &u, const sc_unsigned &v);
457bool operator != (const sc_unsigned &u, int64 v);
458bool operator != (const sc_unsigned &u, uint64 v);
459bool operator != (const sc_unsigned &u, long v);
460bool operator != (const sc_unsigned &u, unsigned long v);
461inline bool operator != (const sc_unsigned &u, int v);
462inline bool operator != (const sc_unsigned &u, unsigned int v);
463
464bool operator != (int64 u, const sc_unsigned &v);
465bool operator != (uint64 u, const sc_unsigned &v);
466bool operator != (long u, const sc_unsigned &v);
467bool operator != (unsigned long u, const sc_unsigned &v);
468inline bool operator != (int u, const sc_unsigned &v);
469inline bool operator != (unsigned int u, const sc_unsigned &v);
470
471bool operator != (const sc_unsigned &u, const sc_uint_base &v);
472bool operator != (const sc_unsigned &u, const sc_int_base &v);
473bool operator != (const sc_uint_base &u, const sc_unsigned &v);
474bool operator != (const sc_int_base &u, const sc_unsigned &v);
475
476// Logical LESS_THAN operators:
477bool operator < (const sc_unsigned &u, const sc_signed &v);
478bool operator < (const sc_signed &u, const sc_unsigned &v);
479
480bool operator < (const sc_unsigned &u, const sc_unsigned &v);
481bool operator < (const sc_unsigned &u, int64 v);
482bool operator < (const sc_unsigned &u, uint64 v);
483bool operator < (const sc_unsigned &u, long v);
484bool operator < (const sc_unsigned &u, unsigned long v);
485inline bool operator < (const sc_unsigned &u, int v);
486inline bool operator < (const sc_unsigned &u, unsigned int v);
487
488bool operator < (int64 u, const sc_unsigned &v);
489bool operator < (uint64 u, const sc_unsigned &v);
490bool operator < (long u, const sc_unsigned &v);
491bool operator < (unsigned long u, const sc_unsigned &v);
492inline bool operator < (int u, const sc_unsigned &v);
493inline bool operator < (unsigned int u, const sc_unsigned &v);
494
495bool operator < (const sc_unsigned &u, const sc_uint_base &v);
496bool operator < (const sc_unsigned &u, const sc_int_base &v);
497bool operator < (const sc_uint_base &u, const sc_unsigned &v);
498bool operator < (const sc_int_base &u, const sc_unsigned &v);
499
500// Logical LESS_THAN_AND_EQUAL operators:
501bool operator <= (const sc_unsigned &u, const sc_signed &v);
502bool operator <= (const sc_signed &u, const sc_unsigned &v);
503
504bool operator <= (const sc_unsigned &u, const sc_unsigned &v);
505bool operator <= (const sc_unsigned &u, int64 v);
506bool operator <= (const sc_unsigned &u, uint64 v);
507bool operator <= (const sc_unsigned &u, long v);
508bool operator <= (const sc_unsigned &u, unsigned long v);
509inline bool operator <= (const sc_unsigned &u, int v);
510inline bool operator <= (const sc_unsigned &u, unsigned int v);
511
512bool operator <= (int64 u, const sc_unsigned &v);
513bool operator <= (uint64 u, const sc_unsigned &v);
514bool operator <= (long u, const sc_unsigned &v);
515bool operator <= (unsigned long u, const sc_unsigned &v);
516inline bool operator <= (int u, const sc_unsigned &v);
517inline bool operator <= (unsigned int u, const sc_unsigned &v);
518
519bool operator <= (const sc_unsigned &u, const sc_uint_base &v);
520bool operator <= (const sc_unsigned &u, const sc_int_base &v);
521bool operator <= (const sc_uint_base &u, const sc_unsigned &v);
522bool operator <= (const sc_int_base &u, const sc_unsigned &v);
523
524// Logical GREATER_THAN operators:
525bool operator > (const sc_unsigned &u, const sc_signed &v);
526bool operator > (const sc_signed &u, const sc_unsigned &v);
527
528bool operator > (const sc_unsigned &u, const sc_unsigned &v);
529bool operator > (const sc_unsigned &u, int64 v);
530bool operator > (const sc_unsigned &u, uint64 v);
531bool operator > (const sc_unsigned &u, long v);
532bool operator > (const sc_unsigned &u, unsigned long v);
533inline bool operator > (const sc_unsigned &u, int v);
534inline bool operator > (const sc_unsigned &u, unsigned int v);
535
536bool operator > (int64 u, const sc_unsigned &v);
537bool operator > (uint64 u, const sc_unsigned &v);
538bool operator > (long u, const sc_unsigned &v);
539bool operator > (unsigned long u, const sc_unsigned &v);
540inline bool operator > (int u, const sc_unsigned &v);
541inline bool operator > (unsigned int u, const sc_unsigned &v);
542
543bool operator > (const sc_unsigned &u, const sc_uint_base &v);
544bool operator > (const sc_unsigned &u, const sc_int_base &v);
545bool operator > (const sc_uint_base &u, const sc_unsigned &v);
546bool operator > (const sc_int_base &u, const sc_unsigned &v);
547
548// Logical GREATER_THAN_AND_EQUAL operators:
549bool operator >= (const sc_unsigned &u, const sc_signed &v);
550bool operator >= (const sc_signed &u, const sc_unsigned &v);
551
552bool operator >= (const sc_unsigned &u, const sc_unsigned &v);
553bool operator >= (const sc_unsigned &u, int64 v);
554bool operator >= (const sc_unsigned &u, uint64 v);
555bool operator >= (const sc_unsigned &u, long v);
556bool operator >= (const sc_unsigned &u, unsigned long v);
557inline bool operator >= (const sc_unsigned &u, int v);
558inline bool operator >= (const sc_unsigned &u, unsigned int v);
559
560bool operator >= (int64 u, const sc_unsigned &v);
561bool operator >= (uint64 u, const sc_unsigned &v);
562bool operator >= (long u, const sc_unsigned &v);
563bool operator >= (unsigned long u, const sc_unsigned &v);
564inline bool operator >= (int u, const sc_unsigned &v);
565inline bool operator >= (unsigned int u, const sc_unsigned &v);
566
567bool operator >= (const sc_unsigned &u, const sc_uint_base &v);
568bool operator >= (const sc_unsigned &u, const sc_int_base &v);
569bool operator >= (const sc_uint_base &u, const sc_unsigned &v);
570bool operator >= (const sc_int_base &u, const sc_unsigned &v);
571
572// Bitwise NOT operator (unary).
573sc_unsigned operator ~ (const sc_unsigned &u);
574
575// ----------------------------------------------------------------------------
576//  CLASS : sc_unsigned_bitref_r
577//
578//  Proxy class for sc_unsigned bit selection (r-value only).
579// ----------------------------------------------------------------------------
580
581class sc_unsigned_bitref_r : public sc_value_base
582{
583    friend class sc_unsigned;
584
585  protected:
586    // construction and initialization:
587    sc_unsigned_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {}
588
589    void
590    initialize(const sc_unsigned *obj_p, int index_)
591    {
592        m_obj_p = const_cast<sc_unsigned *>(obj_p);
593        m_index = index_;
594    }
595
596  public:
597    // destructor
598    virtual ~sc_unsigned_bitref_r() {}
599
600    // copy constructor
601    sc_unsigned_bitref_r(const sc_unsigned_bitref_r &a) :
602        sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
603    {}
604
605    // capacity
606    int length() const { return 1; }
607
608    // implicit conversion to bool
609    operator uint64 () const;
610    bool operator ! () const;
611    bool operator ~ () const;
612
613    // explicit conversions
614    uint64 value() const { return operator uint64(); }
615    bool to_bool() const { return operator uint64(); }
616
617    // concatenation support
618    virtual int
619    concat_length(bool *xz_present_p) const
620    {
621        if (xz_present_p)
622            *xz_present_p = false;
623        return 1;
624    }
625    virtual uint64
626    concat_get_uint64() const
627    {
628        return (uint64)operator uint64();
629    }
630    virtual bool
631    concat_get_ctrl(sc_digit *dst_p, int low_i) const
632    {
633        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
634        int word_i = low_i / BITS_PER_DIGIT;
635        dst_p[word_i] &= ~bit_mask;
636        return false;
637    }
638    virtual bool
639    concat_get_data(sc_digit *dst_p, int low_i) const
640    {
641        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
642        bool result; // True if non-zero.
643        int word_i = low_i / BITS_PER_DIGIT;
644        if (operator uint64())
645        {
646            dst_p[word_i] |= bit_mask;
647            result = true;
648        } else {
649            dst_p[word_i] &= ~bit_mask;
650            result = false;
651        }
652        return result;
653    }
654
655    // other methods
656    void print(::std::ostream &os=::std::cout) const { os << to_bool(); }
657
658  protected:
659    int m_index;
660    sc_unsigned *m_obj_p;
661
662  private:
663    // Disabled
664    const sc_unsigned_bitref_r &operator = (const sc_unsigned_bitref_r &);
665};
666
667inline ::std::ostream &operator << (
668        ::std::ostream &, const sc_unsigned_bitref_r &);
669
670
671// ----------------------------------------------------------------------------
672//  CLASS : sc_unsigned_bitref
673//
674//  Proxy class for sc_unsigned bit selection (r-value and l-value).
675// ----------------------------------------------------------------------------
676
677class sc_unsigned_bitref : public sc_unsigned_bitref_r
678{
679    friend class sc_unsigned;
680    friend class sc_core::sc_vpool<sc_unsigned_bitref>;
681
682  protected: // construction
683    sc_unsigned_bitref() : sc_unsigned_bitref_r() {}
684
685  public:
686    // copy constructor
687    sc_unsigned_bitref(const sc_unsigned_bitref &a) : sc_unsigned_bitref_r(a)
688    {}
689
690    // assignment operators
691    const sc_unsigned_bitref &operator = (const sc_unsigned_bitref_r &);
692    const sc_unsigned_bitref &operator = (const sc_unsigned_bitref &);
693    const sc_unsigned_bitref &operator = (bool);
694
695    const sc_unsigned_bitref &operator &= (bool);
696    const sc_unsigned_bitref &operator |= (bool);
697    const sc_unsigned_bitref &operator ^= (bool);
698
699    // concatenation methods
700    virtual void concat_set(int64 src, int low_i);
701    virtual void concat_set(const sc_signed &src, int low_i);
702    virtual void concat_set(const sc_unsigned &src, int low_i);
703    virtual void concat_set(uint64 src, int low_i);
704
705    // other methods
706    void scan(::std::istream &is=::std::cin);
707
708  protected:
709    static sc_core::sc_vpool<sc_unsigned_bitref> m_pool;
710};
711
712inline ::std::istream &operator >> (::std::istream &, sc_unsigned_bitref &);
713
714
715// ----------------------------------------------------------------------------
716//  CLASS : sc_unsigned_subref_r
717//
718//  Proxy class for sc_unsigned part selection (r-value only).
719// ----------------------------------------------------------------------------
720
721class sc_unsigned_subref_r : public sc_value_base
722{
723    friend class sc_signed;
724    friend class sc_unsigned;
725    friend class sc_unsigned_signal;
726
727  protected:
728    // constructor
729    sc_unsigned_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0)
730    {}
731
732    void
733    initialize(const sc_unsigned *obj_p, int left_, int right_)
734    {
735        m_obj_p = const_cast<sc_unsigned *>(obj_p);
736        m_left = left_;
737        m_right = right_;
738    }
739
740  public:
741    // destructor
742    virtual ~sc_unsigned_subref_r() {}
743
744    // copy constructor
745    sc_unsigned_subref_r(const sc_unsigned_subref_r &a) :
746            sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p),
747            m_right(a.m_right)
748    {}
749
750    // capacity
751    int
752    length() const
753    {
754        if (m_left >= m_right)
755            return m_left - m_right + 1;
756        else
757            return m_right - m_left + 1;
758    }
759
760    // implicit conversion to sc_unsigned
761    operator sc_unsigned () const;
762
763    // explicit conversions
764    int to_int() const;
765    unsigned int to_uint() const;
766    long to_long() const;
767    unsigned long to_ulong() const;
768    int64 to_int64() const;
769    uint64 to_uint64() const;
770    double to_double() const;
771
772    // explicit conversion to character string
773    const std::string to_string(sc_numrep numrep=SC_DEC) const;
774    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
775
776    // concatenation support
777    virtual int concat_length(bool *xz_present_p) const
778    {
779        if (xz_present_p)
780            *xz_present_p = false;
781        return m_left - m_right + 1;
782    }
783    virtual uint64 concat_get_uint64() const;
784    virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const;
785    virtual bool concat_get_data(sc_digit *dst_p, int low_i) const;
786
787    // reduce methods
788    bool and_reduce() const;
789    bool nand_reduce() const;
790    bool or_reduce() const;
791    bool nor_reduce() const;
792    bool xor_reduce() const ;
793    bool xnor_reduce() const;
794
795    // other methods
796    void
797    print(::std::ostream &os=::std::cout) const
798    {
799        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
800    }
801
802  protected:
803    int m_left; // Left-most bit in this part selection.
804    sc_unsigned *m_obj_p; // Target of this part selection.
805    int m_right; // Right-most bit in this part selection.
806
807  private:
808    // Disabled
809    const sc_unsigned_subref_r &operator = (const sc_unsigned_subref_r &);
810};
811
812inline ::std::ostream &operator << (
813        ::std::ostream &, const sc_unsigned_subref_r &);
814
815
816// ----------------------------------------------------------------------------
817//  CLASS : sc_unsigned_subref
818//
819//  Proxy class for sc_unsigned part selection (r-value and l-value).
820// ----------------------------------------------------------------------------
821
822class sc_unsigned_subref : public sc_unsigned_subref_r
823{
824    friend class sc_unsigned;
825    friend class sc_core::sc_vpool<sc_unsigned_subref>;
826
827    // constructor
828  protected:
829    sc_unsigned_subref() : sc_unsigned_subref_r() {}
830
831  public:
832    // copy constructor
833    sc_unsigned_subref(const sc_unsigned_subref &a) : sc_unsigned_subref_r(a)
834    {}
835
836    // assignment operators
837    const sc_unsigned_subref &operator = (const sc_unsigned_subref_r &a);
838    const sc_unsigned_subref &operator = (const sc_unsigned_subref &a);
839    const sc_unsigned_subref &operator = (const sc_unsigned &a);
840
841    template<class T>
842    const sc_unsigned_subref &operator = (const sc_generic_base<T> &a);
843    const sc_unsigned_subref &operator = (const sc_signed_subref_r &a);
844    const sc_unsigned_subref &operator = (const sc_signed &a);
845
846    const sc_unsigned_subref &operator = (const char *a);
847    const sc_unsigned_subref &operator = (unsigned long a);
848    const sc_unsigned_subref &operator = (long a);
849
850    const sc_unsigned_subref &
851    operator = (unsigned int a)
852    {
853        return operator = ((unsigned long)a);
854    }
855
856    const sc_unsigned_subref &
857    operator = (int a)
858    {
859        return operator = ((long)a);
860    }
861
862    const sc_unsigned_subref &operator = (uint64 a);
863    const sc_unsigned_subref &operator = (int64 a);
864    const sc_unsigned_subref &operator = (double a);
865    const sc_unsigned_subref &operator = (const sc_int_base &a);
866    const sc_unsigned_subref &operator = (const sc_uint_base &a);
867
868    // concatenation methods
869    virtual void concat_set(int64 src, int low_i);
870    virtual void concat_set(const sc_signed &src, int low_i);
871    virtual void concat_set(const sc_unsigned &src, int low_i);
872    virtual void concat_set(uint64 src, int low_i);
873
874    // other methods
875    void scan(::std::istream &is=::std::cin);
876
877  protected:
878    static sc_core::sc_vpool<sc_unsigned_subref> m_pool;
879};
880
881inline ::std::istream &operator >> (::std::istream &, sc_unsigned_subref &);
882
883
884// ----------------------------------------------------------------------------
885//  CLASS : sc_unsigned
886//
887//  Arbitrary precision unsigned number.
888// ----------------------------------------------------------------------------
889
890class sc_unsigned : public sc_value_base
891{
892    friend class sc_concatref;
893    friend class sc_unsigned_bitref_r;
894    friend class sc_unsigned_bitref;
895    friend class sc_unsigned_subref_r;
896    friend class sc_unsigned_subref;
897    friend class sc_signed;
898    friend class sc_signed_subref;
899    friend class sc_signed_subref_r;
900
901    // Needed for types using sc_unsigned.
902    typedef bool elemtype;
903
904    void invalid_init(const char *type_name, int nb) const;
905
906  public:
907    // constructors
908    explicit sc_unsigned(int nb=sc_length_param().len());
909    sc_unsigned(const sc_unsigned &v);
910    sc_unsigned(const sc_signed &v);
911    template<class T>
912    explicit sc_unsigned(const sc_generic_base<T> &v);
913    explicit sc_unsigned(const sc_bv_base &v);
914    explicit sc_unsigned(const sc_lv_base &v);
915    explicit sc_unsigned(const sc_int_subref_r &v);
916    explicit sc_unsigned(const sc_uint_subref_r &v);
917    explicit sc_unsigned(const sc_signed_subref_r &v);
918    explicit sc_unsigned(const sc_unsigned_subref_r &v);
919
920    // assignment operators
921    const sc_unsigned &operator = (const sc_unsigned &v);
922    const sc_unsigned &operator = (const sc_unsigned_subref_r &a);
923
924    template<class T>
925    const sc_unsigned &
926    operator = (const sc_generic_base<T> &a)
927    {
928        a->to_sc_unsigned(*this);
929        return *this;
930    }
931
932    const sc_unsigned &operator = (const sc_signed &v);
933    const sc_unsigned &operator = (const sc_signed_subref_r &a);
934
935    const sc_unsigned &operator = (const char *v);
936    const sc_unsigned &operator = (int64 v);
937    const sc_unsigned &operator = (uint64 v);
938    const sc_unsigned &operator = (long v);
939    const sc_unsigned &operator = (unsigned long v);
940
941    const sc_unsigned &
942    operator = (int v)
943    {
944        return operator = ((long)v);
945    }
946
947    const sc_unsigned &
948    operator = (unsigned int v)
949    {
950        return operator = ((unsigned long)v);
951    }
952
953    const sc_unsigned &operator = (double v);
954    const sc_unsigned &operator = (const sc_int_base &v);
955    const sc_unsigned &operator = (const sc_uint_base &v);
956
957    const sc_unsigned &operator = (const sc_bv_base &);
958    const sc_unsigned &operator = (const sc_lv_base &);
959
960    const sc_unsigned &operator = (const sc_fxval &);
961    const sc_unsigned &operator = (const sc_fxval_fast &);
962    const sc_unsigned &operator = (const sc_fxnum &);
963    const sc_unsigned &operator = (const sc_fxnum_fast &);
964
965    // destructor
966    virtual ~sc_unsigned()
967    {
968#       ifndef SC_MAX_NBITS
969            delete [] digit;
970#       endif
971    }
972
973    // Concatenation support:
974    sc_digit *get_raw() const { return digit; }
975    virtual int
976    concat_length(bool *xz_present_p) const
977    {
978        if (xz_present_p)
979            *xz_present_p = false;
980        return nbits - 1;
981    }
982    virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const;
983    virtual bool concat_get_data(sc_digit *dst_p, int low_i) const;
984    virtual uint64 concat_get_uint64() const;
985    virtual void concat_set(int64 src, int low_i);
986    virtual void concat_set(const sc_signed &src, int low_i);
987    virtual void concat_set(const sc_unsigned &src, int low_i);
988    virtual void concat_set(uint64 src, int low_i);
989
990    // Increment operators.
991    sc_unsigned &operator ++ ();
992    const sc_unsigned operator ++ (int);
993
994    // Decrement operators.
995    sc_unsigned &operator -- ();
996    const sc_unsigned operator -- (int);
997
998    // bit selection
999    inline void
1000    check_index(int i) const
1001    {
1002        if ((i < 0) || (i >= nbits - 1))
1003            invalid_index(i);
1004    }
1005
1006    void invalid_index(int i) const;
1007
1008    sc_unsigned_bitref &
1009    operator [] (int i)
1010    {
1011        check_index(i);
1012        sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate();
1013        result_p->initialize(this, i);
1014        return *result_p;
1015    }
1016
1017    const sc_unsigned_bitref_r &
1018    operator [] (int i) const
1019    {
1020        check_index(i);
1021        sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate();
1022        result_p->initialize(this, i);
1023        return *result_p;
1024    }
1025
1026    sc_unsigned_bitref &
1027    bit(int i)
1028    {
1029        check_index(i);
1030        sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate();
1031        result_p->initialize(this, i);
1032        return *result_p;
1033    }
1034
1035    const sc_unsigned_bitref_r &
1036    bit(int i) const
1037    {
1038        check_index(i);
1039        sc_unsigned_bitref *result_p = sc_unsigned_bitref::m_pool.allocate();
1040        result_p->initialize(this, i);
1041        return *result_p;
1042    }
1043
1044    // part selection
1045
1046    // Subref operators. Help access the range of bits from the ith to
1047    // jth. These indices have arbitrary precedence with respect to each
1048    // other, i.e., we can have i <= j or i > j. Note the equivalence
1049    // between range(i, j) and operator (i, j). Also note that
1050    // operator (i, i) returns an unsigned number that corresponds to the
1051    // bit operator [i], so these two forms are not the same.
1052    inline void
1053    check_range(int l, int r) const
1054    {
1055        if (l < r) {
1056            if ((l < 0) || (r >= nbits - 1))
1057                invalid_range(l, r);
1058        } else {
1059            if ((r < 0) || (l >= nbits - 1))
1060                invalid_range(l, r);
1061        }
1062    }
1063
1064    void invalid_range(int l, int r) const;
1065
1066    sc_unsigned_subref &
1067    range(int i, int j)
1068    {
1069        check_range(i, j);
1070        sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate();
1071        result_p->initialize(this, i, j);
1072        return *result_p;
1073    }
1074
1075    const sc_unsigned_subref_r &
1076    range(int i, int j) const
1077    {
1078        check_range(i, j);
1079        sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate();
1080        result_p->initialize(this, i, j);
1081        return *result_p;
1082    }
1083
1084    sc_unsigned_subref &
1085    operator () (int i, int j)
1086    {
1087        check_range(i,j);
1088        sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate();
1089        result_p->initialize(this, i, j);
1090        return *result_p;
1091    }
1092
1093    const sc_unsigned_subref_r &
1094    operator () (int i, int j) const
1095    {
1096        check_range(i,j);
1097        sc_unsigned_subref *result_p = sc_unsigned_subref::m_pool.allocate();
1098        result_p->initialize(this, i, j);
1099        return *result_p;
1100    }
1101
1102    // explicit conversions
1103    int to_int() const;
1104    unsigned int to_uint() const;
1105    long to_long() const;
1106    unsigned long to_ulong() const;
1107    int64 to_int64() const;
1108    uint64 to_uint64() const;
1109    double to_double() const;
1110
1111    // explicit conversion to character string
1112    const std::string to_string(sc_numrep numrep=SC_DEC) const;
1113    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
1114
1115    // Print functions. dump prints the internals of the class.
1116    void
1117    print(::std::ostream &os=::std::cout) const
1118    {
1119        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
1120    }
1121
1122    void scan(::std::istream &is=::std::cin);
1123    void dump(::std::ostream &os=::std::cout) const;
1124
1125    // Functions to find various properties.
1126    int length() const { return nbits - 1; } // Bit width.
1127    bool iszero() const; // Is the number zero?
1128    bool sign() const { return 0; } // Sign.
1129
1130    // reduce methods
1131    bool and_reduce() const;
1132    bool nand_reduce() const { return !and_reduce(); }
1133    bool or_reduce() const;
1134    bool nor_reduce() const { return !or_reduce(); }
1135    bool xor_reduce() const;
1136    bool xnor_reduce() const { return !xor_reduce(); }
1137
1138    // Functions to access individual bits.
1139    bool test(int i) const; // Is the ith bit 0 or 1?
1140    void set(int i); // Set the ith bit to 1.
1141    void clear(int i); // Set the ith bit to 0.
1142    void
1143    set(int i, bool v) // Set the ith bit to v.
1144    {
1145        if (v)
1146            set(i);
1147        else
1148            clear(i);
1149    }
1150    void
1151    invert(int i)           // Negate the ith bit.
1152    {
1153        if (test(i))
1154            clear(i);
1155        else
1156            set(i);
1157    }
1158
1159    // Make the number equal to its mirror image.
1160    void reverse();
1161
1162    // Get/set a packed bit representation of the number.
1163    void get_packed_rep(sc_digit *buf) const;
1164    void set_packed_rep(sc_digit *buf);
1165
1166    /*
1167      The comparison of the old and new semantics are as follows:
1168
1169      Let s = sc_signed,
1170          u = sc_unsigned,
1171          un = { uint64, unsigned long, unsigned int },
1172          sn = { int64, long, int, char* }, and
1173          OP = { +, -, *, /, % }.
1174
1175      Old semantics:                     New semantics:
1176        u OP u -> u                        u OP u -> u
1177        s OP u -> u                        s OP u -> s
1178        u OP s -> u                        u OP s -> s
1179        s OP s -> s                        s OP s -> s
1180
1181        u OP un = un OP u -> u             u OP un = un OP u -> u
1182        u OP sn = sn OP u -> u             u OP sn = sn OP u -> s
1183
1184        s OP un = un OP s -> s             s OP un = un OP s -> s
1185        s OP sn = sn OP s -> s             s OP sn = sn OP s -> s
1186
1187      In the new semantics, the result is u if both operands are u; the
1188      result is s otherwise. The only exception is subtraction. The result
1189      of a subtraction is always s.
1190
1191      The old semantics is like C/C++ semantics on integer types; the
1192      new semantics is due to the VSIA C/C++ data types standard.
1193    */
1194
1195    // ARITHMETIC OPERATORS:
1196
1197    // ADDition operators:
1198    friend sc_signed operator + (const sc_unsigned &u, const sc_signed &v);
1199    friend sc_signed operator + (const sc_signed &u, const sc_unsigned &v);
1200
1201    friend sc_unsigned operator + (const sc_unsigned &u, const sc_unsigned &v);
1202    friend sc_signed operator + (const sc_unsigned &u, int64 v);
1203    friend sc_unsigned operator + (const sc_unsigned &u, uint64 v);
1204    friend sc_signed operator + (const sc_unsigned &u, long v);
1205    friend sc_unsigned operator + (const sc_unsigned &u, unsigned long v);
1206    friend sc_signed operator + (const sc_unsigned &u, int v);
1207    friend sc_unsigned
1208    operator + (const sc_unsigned &u, unsigned int v)
1209    {
1210        return operator + (u, (unsigned long)v);
1211    }
1212
1213    friend sc_signed operator + (int64 u, const sc_unsigned &v);
1214    friend sc_unsigned operator + (uint64 u, const sc_unsigned &v);
1215    friend sc_signed operator + (long u, const sc_unsigned &v);
1216    friend sc_unsigned operator + (unsigned long u, const sc_unsigned &v);
1217    friend sc_signed operator + (int u, const sc_unsigned &v);
1218    friend sc_unsigned
1219    operator + (unsigned int u, const sc_unsigned &v)
1220    {
1221        return operator + ((unsigned long)u, v);
1222    }
1223
1224    const sc_unsigned &operator += (const sc_signed &v);
1225    const sc_unsigned &operator += (const sc_unsigned &v);
1226    const sc_unsigned &operator += (int64 v);
1227    const sc_unsigned &operator += (uint64 v);
1228    const sc_unsigned &operator += (long v);
1229    const sc_unsigned &operator += (unsigned long v);
1230    const sc_unsigned &
1231    operator += (int v)
1232    {
1233        return operator += ((long)v);
1234    }
1235    const sc_unsigned &
1236    operator += (unsigned int v)
1237    {
1238        return operator += ((unsigned long)v);
1239    }
1240
1241    friend sc_unsigned operator + (
1242            const sc_unsigned &u, const sc_uint_base &v);
1243    friend sc_signed operator + (const sc_unsigned &u, const sc_int_base &v);
1244    friend sc_unsigned operator + (
1245            const sc_uint_base &u, const sc_unsigned &v);
1246    friend sc_signed operator + (const sc_int_base &u, const sc_unsigned &v);
1247    const sc_unsigned &operator += (const sc_int_base &v);
1248    const sc_unsigned &operator += (const sc_uint_base &v);
1249
1250    // SUBtraction operators:
1251    friend sc_signed operator - (const sc_unsigned &u, const sc_signed &v);
1252    friend sc_signed operator - (const sc_signed &u, const sc_unsigned &v);
1253
1254    friend sc_signed operator - (const sc_unsigned &u, const sc_unsigned &v);
1255    friend sc_signed operator - (const sc_unsigned &u, int64 v);
1256    friend sc_signed operator - (const sc_unsigned &u, uint64 v);
1257    friend sc_signed operator - (const sc_unsigned &u, long v);
1258    friend sc_signed operator - (const sc_unsigned &u, unsigned long v);
1259    friend sc_signed operator - (const sc_unsigned &u, int v);
1260    friend sc_signed operator - (const sc_unsigned &u, unsigned int v);
1261
1262    friend sc_signed operator - (int64 u, const sc_unsigned &v);
1263    friend sc_signed operator - (uint64 u, const sc_unsigned &v);
1264    friend sc_signed operator - (long u, const sc_unsigned &v);
1265    friend sc_signed operator - (unsigned long u, const sc_unsigned &v);
1266    friend sc_signed operator - (int u, const sc_unsigned &v);
1267    friend sc_signed operator - (unsigned int u, const sc_unsigned &v);
1268
1269    const sc_unsigned &operator -= (const sc_signed &v);
1270    const sc_unsigned &operator -= (const sc_unsigned &v);
1271    const sc_unsigned &operator -= (int64 v);
1272    const sc_unsigned &operator -= (uint64 v);
1273    const sc_unsigned &operator -= (long v);
1274    const sc_unsigned &operator -= (unsigned long v);
1275    const sc_unsigned &
1276    operator -= (int v)
1277    {
1278        return operator -= ((long)v);
1279    }
1280    const sc_unsigned &
1281    operator -= (unsigned int v)
1282    {
1283        return operator -= ((unsigned long)v);
1284    }
1285
1286    friend sc_signed operator - (const sc_unsigned &u, const sc_uint_base &v);
1287    friend sc_signed operator - (const sc_unsigned &u, const sc_int_base &v);
1288    friend sc_signed operator - (const sc_uint_base &u, const sc_unsigned &v);
1289    friend sc_signed operator - (const sc_int_base &u, const sc_unsigned &v);
1290    const sc_unsigned &operator -= (const sc_int_base &v);
1291    const sc_unsigned &operator -= (const sc_uint_base &v);
1292
1293    // MULtiplication operators:
1294    friend sc_signed operator * (const sc_unsigned &u, const sc_signed &v);
1295    friend sc_signed operator * (const sc_signed &u, const sc_unsigned &v);
1296
1297    friend sc_unsigned operator * (const sc_unsigned &u, const sc_unsigned &v);
1298    friend sc_signed operator * (const sc_unsigned &u, int64 v);
1299    friend sc_unsigned operator * (const sc_unsigned &u, uint64 v);
1300    friend sc_signed operator * (const sc_unsigned &u, long v);
1301    friend sc_unsigned operator * (const sc_unsigned &u, unsigned long v);
1302    friend sc_signed operator * (const sc_unsigned &u, int v);
1303    friend sc_unsigned
1304    operator * (const sc_unsigned &u, unsigned int v)
1305    {
1306        return operator * (u, (unsigned long)v);
1307    }
1308
1309    friend sc_signed operator * (int64 u, const sc_unsigned &v);
1310    friend sc_unsigned operator * (uint64 u, const sc_unsigned &v);
1311    friend sc_signed operator * (long u, const sc_unsigned &v);
1312    friend sc_unsigned operator * (unsigned long u, const sc_unsigned &v);
1313    friend sc_signed operator * (int u, const sc_unsigned &v);
1314    friend sc_unsigned
1315    operator * (unsigned int u, const sc_unsigned &v)
1316    {
1317        return operator * ((unsigned long)u, v);
1318    }
1319
1320    const sc_unsigned &operator *= (const sc_signed &v);
1321    const sc_unsigned &operator *= (const sc_unsigned &v);
1322    const sc_unsigned &operator *= (int64 v);
1323    const sc_unsigned &operator *= (uint64 v);
1324    const sc_unsigned &operator *= (long v);
1325    const sc_unsigned &operator *= (unsigned long v);
1326    const sc_unsigned &operator *= (int v) { return operator *= ((long)v); }
1327    const sc_unsigned &
1328    operator *= (unsigned int v)
1329    {
1330        return operator *= ((unsigned long)v);
1331    }
1332
1333    friend sc_unsigned operator * (
1334            const sc_unsigned &u, const sc_uint_base &v);
1335    friend sc_signed operator * (const sc_unsigned &u, const sc_int_base &v);
1336    friend sc_unsigned operator * (
1337            const sc_uint_base &u, const sc_unsigned &v);
1338    friend sc_signed operator * (const sc_int_base &u, const sc_unsigned &v);
1339    const sc_unsigned &operator *= (const sc_int_base &v);
1340    const sc_unsigned &operator *= (const sc_uint_base &v);
1341
1342    // DIVision operators:
1343    friend sc_signed operator / (const sc_unsigned &u, const sc_signed &v);
1344    friend sc_signed operator / (const sc_signed &u, const sc_unsigned &v);
1345
1346    friend sc_unsigned operator / (const sc_unsigned &u, const sc_unsigned &v);
1347    friend sc_signed operator / (const sc_unsigned &u, int64 v);
1348    friend sc_unsigned operator / (const sc_unsigned &u, uint64 v);
1349    friend sc_signed operator / (const sc_unsigned &u, long v);
1350    friend sc_unsigned operator / (const sc_unsigned &u, unsigned long v);
1351    friend sc_signed operator / (const sc_unsigned &u, int v);
1352    friend sc_unsigned
1353    operator / (const sc_unsigned &u, unsigned int v)
1354    {
1355        return operator / (u, (unsigned long)v);
1356    }
1357
1358    friend sc_signed operator / (int64 u, const sc_unsigned &v);
1359    friend sc_unsigned operator / (uint64 u, const sc_unsigned &v);
1360    friend sc_signed operator / (long u, const sc_unsigned &v);
1361    friend sc_unsigned operator / (unsigned long u, const sc_unsigned &v);
1362    friend sc_signed operator / (int u, const sc_unsigned &v);
1363    friend sc_unsigned
1364    operator / (unsigned int u, const sc_unsigned &v)
1365    {
1366        return operator / ((unsigned long)u, v);
1367    }
1368
1369    const sc_unsigned &operator /= (const sc_signed &v);
1370    const sc_unsigned &operator /= (const sc_unsigned &v);
1371    const sc_unsigned &operator /= (int64 v);
1372    const sc_unsigned &operator /= (uint64 v);
1373    const sc_unsigned &operator /= (long v);
1374    const sc_unsigned &operator /= (unsigned long v);
1375    const sc_unsigned &operator /= (int v) { return operator /= ((long)v); }
1376    const sc_unsigned &
1377    operator /= (unsigned int v)
1378    {
1379        return operator /= ((unsigned long)v);
1380    }
1381
1382    friend sc_unsigned operator / (
1383            const sc_unsigned &u, const sc_uint_base &v);
1384    friend sc_signed operator / (const sc_unsigned &u, const sc_int_base &v);
1385    friend sc_unsigned operator / (
1386            const sc_uint_base &u, const sc_unsigned &v);
1387    friend sc_signed operator / (const sc_int_base &u, const sc_unsigned &v);
1388    const sc_unsigned &operator /= (const sc_int_base &v);
1389    const sc_unsigned &operator /= (const sc_uint_base &v);
1390
1391    // MODulo operators:
1392    friend sc_signed operator % (const sc_unsigned &u, const sc_signed &v);
1393    friend sc_signed operator % (const sc_signed &u, const sc_unsigned &v);
1394
1395    friend sc_unsigned operator % (const sc_unsigned &u, const sc_unsigned &v);
1396    friend sc_signed operator % (const sc_unsigned &u, int64 v);
1397    friend sc_unsigned operator % (const sc_unsigned &u, uint64 v);
1398    friend sc_signed operator % (const sc_unsigned &u, long v);
1399    friend sc_unsigned operator % (const sc_unsigned &u, unsigned long v);
1400    friend sc_signed operator % (const sc_unsigned &u, int v);
1401    friend sc_unsigned
1402    operator % (const sc_unsigned &u, unsigned int v)
1403    {
1404        return operator % (u, (unsigned long)v);
1405    }
1406
1407    friend sc_signed operator % (int64 u, const sc_unsigned &v);
1408    friend sc_unsigned operator % (uint64 u, const sc_unsigned &v);
1409    friend sc_signed operator % (long u, const sc_unsigned &v);
1410    friend sc_unsigned operator % (unsigned long u, const sc_unsigned &v);
1411    friend sc_signed operator % (int u, const sc_unsigned &v);
1412    friend sc_unsigned
1413    operator % (unsigned int u, const sc_unsigned &v)
1414    {
1415        return operator % ((unsigned long)u, v);
1416    }
1417
1418    const sc_unsigned &operator %= (const sc_signed &v);
1419    const sc_unsigned &operator %= (const sc_unsigned &v);
1420    const sc_unsigned &operator %= (int64 v);
1421    const sc_unsigned &operator %= (uint64 v);
1422    const sc_unsigned &operator %= (long v);
1423    const sc_unsigned &operator %= (unsigned long v);
1424    const sc_unsigned &operator %= (int v) { return operator %= ((long)v); }
1425    const sc_unsigned &
1426    operator %= (unsigned int v)
1427    {
1428        return operator %= ((unsigned long)v);
1429    }
1430
1431    friend sc_unsigned operator % (
1432            const sc_unsigned &u, const sc_uint_base &v);
1433    friend sc_signed operator % (const sc_unsigned &u, const sc_int_base &v);
1434    friend sc_unsigned operator % (
1435            const sc_uint_base &u, const sc_unsigned &v);
1436    friend sc_signed operator % (const sc_int_base &u, const sc_unsigned &v);
1437    const sc_unsigned &operator %= (const sc_int_base &v);
1438    const sc_unsigned &operator %= (const sc_uint_base &v);
1439
1440    // BITWISE OPERATORS:
1441
1442    // Bitwise AND operators:
1443    friend sc_signed operator & (const sc_unsigned &u, const sc_signed &v);
1444    friend sc_signed operator & (const sc_signed &u, const sc_unsigned &v);
1445
1446    friend sc_unsigned operator & (const sc_unsigned &u, const sc_unsigned &v);
1447    friend sc_signed operator & (const sc_unsigned &u, int64 v);
1448    friend sc_unsigned operator & (const sc_unsigned &u, uint64 v);
1449    friend sc_signed operator & (const sc_unsigned &u, long v);
1450    friend sc_unsigned operator & (const sc_unsigned &u, unsigned long v);
1451    friend sc_signed operator & (const sc_unsigned &u, int v);
1452    friend sc_unsigned
1453    operator & (const sc_unsigned &u, unsigned int v)
1454    {
1455        return operator & (u, (unsigned long)v);
1456    }
1457
1458    friend sc_signed operator & (int64 u, const sc_unsigned &v);
1459    friend sc_unsigned operator & (uint64 u, const sc_unsigned &v);
1460    friend sc_signed operator & (long u, const sc_unsigned &v);
1461    friend sc_unsigned operator & (unsigned long u, const sc_unsigned &v);
1462    friend sc_signed operator & (int u, const sc_unsigned &v);
1463    friend sc_unsigned
1464    operator & (unsigned int u, const sc_unsigned &v)
1465    {
1466        return operator & ((unsigned long)u, v);
1467    }
1468
1469    const sc_unsigned &operator &= (const sc_signed &v);
1470    const sc_unsigned &operator &= (const sc_unsigned &v);
1471    const sc_unsigned &operator &= (int64 v);
1472    const sc_unsigned &operator &= (uint64 v);
1473    const sc_unsigned &operator &= (long v);
1474    const sc_unsigned &operator &= (unsigned long v);
1475    const sc_unsigned &operator &= (int v) { return operator&=((long) v); }
1476    const sc_unsigned &
1477    operator &= (unsigned int v)
1478    {
1479        return operator &= ((unsigned long)v);
1480    }
1481
1482    friend sc_unsigned operator & (
1483            const sc_unsigned &u, const sc_uint_base &v);
1484    friend sc_signed operator & (const sc_unsigned &u, const sc_int_base &v);
1485    friend sc_unsigned operator & (
1486            const sc_uint_base &u, const sc_unsigned &v);
1487    friend sc_signed operator & (const sc_int_base &u, const sc_unsigned &v);
1488    const sc_unsigned &operator &= (const sc_int_base &v);
1489    const sc_unsigned &operator &= (const sc_uint_base &v);
1490
1491    // Bitwise OR operators:
1492    friend sc_signed operator | (const sc_unsigned &u, const sc_signed &v);
1493    friend sc_signed operator | (const sc_signed &u, const sc_unsigned &v);
1494
1495    friend sc_unsigned operator | (const sc_unsigned &u, const sc_unsigned &v);
1496    friend sc_signed operator | (const sc_unsigned &u, int64 v);
1497    friend sc_unsigned operator | (const sc_unsigned &u, uint64 v);
1498    friend sc_signed operator | (const sc_unsigned &u, long v);
1499    friend sc_unsigned operator | (const sc_unsigned &u, unsigned long v);
1500    friend sc_signed operator | (const sc_unsigned &u, int v);
1501    friend sc_unsigned
1502    operator | (const sc_unsigned &u, unsigned int v)
1503    {
1504        return operator | (u, (unsigned long)v);
1505    }
1506
1507    friend sc_signed operator | (int64 u, const sc_unsigned &v);
1508    friend sc_unsigned operator | (uint64 u, const sc_unsigned &v);
1509    friend sc_signed operator | (long u, const sc_unsigned &v);
1510    friend sc_unsigned operator | (unsigned long u, const sc_unsigned &v);
1511    friend sc_signed operator | (int u, const sc_unsigned &v);
1512    friend sc_unsigned
1513    operator | (unsigned int u, const sc_unsigned &v)
1514    {
1515        return operator | ((unsigned long)u, v);
1516    }
1517
1518    const sc_unsigned &operator |= (const sc_signed &v);
1519    const sc_unsigned &operator |= (const sc_unsigned &v);
1520    const sc_unsigned &operator |= (int64 v);
1521    const sc_unsigned &operator |= (uint64 v);
1522    const sc_unsigned &operator |= (long v);
1523    const sc_unsigned &operator |= (unsigned long v);
1524    const sc_unsigned &operator |= (int v) { return operator|=((long) v); }
1525    const sc_unsigned &
1526    operator |= (unsigned int v)
1527    {
1528        return operator |= ((unsigned long)v);
1529    }
1530
1531    friend sc_unsigned operator | (
1532            const sc_unsigned &u, const sc_uint_base &v);
1533    friend sc_signed operator | (const sc_unsigned &u, const sc_int_base &v);
1534    friend sc_unsigned operator | (
1535            const sc_uint_base &u, const sc_unsigned &v);
1536    friend sc_signed operator | (const sc_int_base &u, const sc_unsigned &v);
1537    const sc_unsigned &operator |= (const sc_int_base &v);
1538    const sc_unsigned &operator |= (const sc_uint_base &v);
1539
1540    // Bitwise XOR operators:
1541    friend sc_signed operator ^ (const sc_unsigned &u, const sc_signed &v);
1542    friend sc_signed operator ^ (const sc_signed &u, const sc_unsigned &v);
1543
1544    friend sc_unsigned operator ^ (const sc_unsigned &u, const sc_unsigned &v);
1545    friend sc_signed operator ^ (const sc_unsigned &u, int64 v);
1546    friend sc_unsigned operator ^ (const sc_unsigned &u, uint64 v);
1547    friend sc_signed operator ^ (const sc_unsigned &u, long v);
1548    friend sc_unsigned operator ^ (const sc_unsigned &u, unsigned long v);
1549    friend sc_signed operator ^ (const sc_unsigned &u, int v);
1550    friend sc_unsigned
1551    operator ^ (const sc_unsigned &u, unsigned int v)
1552    {
1553        return operator ^ (u, (unsigned long)v);
1554    }
1555
1556    friend sc_signed operator ^ (int64 u, const sc_unsigned &v);
1557    friend sc_unsigned operator ^ (uint64 u, const sc_unsigned &v);
1558    friend sc_signed operator ^ (long u, const sc_unsigned &v);
1559    friend sc_unsigned operator ^ (unsigned long u, const sc_unsigned &v);
1560    friend sc_signed operator ^ (int u, const sc_unsigned &v);
1561    friend sc_unsigned
1562    operator ^ (unsigned int u, const sc_unsigned &v)
1563    {
1564        return operator ^ ((unsigned long)u, v);
1565    }
1566
1567    const sc_unsigned &operator ^= (const sc_signed &v);
1568    const sc_unsigned &operator ^= (const sc_unsigned &v);
1569    const sc_unsigned &operator ^= (int64 v);
1570    const sc_unsigned &operator ^= (uint64 v);
1571    const sc_unsigned &operator ^= (long v);
1572    const sc_unsigned &operator ^= (unsigned long v);
1573    const sc_unsigned &
1574    operator ^= (int v)
1575    {
1576        return operator ^= ((long)v);
1577    }
1578    const sc_unsigned &
1579    operator ^= (unsigned int v)
1580    {
1581        return operator ^= ((unsigned long)v);
1582    }
1583
1584    friend sc_unsigned operator ^ (
1585            const sc_unsigned &u, const sc_uint_base &v);
1586    friend sc_signed operator ^ (const sc_unsigned &u, const sc_int_base &v);
1587    friend sc_unsigned operator ^ (
1588            const sc_uint_base &u, const sc_unsigned &v);
1589    friend sc_signed operator ^ (const sc_int_base &u, const sc_unsigned &v);
1590    const sc_unsigned &operator ^= (const sc_int_base &v);
1591    const sc_unsigned &operator ^= (const sc_uint_base &v);
1592
1593    // SHIFT OPERATORS:
1594
1595    // LEFT SHIFT operators:
1596    friend sc_unsigned operator << (const sc_unsigned &u, const sc_signed &v);
1597    friend sc_signed operator << (const sc_signed &u, const sc_unsigned &v);
1598
1599    friend sc_unsigned operator << (
1600            const sc_unsigned &u, const sc_unsigned &v);
1601    friend sc_unsigned operator << (const sc_unsigned &u, int64 v);
1602    friend sc_unsigned operator << (const sc_unsigned &u, uint64 v);
1603    friend sc_unsigned operator << (const sc_unsigned &u, long v);
1604    friend sc_unsigned operator << (const sc_unsigned &u, unsigned long v);
1605    friend sc_unsigned
1606    operator << (const sc_unsigned &u, int v)
1607    {
1608        return operator << (u, (long)v);
1609    }
1610    friend sc_unsigned
1611    operator << (const sc_unsigned &u, unsigned int v)
1612    {
1613        return operator << (u, (unsigned long)v);
1614    }
1615
1616    const sc_unsigned &operator <<= (const sc_signed &v);
1617    const sc_unsigned &operator <<= (const sc_unsigned &v);
1618    const sc_unsigned &operator <<= (int64 v);
1619    const sc_unsigned &operator <<= (uint64 v);
1620    const sc_unsigned &operator <<= (long v);
1621    const sc_unsigned &operator <<= (unsigned long v);
1622    const sc_unsigned &operator <<= (int v) { return operator <<= ((long)v); }
1623    const sc_unsigned &
1624    operator <<= (unsigned int v)
1625    {
1626        return operator <<= ((unsigned long)v);
1627    }
1628
1629    friend sc_unsigned operator << (
1630            const sc_unsigned &u, const sc_uint_base &v);
1631    friend sc_unsigned operator << (
1632            const sc_unsigned &u, const sc_int_base &v);
1633    const sc_unsigned &operator <<= (const sc_int_base &v);
1634    const sc_unsigned &operator <<= (const sc_uint_base &v);
1635
1636    // RIGHT SHIFT operators:
1637    friend sc_unsigned operator >> (const sc_unsigned &u, const sc_signed &v);
1638    friend sc_signed operator >> (const sc_signed &u, const sc_unsigned &v);
1639
1640    friend sc_unsigned operator >> (
1641            const sc_unsigned &u, const sc_unsigned &v);
1642    friend sc_unsigned operator >> (const sc_unsigned &u, int64 v);
1643    friend sc_unsigned operator >> (const sc_unsigned &u, uint64 v);
1644    friend sc_unsigned operator >> (const sc_unsigned &u, long v);
1645    friend sc_unsigned operator >> (const sc_unsigned &u, unsigned long v);
1646    friend sc_unsigned
1647    operator >> (const sc_unsigned &u, int v)
1648    {
1649        return operator >> (u, (long)v);
1650    }
1651    friend sc_unsigned
1652    operator >> (const sc_unsigned &u, unsigned int v)
1653    {
1654        return operator >> (u, (unsigned long)v);
1655    }
1656
1657    const sc_unsigned &operator >>= (const sc_signed &v);
1658    const sc_unsigned &operator >>= (const sc_unsigned &v);
1659    const sc_unsigned &operator >>= (int64 v);
1660    const sc_unsigned &operator >>= (uint64 v);
1661    const sc_unsigned &operator >>= (long v);
1662    const sc_unsigned &operator >>= (unsigned long v);
1663    const sc_unsigned &operator >>= (int v) { return operator >>= ((long)v); }
1664    const sc_unsigned &
1665    operator >>= (unsigned int v)
1666    {
1667        return operator >>= ((unsigned long)v);
1668    }
1669
1670    friend sc_unsigned operator >> (const sc_unsigned &, const sc_uint_base &);
1671    friend sc_unsigned operator >> (const sc_unsigned&, const sc_int_base &);
1672    const sc_unsigned &operator >>= (const sc_int_base &v);
1673    const sc_unsigned &operator >>= (const sc_uint_base &v);
1674
1675    // Unary arithmetic operators
1676    friend sc_unsigned operator + (const sc_unsigned &u);
1677    friend sc_signed operator - (const sc_unsigned &u);
1678
1679    // LOGICAL OPERATORS:
1680
1681    // Logical EQUAL operators:
1682    friend bool operator == (const sc_unsigned &u, const sc_signed &v);
1683    friend bool operator == (const sc_signed &u, const sc_unsigned &v);
1684
1685    friend bool operator == (const sc_unsigned &u, const sc_unsigned &v);
1686    friend bool operator == (const sc_unsigned &u, int64 v);
1687    friend bool operator == (const sc_unsigned &u, uint64 v);
1688    friend bool operator == (const sc_unsigned &u, long v);
1689    friend bool operator == (const sc_unsigned &u, unsigned long v);
1690    friend bool
1691    operator == (const sc_unsigned &u, int v)
1692    {
1693        return operator == (u, (long)v);
1694    }
1695    friend bool
1696    operator == (const sc_unsigned &u, unsigned int v)
1697    {
1698        return operator == (u, (unsigned long)v);
1699    }
1700
1701    friend bool operator == (int64 u, const sc_unsigned &v);
1702    friend bool operator == (uint64 u, const sc_unsigned &v);
1703    friend bool operator == (long u, const sc_unsigned &v);
1704    friend bool operator == (unsigned long u, const sc_unsigned &v);
1705    friend bool
1706    operator == (int u, const sc_unsigned &v)
1707    {
1708        return operator == ((long)u, v);
1709    }
1710    friend bool
1711    operator == (unsigned int u, const sc_unsigned &v)
1712    {
1713        return operator == ((unsigned long)u, v);
1714    }
1715
1716    friend bool operator == (const sc_unsigned &u, const sc_uint_base &v);
1717    friend bool operator == (const sc_unsigned &u, const sc_int_base &v);
1718    friend bool operator == (const sc_uint_base &u, const sc_unsigned &v);
1719    friend bool operator == (const sc_int_base &u, const sc_unsigned &v);
1720
1721    // Logical NOT_EQUAL operators:
1722    friend bool operator != (const sc_unsigned &u, const sc_signed &v);
1723    friend bool operator != (const sc_signed &u, const sc_unsigned &v);
1724
1725    friend bool operator != (const sc_unsigned &u, const sc_unsigned &v);
1726    friend bool operator != (const sc_unsigned &u, int64 v);
1727    friend bool operator != (const sc_unsigned &u, uint64 v);
1728    friend bool operator != (const sc_unsigned &u, long v);
1729    friend bool operator != (const sc_unsigned &u, unsigned long v);
1730    friend bool
1731    operator != (const sc_unsigned &u, int v)
1732    {
1733        return operator != (u, (long)v);
1734    }
1735    friend bool
1736    operator != (const sc_unsigned &u, unsigned int v)
1737    {
1738        return operator != (u, (unsigned long)v);
1739    }
1740
1741    friend bool operator != (int64 u, const sc_unsigned &v);
1742    friend bool operator != (uint64 u, const sc_unsigned &v);
1743    friend bool operator != (long u, const sc_unsigned &v);
1744    friend bool operator != (unsigned long u, const sc_unsigned &v);
1745    friend bool
1746    operator != (int u, const sc_unsigned &v)
1747    {
1748        return operator != ((long)u, v);
1749    }
1750    friend bool
1751    operator != (unsigned int u, const sc_unsigned &v)
1752    {
1753        return operator != ((unsigned long)u, v);
1754    }
1755
1756    friend bool operator != (const sc_unsigned &u, const sc_uint_base &v);
1757    friend bool operator != (const sc_unsigned &u, const sc_int_base &v);
1758    friend bool operator != (const sc_uint_base &u, const sc_unsigned &v);
1759    friend bool operator != (const sc_int_base &u, const sc_unsigned &v);
1760
1761    // Logical LESS_THAN operators:
1762    friend bool operator < (const sc_unsigned &u, const sc_signed &v);
1763    friend bool operator < (const sc_signed &u, const sc_unsigned &v);
1764
1765    friend bool operator < (const sc_unsigned &u, const sc_unsigned &v);
1766    friend bool operator < (const sc_unsigned &u, int64 v);
1767    friend bool operator < (const sc_unsigned &u, uint64 v);
1768    friend bool operator < (const sc_unsigned &u, long v);
1769    friend bool operator < (const sc_unsigned &u, unsigned long v);
1770    friend bool
1771    operator < (const sc_unsigned &u, int v)
1772    {
1773        return operator < (u, (long)v);
1774    }
1775    friend bool
1776    operator < (const sc_unsigned &u, unsigned int v)
1777    {
1778        return operator < (u, (unsigned long)v);
1779    }
1780
1781    friend bool operator < (int64 u, const sc_unsigned &v);
1782    friend bool operator < (uint64 u, const sc_unsigned &v);
1783    friend bool operator < (long u, const sc_unsigned &v);
1784    friend bool operator < (unsigned long u, const sc_unsigned &v);
1785    friend bool
1786    operator < (int u, const sc_unsigned &v)
1787    {
1788        return operator < ((long)u, v);
1789    }
1790    friend bool
1791    operator < (unsigned int u, const sc_unsigned &v)
1792    {
1793        return operator < ((unsigned long)u, v);
1794    }
1795
1796    friend bool operator < (const sc_unsigned &u, const sc_uint_base &v);
1797    friend bool operator < (const sc_unsigned &u, const sc_int_base &v);
1798    friend bool operator < (const sc_uint_base &u, const sc_unsigned &v);
1799    friend bool operator < (const sc_int_base &u, const sc_unsigned &v);
1800
1801    // Logical LESS_THAN_AND_EQUAL operators:
1802    friend bool operator <= (const sc_unsigned &u, const sc_signed &v);
1803    friend bool operator <= (const sc_signed &u, const sc_unsigned &v);
1804
1805    friend bool operator <= (const sc_unsigned &u, const sc_unsigned &v);
1806    friend bool operator <= (const sc_unsigned &u, int64 v);
1807    friend bool operator <= (const sc_unsigned &u, uint64 v);
1808    friend bool operator <= (const sc_unsigned &u, long v);
1809    friend bool operator <= (const sc_unsigned &u, unsigned long v);
1810    friend bool
1811    operator <= (const sc_unsigned &u, int v)
1812    {
1813        return operator <= (u, (long)v);
1814    }
1815    friend bool
1816    operator <= (const sc_unsigned &u, unsigned int v)
1817    {
1818        return operator <= (u, (unsigned long)v);
1819    }
1820
1821    friend bool operator <= (int64 u, const sc_unsigned &v);
1822    friend bool operator <= (uint64 u, const sc_unsigned &v);
1823    friend bool operator <= (long u, const sc_unsigned &v);
1824    friend bool operator <= (unsigned long u, const sc_unsigned &v);
1825    friend bool
1826    operator <= (int u, const sc_unsigned &v)
1827    {
1828        return operator <= ((long)u, v);
1829    }
1830    friend bool
1831    operator <= (unsigned int u, const sc_unsigned &v)
1832    {
1833        return operator <= ((unsigned long)u, v);
1834    }
1835
1836    friend bool operator <= (const sc_unsigned &u, const sc_uint_base &v);
1837    friend bool operator <= (const sc_unsigned &u, const sc_int_base &v);
1838    friend bool operator <= (const sc_uint_base &u, const sc_unsigned &v);
1839    friend bool operator <= (const sc_int_base &u, const sc_unsigned &v);
1840
1841    // Logical GREATER_THAN operators:
1842    friend bool operator > (const sc_unsigned &u, const sc_signed &v);
1843    friend bool operator > (const sc_signed &u, const sc_unsigned &v);
1844
1845    friend bool operator > (const sc_unsigned &u, const sc_unsigned &v);
1846    friend bool operator > (const sc_unsigned &u, int64 v);
1847    friend bool operator > (const sc_unsigned &u, uint64 v);
1848    friend bool operator > (const sc_unsigned &u, long v);
1849    friend bool operator > (const sc_unsigned &u, unsigned long v);
1850    friend bool
1851    operator > (const sc_unsigned &u, int v)
1852    {
1853        return operator > (u, (long)v);
1854    }
1855    friend bool
1856    operator > (const sc_unsigned &u, unsigned int v)
1857    {
1858        return operator > (u, (unsigned long)v);
1859    }
1860
1861    friend bool operator > (int64 u, const sc_unsigned &v);
1862    friend bool operator > (uint64 u, const sc_unsigned &v);
1863    friend bool operator > (long u, const sc_unsigned &v);
1864    friend bool operator > (unsigned long u, const sc_unsigned &v);
1865    friend bool
1866    operator > (int u, const sc_unsigned &v)
1867    {
1868        return operator > ((long)u, v);
1869    }
1870    friend bool
1871    operator > (unsigned int u, const sc_unsigned &v)
1872    {
1873        return operator > ((unsigned long)u, v);
1874    }
1875
1876    friend bool operator > (const sc_unsigned &u, const sc_uint_base &v);
1877    friend bool operator > (const sc_unsigned &u, const sc_int_base &v);
1878    friend bool operator > (const sc_uint_base &u, const sc_unsigned &v);
1879    friend bool operator > (const sc_int_base &u, const sc_unsigned &v);
1880
1881    // Logical GREATER_THAN_AND_EQUAL operators:
1882    friend bool operator >= (const sc_unsigned &u, const sc_signed &v);
1883    friend bool operator >= (const sc_signed &u, const sc_unsigned &v);
1884
1885    friend bool operator >= (const sc_unsigned &u, const sc_unsigned &v);
1886    friend bool operator >= (const sc_unsigned &u, int64 v);
1887    friend bool operator >= (const sc_unsigned &u, uint64 v);
1888    friend bool operator >= (const sc_unsigned &u, long v);
1889    friend bool operator >= (const sc_unsigned &u, unsigned long v);
1890    friend bool
1891    operator >= (const sc_unsigned &u, int v)
1892    {
1893        return operator >= (u, (long)v);
1894    }
1895    friend bool
1896    operator >= (const sc_unsigned &u, unsigned int v)
1897    {
1898        return operator >= (u, (unsigned long)v);
1899    }
1900
1901    friend bool operator >= (int64 u, const sc_unsigned &v);
1902    friend bool operator >= (uint64 u, const sc_unsigned &v);
1903    friend bool operator >= (long u, const sc_unsigned &v);
1904    friend bool operator >= (unsigned long u, const sc_unsigned &v);
1905    friend bool
1906    operator >= (int u, const sc_unsigned &v)
1907    {
1908        return operator >= ((long)u, v);
1909    }
1910    friend bool
1911    operator >= (unsigned int u, const sc_unsigned &v)
1912    {
1913        return operator >= ((unsigned long)u, v);
1914    }
1915
1916    friend bool operator >= (const sc_unsigned &u, const sc_uint_base &v);
1917    friend bool operator >= (const sc_unsigned &u, const sc_int_base &v);
1918    friend bool operator >= (const sc_uint_base &u, const sc_unsigned &v);
1919    friend bool operator >= (const sc_int_base &u, const sc_unsigned &v);
1920
1921    // Bitwise NOT operator (unary).
1922    friend sc_unsigned operator ~ (const sc_unsigned &u);
1923
1924    // Helper functions.
1925    friend int compare_unsigned(
1926            small_type us, int unb, int und, const sc_digit *ud,
1927            small_type vs, int vnb, int vnd, const sc_digit *vd,
1928            small_type if_u_signed, small_type if_v_signed);
1929
1930    friend sc_unsigned add_unsigned_friend(
1931            small_type us, int unb, int und, const sc_digit *ud,
1932            small_type vs, int vnb, int vnd, const sc_digit *vd);
1933
1934    friend sc_unsigned sub_unsigned_friend(
1935            small_type us, int unb, int und, const sc_digit *ud,
1936            small_type vs, int vnb, int vnd, const sc_digit *vd);
1937
1938    friend sc_unsigned mul_unsigned_friend(
1939            small_type s, int unb, int und, const sc_digit *ud,
1940            int vnb, int vnd, const sc_digit *vd);
1941
1942    friend sc_unsigned div_unsigned_friend(
1943            small_type s, int unb, int und, const sc_digit *ud,
1944            int vnb, int vnd, const sc_digit *vd);
1945
1946    friend sc_unsigned mod_unsigned_friend(
1947            small_type us, int unb, int und, const sc_digit *ud,
1948            int vnb, int vnd, const sc_digit *vd);
1949
1950    friend sc_unsigned and_unsigned_friend(
1951            small_type us, int unb, int und, const sc_digit *ud,
1952            small_type vs, int vnb, int vnd, const sc_digit *vd);
1953
1954    friend sc_unsigned or_unsigned_friend(
1955            small_type us, int unb, int und, const sc_digit *ud,
1956            small_type vs, int vnb, int vnd, const sc_digit *vd);
1957
1958    friend sc_unsigned xor_unsigned_friend(
1959            small_type us, int unb, int und, const sc_digit *ud,
1960            small_type vs, int vnb, int vnd, const sc_digit *vd);
1961
1962  public:
1963    static sc_core::sc_vpool<sc_unsigned> m_pool;
1964
1965  private:
1966    small_type sgn; // Shortened as s.
1967    int nbits; // Shortened as nb.
1968    int ndigits; // Shortened as nd.
1969
1970#ifdef SC_MAX_NBITS
1971    sc_digit digit[DIV_CEIL(SC_MAX_NBITS)]; // Shortened as d.
1972#else
1973    sc_digit *digit; // Shortened as d.
1974#endif
1975
1976    // Private constructors:
1977
1978    // Create a copy of v with sign s.
1979    sc_unsigned(const sc_unsigned &v, small_type s);
1980    sc_unsigned(const sc_signed &v, small_type s);
1981
1982    // Create an unsigned number with the given attributes.
1983    sc_unsigned(small_type s, int nb, int nd, sc_digit *d, bool alloc=true);
1984
1985    // Create an unsigned number using the bits u[l..r].
1986    sc_unsigned(const sc_signed *u, int l, int r);
1987    sc_unsigned(const sc_unsigned *u, int l, int r);
1988
1989    // Private member functions. The called functions are inline functions.
1990
1991    small_type default_sign() const { return SC_POS; }
1992
1993    int num_bits(int nb) const { return nb + 1; }
1994
1995    bool check_if_outside(int bit_num) const;
1996
1997    void
1998    copy_digits(int nb, int nd, const sc_digit *d)
1999    {
2000        copy_digits_unsigned(sgn, nbits, ndigits, digit, nb, nd, d);
2001    }
2002
2003    void makezero() { sgn = make_zero(ndigits, digit); }
2004
2005    // Conversion functions between 2's complement (2C) and
2006    // sign-magnitude (SM):
2007    void
2008    convert_2C_to_SM()
2009    {
2010        sgn = convert_unsigned_2C_to_SM(nbits, ndigits, digit);
2011    }
2012
2013    void
2014    convert_SM_to_2C_to_SM()
2015    {
2016        sgn = convert_unsigned_SM_to_2C_to_SM(sgn, nbits, ndigits, digit);
2017    }
2018
2019    void convert_SM_to_2C() { convert_unsigned_SM_to_2C(sgn, ndigits, digit); }
2020};
2021
2022inline ::std::ostream &operator << (::std::ostream &, const sc_unsigned &);
2023
2024inline ::std::istream &operator >> (::std::istream &, sc_unsigned &);
2025
2026
2027// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
2028
2029// ----------------------------------------------------------------------------
2030//  CLASS : sc_unsigned_bitref_r
2031//
2032//  Proxy class for sc_unsigned bit selection (r-value only).
2033// ----------------------------------------------------------------------------
2034
2035
2036inline ::std::ostream &
2037operator << (::std::ostream &os, const sc_unsigned_bitref_r &a)
2038{
2039    a.print(os);
2040    return os;
2041}
2042
2043
2044// ----------------------------------------------------------------------------
2045//  CLASS : sc_unsigned_bitref
2046//
2047//  Proxy class for sc_unsigned bit selection (r-value and l-value).
2048// ----------------------------------------------------------------------------
2049
2050template<class T>
2051inline const sc_unsigned_subref &
2052sc_unsigned_subref::operator = (const sc_generic_base<T> &a)
2053{
2054    sc_unsigned temp(length());
2055    a->to_sc_unsigned(temp);
2056    return *this = temp;
2057}
2058
2059inline ::std::istream &
2060operator >> (::std::istream &is, sc_unsigned_bitref &a)
2061{
2062    a.scan(is);
2063    return is;
2064}
2065
2066
2067// ----------------------------------------------------------------------------
2068//  CLASS : sc_unsigned_subref_r
2069//
2070//  Proxy class for sc_unsigned part selection (r-value only).
2071// ----------------------------------------------------------------------------
2072
2073// reduce methods
2074
2075inline bool
2076sc_unsigned_subref_r::and_reduce() const
2077{
2078    const sc_unsigned *target_p = m_obj_p;
2079    for (int i = m_right; i <= m_left; i++)
2080        if (!target_p->test(i))
2081            return false;
2082    return true;
2083}
2084
2085inline bool
2086sc_unsigned_subref_r::nand_reduce() const
2087{
2088    return !and_reduce();
2089}
2090
2091inline bool
2092sc_unsigned_subref_r::or_reduce() const
2093{
2094    const sc_unsigned *target_p = m_obj_p;
2095    for (int i = m_right; i <= m_left; i++)
2096        if (target_p->test(i))
2097            return true;
2098    return false;
2099}
2100
2101inline bool
2102sc_unsigned_subref_r::nor_reduce() const
2103{
2104    return !or_reduce();
2105}
2106
2107inline bool
2108sc_unsigned_subref_r::xor_reduce() const
2109{
2110    int odd;
2111    const sc_unsigned *target_p = m_obj_p;
2112    odd = 0;
2113    for (int i = m_right; i <= m_left; i++)
2114        if (target_p->test(i)) odd = ~odd;
2115    return odd ? true : false;
2116}
2117
2118inline bool sc_unsigned_subref_r::xnor_reduce() const { return !xor_reduce(); }
2119
2120inline ::std::ostream &
2121operator << (::std::ostream &os, const sc_unsigned_subref_r &a)
2122{
2123    a.print(os);
2124    return os;
2125}
2126
2127
2128// ----------------------------------------------------------------------------
2129//  CLASS : sc_unsigned_subref
2130//
2131//  Proxy class for sc_unsigned part selection (r-value and l-value).
2132// ----------------------------------------------------------------------------
2133
2134// assignment operators
2135
2136inline const sc_unsigned_subref &
2137sc_unsigned_subref::operator = (const char *a)
2138{
2139    sc_unsigned aa(length());
2140    return (*this = aa = a);
2141}
2142
2143
2144inline ::std::istream &
2145operator >> (::std::istream &is, sc_unsigned_subref &a)
2146{
2147    a.scan(is);
2148    return is;
2149}
2150
2151
2152// ----------------------------------------------------------------------------
2153//  CLASS : sc_unsigned
2154//
2155//  Arbitrary precision signed number.
2156// ----------------------------------------------------------------------------
2157
2158template<class T>
2159sc_unsigned::sc_unsigned( const sc_generic_base<T> &v)
2160{
2161    int nb = v->length();
2162    sgn = default_sign();
2163    if (nb > 0) {
2164        nbits = num_bits(nb);
2165    } else {
2166        invalid_init("sc_generic_base<T>", nb);
2167        sc_core::sc_abort(); // can't recover from here
2168    }
2169    ndigits = DIV_CEIL(nbits);
2170#   ifdef SC_MAX_NBITS
2171        test_bound(nb);
2172#   else
2173        digit = new sc_digit[ndigits];
2174#   endif
2175    makezero();
2176    v->to_sc_unsigned(*this);
2177}
2178
2179inline ::std::ostream &
2180operator << (::std::ostream &os, const sc_unsigned &a)
2181{
2182    a.print(os);
2183    return os;
2184}
2185
2186inline ::std::istream &
2187operator >> (::std::istream &is, sc_unsigned &a)
2188{
2189    a.scan(is);
2190    return is;
2191}
2192
2193} // namespace sc_dt
2194
2195#endif // __SYSTEMC_EXT_DT_INT_SC_UNSIGNED_HH__
2196