1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_uint_base.h -- An unsigned integer whose length is less than 64 bits.
23
24               Unlike arbitrary precision, arithmetic and bitwise operations
25               are performed using the native types (hence capped at 64 bits).
26               The sc_uint integer is useful when the user does not need
27               arbitrary precision and the performance is superior to
28               sc_bigint/sc_biguint.
29
30  Original Author: Amit Rao, Synopsys, Inc.
31
32 *****************************************************************************/
33
34/*****************************************************************************
35
36  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
37  changes you are making here.
38
39      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
40  Description of Modification: - Resolved ambiguity with sc_(un)signed.
41                               - Merged the code for 64- and 32-bit versions
42                                 via the constants in sc_nbdefs.h.
43                               - Eliminated redundant file inclusions.
44
45      Name, Affiliation, Date:
46  Description of Modification:
47
48 *****************************************************************************/
49
50// $Log: sc_uint_base.h,v $
51// Revision 1.3  2011/08/24 22:05:46  acg
52//  Torsten Maehne: initialization changes to remove warnings.
53//
54// Revision 1.2  2011/02/18 20:19:15  acg
55//  Andy Goodrich: updating Copyright notice.
56//
57// Revision 1.1.1.1  2006/12/15 20:20:05  acg
58// SystemC 2.3
59//
60// Revision 1.4  2006/05/08 17:50:02  acg
61//   Andy Goodrich: Added David Long's declarations for friend operators,
62//   functions, and methods, to keep the Microsoft compiler happy.
63//
64// Revision 1.3  2006/01/13 18:49:32  acg
65// Added $Log command so that CVS check in comments are reproduced in the
66// source.
67//
68
69#ifndef __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__
70#define __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__
71
72#include <iostream>
73
74#include "../fx/scfx_ieee.hh"
75#include "../misc/sc_value_base.hh"
76#include "../sc_temporary.hh"
77#include "sc_length_param.hh"
78#include "sc_nbdefs.hh"
79
80namespace sc_dt
81{
82
83class sc_concatref;
84
85// classes defined in this module
86class sc_uint_bitref_r;
87class sc_uint_bitref;
88class sc_uint_subref_r;
89class sc_uint_subref;
90class sc_uint_base;
91
92// forward class declarations
93class sc_bv_base;
94class sc_lv_base;
95class sc_int_subref_r;
96class sc_signed_subref_r;
97class sc_unsigned_subref_r;
98class sc_signed;
99class sc_unsigned;
100class sc_fxval;
101class sc_fxval_fast;
102class sc_fxnum;
103class sc_fxnum_fast;
104
105} // namespace sc_dt
106
107// extern template instantiations
108namespace sc_core
109{
110
111extern template class sc_vpool<sc_dt::sc_uint_bitref>;
112extern template class sc_vpool<sc_dt::sc_uint_subref>;
113
114} // namespace sc_core
115
116namespace sc_dt
117{
118
119extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
120
121// friend operator declarations
122inline bool operator == (const sc_uint_base &a, const sc_uint_base &b);
123inline bool operator != (const sc_uint_base &a, const sc_uint_base &b);
124inline bool operator < (const sc_uint_base &a, const sc_uint_base &b);
125inline bool operator <= (const sc_uint_base &a, const sc_uint_base &b);
126inline bool operator > (const sc_uint_base &a, const sc_uint_base &b);
127inline bool operator >= (const sc_uint_base &a, const sc_uint_base &b);
128
129
130// ----------------------------------------------------------------------------
131//  CLASS : sc_uint_bitref_r
132//
133//  Proxy class for sc_uint bit selection (r-value only).
134// ----------------------------------------------------------------------------
135
136class sc_uint_bitref_r : public sc_value_base
137{
138    friend class sc_uint_base;
139    friend class sc_uint_signal;
140
141    // constructors
142  public:
143    sc_uint_bitref_r(const sc_uint_bitref_r &init) :
144         sc_value_base(init), m_index(init.m_index), m_obj_p(init.m_obj_p)
145    {}
146
147  protected:
148    sc_uint_bitref_r() : sc_value_base(), m_index(0), m_obj_p(0) {}
149
150    // initializer for sc_core::sc_vpool:
151    void
152    initialize(const sc_uint_base* obj_p, int index_)
153    {
154        m_obj_p = (sc_uint_base *)obj_p;
155        m_index = index_;
156    }
157
158  public:
159    // destructor
160    virtual ~sc_uint_bitref_r() {}
161
162    // concatenation support
163    virtual int
164    concat_length(bool *xz_present_p) const
165    {
166        if (xz_present_p)
167            *xz_present_p = false;
168        return 1;
169    }
170    virtual bool
171    concat_get_ctrl(sc_digit *dst_p, int low_i) const
172    {
173        int  bit_mask = 1 << (low_i % BITS_PER_DIGIT);
174        int  word_i = low_i / BITS_PER_DIGIT;
175
176        dst_p[word_i] &= ~bit_mask;
177        return false;
178    }
179    virtual bool
180    concat_get_data(sc_digit *dst_p, int low_i) const
181    {
182        int  bit_mask = 1 << (low_i % BITS_PER_DIGIT);
183        bool result;             // True is non-zero.
184        int  word_i = low_i / BITS_PER_DIGIT;
185
186        if (operator uint64()) {
187            dst_p[word_i] |= bit_mask;
188            result = true;
189        } else {
190            dst_p[word_i] &= ~bit_mask;
191            result = false;
192        }
193        return result;
194    }
195    virtual uint64 concat_get_uint64() const { return operator uint64(); }
196
197    // capacity
198    int length() const { return 1; }
199
200    // implicit conversion to uint64
201    operator uint64 () const;
202    bool operator ! () const;
203    bool operator ~ () const;
204
205    // explicit conversions
206    uint64 value() const { return operator uint64 (); }
207    bool to_bool() const { return operator uint64 (); }
208
209    // other methods
210    void print(::std::ostream &os=::std::cout) const { os << to_bool(); }
211
212  protected:
213    int m_index;
214    sc_uint_base *m_obj_p;
215
216  private:
217    // Disabled
218    sc_uint_bitref_r &operator = (const sc_uint_bitref_r &);
219};
220
221inline ::std::ostream &operator << (
222        ::std::ostream &, const sc_uint_bitref_r &);
223
224
225// ----------------------------------------------------------------------------
226//  CLASS : sc_uint_bitref
227//
228//  Proxy class for sc_uint bit selection (r-value and l-value).
229// ----------------------------------------------------------------------------
230
231class sc_uint_bitref : public sc_uint_bitref_r
232{
233    friend class sc_uint_base;
234    friend class sc_core::sc_vpool<sc_uint_bitref>;
235
236    // constructors
237  protected:
238    sc_uint_bitref() : sc_uint_bitref_r() {}
239
240  public:
241    sc_uint_bitref(const sc_uint_bitref &init) : sc_uint_bitref_r(init) {}
242
243  public:
244    // assignment operators
245    sc_uint_bitref &operator = (const sc_uint_bitref_r &b);
246    sc_uint_bitref &operator = (const sc_uint_bitref &b);
247    sc_uint_bitref &operator = (bool b);
248
249    sc_uint_bitref &operator &= (bool b);
250    sc_uint_bitref &operator |= (bool b);
251    sc_uint_bitref &operator ^= (bool b);
252
253    // concatenation methods
254    virtual void concat_set(int64 src, int low_i);
255    virtual void concat_set(const sc_signed &src, int low_i);
256    virtual void concat_set(const sc_unsigned &src, int low_i);
257    virtual void concat_set(uint64 src, int low_i);
258
259    // other methods
260    void scan(::std::istream &is=::std::cin);
261
262  protected:
263    static sc_core::sc_vpool<sc_uint_bitref> m_pool;
264};
265
266inline ::std::istream &operator >> (::std::istream &, sc_uint_bitref &);
267
268
269// ----------------------------------------------------------------------------
270//  CLASS : sc_uint_subref_r
271//
272//  Proxy class for sc_uint part selection (r-value only).
273// ----------------------------------------------------------------------------
274
275class sc_uint_subref_r : public sc_value_base
276{
277    friend class sc_uint_base;
278    friend class sc_uint_subref;
279
280    // constructors
281  public:
282    sc_uint_subref_r( const sc_uint_subref_r& init ) :
283        sc_value_base(init), m_left(init.m_left), m_obj_p(init.m_obj_p),
284        m_right(init.m_right)
285    {}
286
287  protected:
288    sc_uint_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {}
289
290    // initializer for sc_core::sc_vpool:
291    void
292    initialize(const sc_uint_base *obj_p, int left_i, int right_i)
293    {
294        m_obj_p = (sc_uint_base *)obj_p;
295        m_left = left_i;
296        m_right = right_i;
297    }
298
299  public:
300    // destructor
301    virtual ~sc_uint_subref_r() {}
302
303    // capacity
304    int length() const { return (m_left - m_right + 1); }
305
306    // concatenation support
307    virtual int
308    concat_length(bool *xz_present_p) const
309    {
310        if (xz_present_p)
311            *xz_present_p = false;
312        return length();
313    }
314    virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const;
315    virtual bool concat_get_data(sc_digit *dst_p, int low_i) const;
316    virtual uint64
317    concat_get_uint64() const
318    {
319        return (uint64)operator uint_type();
320    }
321
322    // reduce methods
323    bool and_reduce() const;
324    bool nand_reduce() const { return !and_reduce(); }
325    bool or_reduce() const;
326    bool nor_reduce() const { return !or_reduce(); }
327    bool xor_reduce() const;
328    bool xnor_reduce() const { return !xor_reduce(); }
329
330    // implicit conversion to uint_type
331    operator uint_type() const;
332
333    // explicit conversions
334    uint_type value() const { return operator uint_type(); }
335
336    int to_int() const;
337    unsigned int to_uint() const;
338    long to_long() const;
339    unsigned long to_ulong() const;
340    int64 to_int64() const;
341    uint64 to_uint64() const;
342    double to_double() const;
343
344    // explicit conversion to character string
345    const std::string to_string(sc_numrep numrep=SC_DEC) const;
346    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
347
348    // other methods
349    void
350    print(::std::ostream &os=::std::cout) const
351    {
352        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
353    }
354
355  protected:
356    int m_left;
357    sc_uint_base *m_obj_p;
358    int m_right;
359
360  private:
361    // Disabled
362    sc_uint_subref_r &operator = (const sc_uint_subref_r &);
363};
364
365inline ::std::ostream &operator << (
366        ::std::ostream &, const sc_uint_subref_r &);
367
368
369// ----------------------------------------------------------------------------
370//  CLASS : sc_uint_subref
371//
372//  Proxy class for sc_uint part selection (r-value and l-value).
373// ----------------------------------------------------------------------------
374
375class sc_uint_subref : public sc_uint_subref_r
376{
377    friend class sc_uint_base;
378    friend class sc_core::sc_vpool<sc_uint_subref>;
379
380    // constructors
381  protected:
382    sc_uint_subref() : sc_uint_subref_r() {}
383
384  public:
385    sc_uint_subref(const sc_uint_subref &init) : sc_uint_subref_r(init) {}
386
387  public:
388    // assignment operators
389    sc_uint_subref &operator = (uint_type v);
390    sc_uint_subref &operator = (const sc_uint_base &a);
391    sc_uint_subref &
392    operator = (const sc_uint_subref_r &a)
393    {
394        return operator = (a.operator uint_type());
395    }
396    sc_uint_subref &
397    operator = (const sc_uint_subref &a)
398    {
399        return operator = (a.operator uint_type());
400    }
401    template<class T>
402    sc_uint_subref &
403    operator = (const sc_generic_base<T> &a)
404    {
405        return operator = (a->to_uint64());
406    }
407    sc_uint_subref &operator = (const char *a);
408    sc_uint_subref &
409    operator = (unsigned long a)
410    {
411        return operator = ((uint_type)a);
412    }
413    sc_uint_subref &
414    operator = (long a)
415    {
416        return operator = ((uint_type)a);
417    }
418    sc_uint_subref &
419    operator = (unsigned int a)
420    {
421        return operator = ((uint_type)a);
422    }
423    sc_uint_subref &
424    operator = (int a)
425    {
426        return operator = ((uint_type)a);
427    }
428    sc_uint_subref &
429    operator = (int64 a)
430    {
431        return operator = ((uint_type)a);
432    }
433    sc_uint_subref &
434    operator = (double a)
435    {
436        return operator = ((uint_type)a);
437    }
438    sc_uint_subref &operator = (const sc_signed &);
439    sc_uint_subref &operator = (const sc_unsigned &);
440    sc_uint_subref &operator = (const sc_bv_base &);
441    sc_uint_subref &operator = (const sc_lv_base &);
442
443    // concatenation methods
444    virtual void concat_set(int64 src, int low_i);
445    virtual void concat_set(const sc_signed &src, int low_i);
446    virtual void concat_set(const sc_unsigned &src, int low_i);
447    virtual void concat_set(uint64 src, int low_i);
448
449    // other methods
450    void scan(::std::istream &is=::std::cin);
451
452  protected:
453    static sc_core::sc_vpool<sc_uint_subref> m_pool;
454};
455
456inline ::std::istream &operator >> (::std::istream &, sc_uint_subref &);
457
458
459// ----------------------------------------------------------------------------
460//  CLASS : sc_uint_base
461//
462//  Base class for sc_uint.
463// ----------------------------------------------------------------------------
464
465class sc_uint_base : public sc_value_base
466{
467    friend class sc_uint_bitref_r;
468    friend class sc_uint_bitref;
469    friend class sc_uint_subref_r;
470    friend class sc_uint_subref;
471
472    // support methods
473    void invalid_length() const;
474    void invalid_index(int i) const;
475    void invalid_range(int l, int r) const;
476
477    void
478    check_length() const
479    {
480        if (m_len <= 0 || m_len > SC_INTWIDTH) {
481            invalid_length();
482        }
483    }
484
485    void
486    check_index(int i) const
487    {
488        if (i < 0 || i >= m_len) {
489            invalid_index( i );
490        }
491    }
492
493    void
494    check_range(int l, int r) const
495    {
496        if (r < 0 || l >= m_len || l < r) {
497            invalid_range( l, r );
498        }
499    }
500
501    void check_value() const;
502
503    void
504    extend_sign()
505    {
506#ifdef DEBUG_SYSTEMC
507        check_value();
508#endif
509        m_val &= (~UINT_ZERO >> m_ulen);
510    }
511
512  public:
513    // constructors
514    explicit sc_uint_base(int w=sc_length_param().len()) :
515            m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len)
516    {
517        check_length();
518    }
519
520    sc_uint_base(uint_type v, int w) :
521        m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len)
522    {
523        check_length();
524        extend_sign();
525    }
526
527    sc_uint_base(const sc_uint_base &a) :
528            sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
529    {}
530
531    explicit sc_uint_base(const sc_uint_subref_r &a) :
532            m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
533    {
534        extend_sign();
535    }
536
537    template<class T>
538    explicit sc_uint_base(const sc_generic_base<T> &a) :
539            m_val(a->to_uint64()), m_len(a->length()),
540            m_ulen(SC_INTWIDTH - m_len)
541    {
542        check_length();
543        extend_sign();
544    }
545
546    explicit sc_uint_base(const sc_bv_base &v);
547    explicit sc_uint_base(const sc_lv_base &v);
548    explicit sc_uint_base(const sc_int_subref_r &v);
549    explicit sc_uint_base(const sc_signed_subref_r &v);
550    explicit sc_uint_base(const sc_unsigned_subref_r &v);
551    explicit sc_uint_base(const sc_signed &a);
552    explicit sc_uint_base(const sc_unsigned &a);
553
554    // destructor
555    virtual ~sc_uint_base() {}
556
557    // assignment operators
558    sc_uint_base &
559    operator = (uint_type v)
560    {
561        m_val = v;
562        extend_sign();
563        return *this;
564    }
565    sc_uint_base &
566    operator = (const sc_uint_base &a)
567    {
568        m_val = a.m_val;
569        extend_sign();
570        return *this;
571    }
572    sc_uint_base &
573    operator = (const sc_uint_subref_r &a)
574    {
575        m_val = a;
576        extend_sign();
577        return *this;
578    }
579    template<class T>
580    sc_uint_base &
581    operator = (const sc_generic_base<T> &a)
582    {
583        m_val = a->to_uint64();
584        extend_sign();
585        return *this;
586    }
587    sc_uint_base &operator = (const sc_signed &a);
588    sc_uint_base &operator = (const sc_unsigned &a);
589    sc_uint_base &operator = (const sc_fxval &a);
590    sc_uint_base &operator = (const sc_fxval_fast &a);
591    sc_uint_base &operator = (const sc_fxnum &a);
592    sc_uint_base &operator = (const sc_fxnum_fast &a);
593    sc_uint_base &operator = (const sc_bv_base &a);
594    sc_uint_base &operator = (const sc_lv_base &a);
595    sc_uint_base &operator = (const char *a);
596    sc_uint_base &
597    operator = (unsigned long a)
598    {
599        m_val = a;
600        extend_sign();
601        return *this;
602    }
603    sc_uint_base &
604    operator = (long a)
605    {
606        m_val = a;
607        extend_sign();
608        return *this;
609    }
610    sc_uint_base &
611    operator = (unsigned int a)
612    {
613        m_val = a;
614        extend_sign();
615        return *this;
616    }
617    sc_uint_base &
618    operator = (int a)
619    {
620        m_val = a;
621        extend_sign();
622        return *this;
623    }
624    sc_uint_base &
625    operator = (int64 a)
626    {
627        m_val = a;
628        extend_sign();
629        return *this;
630    }
631    sc_uint_base &
632    operator = (double a)
633    {
634        m_val = (uint_type)a;
635        extend_sign();
636        return *this;
637    }
638
639    // arithmetic assignment operators
640    sc_uint_base &
641    operator += (uint_type v)
642    {
643        m_val += v;
644        extend_sign();
645        return *this;
646    }
647    sc_uint_base &
648    operator -= (uint_type v)
649    {
650        m_val -= v;
651        extend_sign();
652        return *this;
653    }
654    sc_uint_base &
655    operator *= (uint_type v)
656    {
657        m_val *= v;
658        extend_sign();
659        return *this;
660    }
661    sc_uint_base &
662    operator /= (uint_type v)
663    {
664        m_val /= v;
665        extend_sign();
666        return *this;
667    }
668    sc_uint_base &
669    operator %= (uint_type v)
670    {
671        m_val %= v;
672        extend_sign();
673        return *this;
674    }
675
676    // bitwise assignment operators
677    sc_uint_base &
678    operator &= (uint_type v)
679    {
680        m_val &= v;
681        extend_sign();
682        return *this;
683    }
684    sc_uint_base &
685    operator |= (uint_type v)
686    {
687        m_val |= v;
688        extend_sign();
689        return *this;
690    }
691    sc_uint_base &
692    operator ^= (uint_type v)
693    {
694        m_val ^= v;
695        extend_sign();
696        return *this;
697    }
698    sc_uint_base &
699    operator <<= (uint_type v)
700    {
701        m_val <<= v;
702        extend_sign();
703        return *this;
704    }
705    sc_uint_base &
706    operator >>= (uint_type v)
707    {
708        m_val >>= v;
709        /* no sign extension needed */
710        return *this;
711    }
712
713    // prefix and postfix increment and decrement operators
714    sc_uint_base &
715    operator ++ () // prefix
716    {
717        ++m_val;
718        extend_sign();
719        return *this;
720    }
721    const sc_uint_base
722    operator ++ (int) // postfix
723    {
724        sc_uint_base tmp(*this);
725        ++m_val;
726        extend_sign();
727        return tmp;
728    }
729
730    sc_uint_base &
731    operator -- () // prefix
732    {
733        --m_val;
734        extend_sign();
735        return *this;
736    }
737    const sc_uint_base
738    operator -- (int) // postfix
739    {
740        sc_uint_base tmp(*this);
741        --m_val;
742        extend_sign();
743        return tmp;
744    }
745
746    // relational operators
747    friend bool
748    operator == (const sc_uint_base &a, const sc_uint_base &b)
749    {
750        return a.m_val == b.m_val;
751    }
752    friend bool
753    operator != (const sc_uint_base &a, const sc_uint_base &b)
754    {
755        return a.m_val != b.m_val;
756    }
757    friend bool
758    operator <  (const sc_uint_base &a, const sc_uint_base &b)
759    {
760        return a.m_val < b.m_val;
761    }
762    friend bool
763    operator <= (const sc_uint_base &a, const sc_uint_base &b)
764    {
765        return a.m_val <= b.m_val;
766    }
767    friend bool
768    operator >  (const sc_uint_base &a, const sc_uint_base &b)
769    {
770        return a.m_val > b.m_val;
771    }
772    friend bool
773    operator >= (const sc_uint_base &a, const sc_uint_base &b)
774    {
775        return a.m_val >= b.m_val;
776    }
777
778    // bit selection
779    sc_uint_bitref &operator [] (int i);
780    const sc_uint_bitref_r &operator [] (int i) const;
781
782    sc_uint_bitref &bit(int i);
783    const sc_uint_bitref_r &bit(int i) const;
784
785    // part selection
786    sc_uint_subref &operator () (int left, int right);
787    const sc_uint_subref_r &operator () (int left, int right) const;
788
789    sc_uint_subref &range(int left, int right);
790    const sc_uint_subref_r &range(int left, int right) const;
791
792    // bit access, without bounds checking or sign extension
793    bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); }
794
795    void set(int i) { m_val |= (UINT_ONE << i); }
796    void
797    set(int i, bool v)
798    {
799        v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i);
800    }
801
802    // capacity
803    int length() const { return m_len; }
804
805    // concatenation support
806    virtual int
807    concat_length(bool *xz_present_p) const
808    {
809        if (xz_present_p)
810            *xz_present_p = false;
811        return length();
812    }
813    virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const;
814    virtual bool concat_get_data( sc_digit *dst_p, int low_i) const;
815    virtual uint64 concat_get_uint64() const { return m_val; }
816    virtual void concat_set(int64 src, int low_i);
817    virtual void concat_set(const sc_signed &src, int low_i);
818    virtual void concat_set(const sc_unsigned &src, int low_i);
819    virtual void concat_set(uint64 src, int low_i);
820
821    // reduce methods
822    bool and_reduce() const;
823    bool nand_reduce() const { return !and_reduce(); }
824    bool or_reduce() const;
825    bool nor_reduce() const { return !or_reduce(); }
826    bool xor_reduce() const;
827    bool xnor_reduce() const { return !xor_reduce(); }
828
829    // implicit conversion to uint_type
830    operator uint_type() const { return m_val; }
831
832    // explicit conversions
833    uint_type value() const { return operator uint_type(); }
834
835    int to_int() const { return (int) m_val; }
836    unsigned int to_uint() const { return (unsigned int)m_val; }
837    long to_long() const { return (long)m_val; }
838    unsigned long to_ulong() const { return (unsigned long)m_val; }
839    int64 to_int64() const { return (int64)m_val; }
840    uint64 to_uint64() const { return (uint64)m_val; }
841    double to_double() const { return uint64_to_double(m_val); }
842
843    long long_low() const { return (long)(m_val & UINT64_32ONES); }
844    long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); }
845
846    // explicit conversion to character string
847    const std::string to_string(sc_numrep numrep=SC_DEC) const;
848    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
849
850    // other methods
851    void
852    print(::std::ostream &os=::std::cout) const
853    {
854        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
855    }
856
857    void scan(::std::istream &is=::std::cin);
858
859  protected:
860    uint_type m_val; // value
861    int m_len; // length
862    int m_ulen; // unused length
863};
864
865inline ::std::ostream &operator << (::std::ostream &, const sc_uint_base &);
866inline ::std::istream &operator >> (::std::istream &, sc_uint_base &);
867
868
869// ----------------------------------------------------------------------------
870//  CLASS : sc_uint_bitref_r
871//
872//  Proxy class for sc_uint bit selection (r-value only).
873// ----------------------------------------------------------------------------
874
875// implicit conversion to bool
876
877inline sc_uint_bitref_r::operator uint64 () const
878{
879    return m_obj_p->test(m_index);
880}
881
882inline bool
883sc_uint_bitref_r::operator ! () const
884{
885    return !m_obj_p->test(m_index);
886}
887
888inline bool
889sc_uint_bitref_r::operator ~ () const
890{
891    return !m_obj_p->test(m_index);
892}
893
894inline ::std::ostream &
895operator << (::std::ostream &os, const sc_uint_bitref_r &a)
896{
897    a.print(os);
898    return os;
899}
900
901
902// ----------------------------------------------------------------------------
903//  CLASS : sc_uint_bitref
904//
905//  Proxy class for sc_uint bit selection (r-value and l-value).
906// ----------------------------------------------------------------------------
907
908// assignment operators
909
910inline sc_uint_bitref &
911sc_uint_bitref::operator = (const sc_uint_bitref_r &b)
912{
913    m_obj_p->set(m_index, b.to_bool());
914    return *this;
915}
916
917inline sc_uint_bitref &
918sc_uint_bitref::operator = (const sc_uint_bitref &b)
919{
920    m_obj_p->set(m_index, b.to_bool());
921    return *this;
922}
923
924inline sc_uint_bitref &
925sc_uint_bitref::operator = (bool b)
926{
927    m_obj_p->set(m_index, b);
928    return *this;
929}
930
931inline sc_uint_bitref &
932sc_uint_bitref::operator &= (bool b)
933{
934    if (!b) {
935        m_obj_p->set(m_index, b);
936    }
937    return *this;
938}
939
940inline sc_uint_bitref &
941sc_uint_bitref::operator |= (bool b)
942{
943    if (b) {
944        m_obj_p->set(m_index, b);
945    }
946    return *this;
947}
948
949inline sc_uint_bitref &
950sc_uint_bitref::operator ^= (bool b)
951{
952    if (b) {
953        m_obj_p->m_val ^= (UINT_ONE << m_index);
954    }
955    return *this;
956}
957
958inline ::std::istream &
959operator >> (::std::istream &is, sc_uint_bitref &a)
960{
961    a.scan(is);
962    return is;
963}
964
965
966// ----------------------------------------------------------------------------
967//  CLASS : sc_uint_subref_r
968//
969//  Proxy class for sc_uint part selection (r-value only).
970// ----------------------------------------------------------------------------
971
972// implicit conversion to uint_type
973
974inline sc_uint_subref_r::operator uint_type() const
975{
976    uint_type val = m_obj_p->m_val;
977    int uleft = SC_INTWIDTH - (m_left + 1);
978    return ((val & (~UINT_ZERO >> uleft)) >> m_right);
979}
980
981
982// reduce methods
983inline bool
984sc_uint_subref_r::and_reduce() const
985{
986    sc_uint_base a(*this);
987    return a.and_reduce();
988}
989inline bool
990sc_uint_subref_r::or_reduce() const
991{
992    sc_uint_base a(*this);
993    return a.or_reduce();
994}
995inline bool
996sc_uint_subref_r::xor_reduce() const
997{
998    sc_uint_base a(*this);
999    return a.xor_reduce();
1000}
1001
1002// explicit conversions
1003inline int
1004sc_uint_subref_r::to_int() const
1005{
1006    sc_uint_base a(*this);
1007    return a.to_int();
1008}
1009inline unsigned int
1010sc_uint_subref_r::to_uint() const
1011{
1012    sc_uint_base a(*this);
1013    return a.to_uint();
1014}
1015inline long
1016sc_uint_subref_r::to_long() const
1017{
1018    sc_uint_base a(*this);
1019    return a.to_long();
1020}
1021inline unsigned long
1022sc_uint_subref_r::to_ulong() const
1023{
1024    sc_uint_base a(*this);
1025    return a.to_ulong();
1026}
1027inline int64
1028sc_uint_subref_r::to_int64() const
1029{
1030    sc_uint_base a(*this);
1031    return a.to_int64();
1032}
1033inline uint64
1034sc_uint_subref_r::to_uint64() const
1035{
1036    sc_uint_base a(*this);
1037    return a.to_uint64();
1038}
1039inline double
1040sc_uint_subref_r::to_double() const
1041{
1042    sc_uint_base a(*this);
1043    return a.to_double();
1044}
1045
1046// explicit conversion to character string
1047inline const std::string
1048sc_uint_subref_r::to_string(sc_numrep numrep) const
1049{
1050    sc_uint_base a(*this);
1051    return a.to_string(numrep);
1052}
1053
1054inline const std::string
1055sc_uint_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
1056{
1057    sc_uint_base a(*this);
1058    return a.to_string(numrep, w_prefix);
1059}
1060
1061// functional notation for the reduce methods
1062inline bool
1063and_reduce(const sc_uint_subref_r &a)
1064{
1065    return a.and_reduce();
1066}
1067inline bool
1068nand_reduce(const sc_uint_subref_r &a)
1069{
1070    return a.nand_reduce();
1071}
1072inline bool
1073or_reduce(const sc_uint_subref_r &a)
1074{
1075    return a.or_reduce();
1076}
1077inline bool
1078nor_reduce(const sc_uint_subref_r &a)
1079{
1080    return a.nor_reduce();
1081}
1082inline bool
1083xor_reduce(const sc_uint_subref_r &a)
1084{
1085    return a.xor_reduce();
1086}
1087inline bool
1088xnor_reduce(const sc_uint_subref_r &a)
1089{
1090    return a.xnor_reduce();
1091}
1092
1093inline ::std::ostream &
1094operator << (::std::ostream &os, const sc_uint_subref_r &a)
1095{
1096    a.print(os);
1097    return os;
1098}
1099
1100
1101// ----------------------------------------------------------------------------
1102//  CLASS : sc_uint_subref
1103//
1104//  Proxy class for sc_uint part selection (r-value and l-value).
1105// ----------------------------------------------------------------------------
1106
1107// assignment operators
1108
1109inline sc_uint_subref &
1110sc_uint_subref::operator = (const sc_uint_base &a)
1111{
1112    return operator = (a.operator uint_type());
1113}
1114
1115inline sc_uint_subref &
1116sc_uint_subref::operator = (const char *a)
1117{
1118    sc_uint_base aa(length());
1119    return (*this = aa = a);
1120}
1121
1122inline ::std::istream &
1123operator >> (::std::istream &is, sc_uint_subref &a)
1124{
1125    a.scan(is);
1126    return is;
1127}
1128
1129
1130// ----------------------------------------------------------------------------
1131//  CLASS : sc_uint_base
1132//
1133//  Base class for sc_uint.
1134// ----------------------------------------------------------------------------
1135
1136// bit selection
1137inline sc_uint_bitref &
1138sc_uint_base::operator [] (int i)
1139{
1140    check_index(i);
1141    sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate();
1142    result_p->initialize(this, i);
1143    return *result_p;
1144}
1145
1146inline const sc_uint_bitref_r &
1147sc_uint_base::operator [] (int i) const
1148{
1149    check_index(i);
1150    sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate();
1151    result_p->initialize(this, i);
1152    return *result_p;
1153}
1154
1155inline sc_uint_bitref &
1156sc_uint_base::bit(int i)
1157{
1158    check_index(i);
1159    sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate();
1160    result_p->initialize(this, i);
1161    return *result_p;
1162}
1163
1164inline const sc_uint_bitref_r &
1165sc_uint_base::bit(int i) const
1166{
1167    check_index(i);
1168    sc_uint_bitref *result_p = sc_uint_bitref::m_pool.allocate();
1169    result_p->initialize(this, i);
1170    return *result_p;
1171}
1172
1173// part selection
1174inline sc_uint_subref &
1175sc_uint_base::operator () (int left, int right)
1176{
1177    check_range(left, right);
1178    sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate();
1179    result_p->initialize(this, left, right);
1180    return *result_p;
1181}
1182
1183inline const sc_uint_subref_r &
1184sc_uint_base::operator () (int left, int right) const
1185{
1186    check_range(left, right);
1187    sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate();
1188    result_p->initialize(this, left, right);
1189    return *result_p;
1190}
1191
1192inline sc_uint_subref &
1193sc_uint_base::range(int left, int right)
1194{
1195    check_range(left, right);
1196    sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate();
1197    result_p->initialize(this, left, right);
1198    return *result_p;
1199}
1200
1201inline const sc_uint_subref_r &
1202sc_uint_base::range(int left, int right) const
1203{
1204    check_range(left, right);
1205    sc_uint_subref *result_p = sc_uint_subref::m_pool.allocate();
1206    result_p->initialize(this, left, right);
1207    return *result_p;
1208}
1209
1210// functional notation for the reduce methods
1211inline bool
1212and_reduce(const sc_uint_base &a)
1213{
1214    return a.and_reduce();
1215}
1216inline bool
1217nand_reduce(const sc_uint_base &a)
1218{
1219    return a.nand_reduce();
1220}
1221inline bool
1222or_reduce(const sc_uint_base &a)
1223{
1224    return a.or_reduce();
1225}
1226inline bool
1227nor_reduce(const sc_uint_base &a)
1228{
1229    return a.nor_reduce();
1230}
1231inline bool
1232xor_reduce(const sc_uint_base &a)
1233{
1234    return a.xor_reduce();
1235}
1236inline bool
1237xnor_reduce(const sc_uint_base &a)
1238{
1239    return a.xnor_reduce();
1240}
1241
1242inline ::std::ostream &
1243operator << (::std::ostream &os, const sc_uint_base &a)
1244{
1245    a.print(os);
1246    return os;
1247}
1248
1249inline ::std::istream &
1250operator >> (::std::istream &is, sc_uint_base &a)
1251{
1252    a.scan(is);
1253    return is;
1254}
1255
1256} // namespace sc_dt
1257
1258#endif // __SYSTEMC_EXT_DT_INT_SC_UINT_BASE_HH__
1259