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_int_base.h -- A signed integer whose length is less than 64 bit.
23
24              Unlike arbitrary precision, arithmetic and bitwise operations
25              are performed using the native types (hence capped at 64 bits).
26              The sc_int 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_int_base.h,v $
51// Revision 1.3  2011/08/24 22:05:45  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:01  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:31  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_INT_BASE_HH__
70#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
71
72#include <iostream>
73
74#include "../misc/sc_value_base.hh"
75#include "../sc_temporary.hh"
76#include "sc_length_param.hh"
77#include "sc_nbdefs.hh"
78#include "sc_uint_base.hh"
79
80namespace sc_dt
81{
82
83class sc_concatref;
84
85// classes defined in this module
86class sc_int_bitref_r;
87class sc_int_bitref;
88class sc_int_subref_r;
89class sc_int_subref;
90class sc_int_base;
91class sc_signed_subref_r;
92class sc_unsigned_subref_r;
93
94// forward class declarations
95class sc_bv_base;
96class sc_lv_base;
97class sc_signed;
98class sc_unsigned;
99class sc_fxval;
100class sc_fxval_fast;
101class sc_fxnum;
102class sc_fxnum_fast;
103
104} // namespace sc_dt
105
106// extern template instantiations
107namespace sc_core
108{
109
110extern template class sc_vpool<sc_dt::sc_int_bitref>;
111extern template class sc_vpool<sc_dt::sc_int_subref>;
112
113} // namespace sc_core
114
115namespace sc_dt
116{
117
118extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];
119
120// friend operator declarations
121
122// relational operators
123
124inline bool operator == (const sc_int_base &a, const sc_int_base &b);
125inline bool operator != (const sc_int_base &a, const sc_int_base &b);
126inline bool operator <  (const sc_int_base &a, const sc_int_base &b);
127inline bool operator <= (const sc_int_base &a, const sc_int_base &b);
128inline bool operator >  (const sc_int_base &a, const sc_int_base &b);
129inline bool operator >= (const sc_int_base &a, const sc_int_base &b);
130
131
132// ----------------------------------------------------------------------------
133//  CLASS : sc_int_bitref_r
134//
135//  Proxy class for sc_int bit selection (r-value only).
136// ----------------------------------------------------------------------------
137
138class sc_int_bitref_r : public sc_value_base
139{
140    friend class sc_int_base;
141
142  protected:
143    // constructor
144    sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {}
145
146    // initializer for sc_core::sc_vpool:
147    void initialize(const sc_int_base *obj_p, int index_)
148    {
149        m_obj_p = (sc_int_base *)obj_p;
150        m_index = index_;
151    }
152
153  public:
154    // copy constructor
155    sc_int_bitref_r(const sc_int_bitref_r &a) :
156        sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
157    {}
158
159    // destructor
160    virtual ~sc_int_bitref_r() {}
161
162    // capacity
163    int length() const { return 1; }
164
165#ifdef SC_DT_DEPRECATED
166    int bitwidth() const { return length(); }
167#endif
168
169    // concatenation support
170    virtual int
171    concat_length(bool *xz_present_p) const
172    {
173        if (xz_present_p)
174            *xz_present_p = false;
175        return 1;
176    }
177    virtual bool
178    concat_get_ctrl(sc_digit *dst_p, int low_i) const
179    {
180        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
181        int word_i = low_i / BITS_PER_DIGIT;
182
183        dst_p[word_i] &= ~bit_mask;
184        return false;
185    }
186    virtual bool
187    concat_get_data(sc_digit *dst_p, int low_i) const
188    {
189        bool non_zero;
190        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
191        int word_i = low_i / BITS_PER_DIGIT;
192
193        if (operator uint64()) {
194            dst_p[word_i] |= bit_mask;
195            non_zero = true;
196        } else {
197            dst_p[word_i] &= ~bit_mask;
198            non_zero = false;
199        }
200        return non_zero;
201    }
202    virtual uint64
203    concat_get_uint64() const
204    {
205        return operator uint64();
206    }
207
208
209    // implicit conversions
210    operator uint64 () const;
211    bool operator ! () const;
212    bool operator ~ () const;
213
214
215    // explicit conversions
216    uint64 value() const { return operator uint64(); }
217
218    bool to_bool() const { return operator uint64(); }
219
220
221    // other methods
222    void print(::std::ostream& os=::std::cout) const { os << to_bool(); }
223
224  protected:
225    int m_index;
226    sc_int_base *m_obj_p;
227
228  private:
229    // Disabled
230    sc_int_bitref_r &operator = (const sc_int_bitref_r &);
231};
232
233
234inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &);
235
236
237// ----------------------------------------------------------------------------
238//  CLASS : sc_int_bitref
239//
240//  Proxy class for sc_int bit selection (r-value and l-value).
241// ----------------------------------------------------------------------------
242
243class sc_int_bitref : public sc_int_bitref_r
244{
245    friend class sc_int_base;
246    friend class sc_core::sc_vpool<sc_int_bitref>;
247
248    // constructor
249    sc_int_bitref() : sc_int_bitref_r() {}
250
251  public:
252    // copy constructor
253    sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {}
254
255    // assignment operators
256    sc_int_bitref &operator = (const sc_int_bitref_r &b);
257    sc_int_bitref &operator = (const sc_int_bitref &b);
258    sc_int_bitref &operator = (bool b);
259
260    sc_int_bitref &operator &= (bool b);
261    sc_int_bitref &operator |= (bool b);
262    sc_int_bitref &operator ^= (bool b);
263
264    // concatenation methods
265    virtual void concat_set(int64 src, int low_i);
266    virtual void concat_set(const sc_signed &src, int low_i);
267    virtual void concat_set(const sc_unsigned &src, int low_i);
268    virtual void concat_set(uint64 src, int low_i);
269
270    // other methods
271    void scan(::std::istream &is=::std::cin);
272
273  public:
274    static sc_core::sc_vpool<sc_int_bitref> m_pool;
275};
276
277
278
279inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &);
280
281
282// ----------------------------------------------------------------------------
283//  CLASS : sc_int_subref_r
284//
285//  Proxy class for sc_int part selection (r-value only).
286// ----------------------------------------------------------------------------
287
288class sc_int_subref_r : public sc_value_base
289{
290    friend class sc_int_base;
291    friend class sc_int_signal;
292    friend class sc_int_subref;
293
294  protected:
295    // constructor
296    sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {}
297
298    // initializer for sc_core::sc_vpool:
299    void initialize( const sc_int_base *obj_p, int left_i, int right_i)
300    {
301        m_obj_p = (sc_int_base *)obj_p;
302        m_left = left_i;
303        m_right = right_i;
304    }
305
306  public:
307    // copy constructor
308    sc_int_subref_r(const sc_int_subref_r &a) :
309        sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p),
310        m_right(a.m_right)
311    {}
312
313    // destructor
314    virtual ~sc_int_subref_r() {}
315
316    // capacity
317    int length() const { return (m_left - m_right + 1); }
318
319    // concatenation support
320    virtual int
321    concat_length(bool *xz_present_p) const
322    {
323        if (xz_present_p)
324            *xz_present_p = false;
325        return length();
326    }
327    virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
328    virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
329    virtual uint64
330    concat_get_uint64() const
331    {
332        int len = length();
333        uint64 val = operator uint_type();
334        if (len < 64)
335            return (uint64)(val & ~((uint_type)-1 << len));
336        else
337            return (uint64)val;
338    }
339
340    // reduce methods
341    bool and_reduce() const;
342    bool nand_reduce() const { return !and_reduce(); }
343    bool or_reduce() const;
344    bool nor_reduce() const { return !or_reduce(); }
345    bool xor_reduce() const;
346    bool xnor_reduce() const { return !xor_reduce(); }
347
348    // implicit conversion to uint_type
349    operator uint_type () const;
350
351    // explicit conversions
352    uint_type value() const { return operator uint_type(); }
353
354
355    int to_int() const;
356    unsigned int to_uint() const;
357    long to_long() const;
358    unsigned long to_ulong() const;
359    int64 to_int64() const;
360    uint64 to_uint64() const;
361    double to_double() const;
362
363    // explicit conversion to character string
364    const std::string to_string(sc_numrep numrep=SC_DEC) const;
365    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
366
367    // other methods
368    void
369    print(::std::ostream &os=::std::cout) const
370    {
371        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
372    }
373
374  protected:
375    int m_left;
376    sc_int_base *m_obj_p;
377    int m_right;
378
379  private:
380    const sc_int_subref_r &operator = (const sc_int_subref_r &);
381};
382
383inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &);
384
385
386// ----------------------------------------------------------------------------
387//  CLASS : sc_int_subref
388//
389//  Proxy class for sc_int part selection (r-value and l-value).
390// ----------------------------------------------------------------------------
391
392class sc_int_subref : public sc_int_subref_r
393{
394    friend class sc_int_base;
395    friend class sc_core::sc_vpool<sc_int_subref>;
396
397  protected:
398    // constructor
399    sc_int_subref() : sc_int_subref_r() {}
400
401  public:
402    // copy constructor
403    sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {}
404
405    // assignment operators
406    sc_int_subref &operator = (int_type v);
407    sc_int_subref &operator = (const sc_int_base &a);
408
409    sc_int_subref &
410    operator = (const sc_int_subref_r &a)
411    {
412        return operator = (a.operator uint_type());
413    }
414
415    sc_int_subref &
416    operator = (const sc_int_subref &a)
417    {
418        return operator = (a.operator uint_type());
419    }
420
421    template< class T >
422    sc_int_subref &
423    operator = (const sc_generic_base<T> &a)
424    {
425        return operator = (a->to_int64());
426    }
427
428    sc_int_subref &operator = (const char *a);
429
430    sc_int_subref &
431    operator = (unsigned long a)
432    {
433        return operator = ((int_type)a);
434    }
435
436    sc_int_subref &
437    operator = (long a)
438    {
439        return operator = ((int_type)a);
440    }
441
442    sc_int_subref &
443    operator = (unsigned int a)
444    {
445        return operator = ((int_type)a);
446    }
447
448    sc_int_subref &
449    operator = (int a)
450    {
451        return operator = ((int_type)a);
452    }
453
454    sc_int_subref &
455    operator = (uint64 a)
456    {
457        return operator = ((int_type)a);
458    }
459
460    sc_int_subref &
461    operator = (double a)
462    {
463        return operator = ((int_type)a);
464    }
465
466    sc_int_subref &operator = (const sc_signed &);
467    sc_int_subref &operator = (const sc_unsigned &);
468    sc_int_subref &operator = (const sc_bv_base &);
469    sc_int_subref &operator = (const sc_lv_base &);
470
471    // concatenation methods
472    virtual void concat_set(int64 src, int low_i);
473    virtual void concat_set(const sc_signed &src, int low_i);
474    virtual void concat_set(const sc_unsigned &src, int low_i);
475    virtual void concat_set(uint64 src, int low_i);
476
477    // other methods
478    void scan(::std::istream &is=::std::cin);
479
480  public:
481    static sc_core::sc_vpool<sc_int_subref> m_pool;
482};
483
484
485inline ::std::istream &operator >> (::std::istream &, sc_int_subref &);
486
487
488// ----------------------------------------------------------------------------
489//  CLASS : sc_int_base
490//
491//  Base class for sc_int.
492// ----------------------------------------------------------------------------
493
494class sc_int_base : public sc_value_base
495{
496    friend class sc_int_bitref_r;
497    friend class sc_int_bitref;
498    friend class sc_int_subref_r;
499    friend class sc_int_subref;
500
501
502    // support methods
503    void invalid_length() const;
504    void invalid_index(int i) const;
505    void invalid_range(int l, int r) const;
506
507    void
508    check_length() const
509    {
510        if (m_len <= 0 || m_len > SC_INTWIDTH) {
511            invalid_length();
512        }
513    }
514
515    void
516    check_index(int i) const
517    {
518        if (i < 0 || i >= m_len) {
519            invalid_index(i);
520        }
521    }
522
523    void
524    check_range(int l, int r) const
525    {
526        if (r < 0 || l >= m_len || l < r) {
527            invalid_range(l, r);
528        }
529    }
530
531    void check_value() const;
532
533    void
534    extend_sign()
535    {
536#ifdef DEBUG_SYSTEMC
537        check_value();
538#endif
539        m_val = (m_val << m_ulen >> m_ulen);
540    }
541
542public:
543
544    // constructors
545    explicit sc_int_base(int w=sc_length_param().len()) :
546            m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len)
547    {
548        check_length();
549    }
550
551    sc_int_base(int_type v, int w) :
552        m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len)
553    {
554        check_length();
555        extend_sign();
556    }
557
558    sc_int_base(const sc_int_base &a) :
559            sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
560    {}
561
562    explicit sc_int_base(const sc_int_subref_r &a) :
563        m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
564    {
565        extend_sign();
566    }
567
568    template< class T >
569    explicit sc_int_base(const sc_generic_base<T> &a) :
570        m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len)
571    {
572        check_length();
573        extend_sign();
574    }
575
576    explicit sc_int_base(const sc_signed &a);
577    explicit sc_int_base(const sc_unsigned &a);
578    explicit sc_int_base(const sc_bv_base &v);
579    explicit sc_int_base(const sc_lv_base &v);
580    explicit sc_int_base(const sc_uint_subref_r &v);
581    explicit sc_int_base(const sc_signed_subref_r &v);
582    explicit sc_int_base(const sc_unsigned_subref_r &v);
583
584
585    // destructor
586    virtual ~sc_int_base() {}
587
588    // assignment operators
589    sc_int_base &
590    operator = (int_type v)
591    {
592        m_val = v;
593        extend_sign();
594        return *this;
595    }
596
597    sc_int_base &
598    operator = (const sc_int_base &a)
599    {
600        m_val = a.m_val;
601        extend_sign();
602        return *this;
603    }
604
605    sc_int_base &
606    operator = (const sc_int_subref_r &a)
607    {
608        m_val = a;
609        extend_sign();
610        return *this;
611    }
612
613    template<class T>
614    sc_int_base &
615    operator = (const sc_generic_base<T> &a)
616    {
617        m_val = a->to_int64();
618        extend_sign();
619        return *this;
620    }
621
622    sc_int_base &operator = (const sc_signed &a);
623    sc_int_base &operator = (const sc_unsigned &a);
624
625    sc_int_base &operator = (const sc_fxval &a);
626    sc_int_base &operator = (const sc_fxval_fast &a);
627    sc_int_base &operator = (const sc_fxnum &a);
628    sc_int_base &operator = (const sc_fxnum_fast &a);
629
630    sc_int_base &operator = (const sc_bv_base &a);
631    sc_int_base &operator = (const sc_lv_base &a);
632
633    sc_int_base &operator = (const char *a);
634
635    sc_int_base &
636    operator = (unsigned long a)
637    {
638        m_val = a;
639        extend_sign();
640        return *this;
641    }
642
643    sc_int_base &
644    operator = (long a)
645    {
646        m_val = a;
647        extend_sign();
648        return *this;
649    }
650
651    sc_int_base &
652    operator = (unsigned int a)
653    {
654        m_val = a;
655        extend_sign();
656        return *this;
657    }
658
659    sc_int_base &
660    operator = (int a)
661    {
662        m_val = a;
663        extend_sign();
664        return *this;
665    }
666
667    sc_int_base &
668    operator = (uint64 a)
669    {
670        m_val = a;
671        extend_sign();
672        return *this;
673    }
674
675    sc_int_base &
676    operator = (double a)
677    {
678        m_val = (int_type)a;
679        extend_sign();
680        return *this;
681    }
682
683    // arithmetic assignment operators
684    sc_int_base &
685    operator += (int_type v)
686    {
687        m_val += v;
688        extend_sign();
689        return *this;
690    }
691
692    sc_int_base &
693    operator -= (int_type v)
694    {
695        m_val -= v;
696        extend_sign();
697        return *this;
698    }
699
700    sc_int_base &
701    operator *= (int_type v)
702    {
703        m_val *= v;
704        extend_sign();
705        return *this;
706    }
707
708    sc_int_base &
709    operator /= (int_type v)
710    {
711        m_val /= v;
712        extend_sign();
713        return *this;
714    }
715
716    sc_int_base &
717    operator %= (int_type v)
718    {
719        m_val %= v;
720        extend_sign();
721        return *this;
722    }
723
724
725    // bitwise assignment operators
726    sc_int_base &
727    operator &= (int_type v)
728    {
729        m_val &= v;
730        extend_sign();
731        return *this;
732    }
733
734    sc_int_base &
735    operator |= (int_type v)
736    {
737        m_val |= v;
738        extend_sign();
739        return *this;
740    }
741
742    sc_int_base &
743    operator ^= (int_type v)
744    {
745        m_val ^= v;
746        extend_sign();
747        return *this;
748    }
749
750
751    sc_int_base &
752    operator <<= (int_type v)
753    {
754        m_val <<= v;
755        extend_sign();
756        return *this;
757    }
758
759    sc_int_base &
760    operator >>= (int_type v)
761    {
762        m_val >>= v;
763        /* no sign extension needed */
764        return *this;
765    }
766
767
768    // prefix and postfix increment and decrement operators
769    sc_int_base &
770    operator ++ () // prefix
771    {
772        ++m_val;
773        extend_sign();
774        return *this;
775    }
776
777    const sc_int_base
778    operator ++ (int) // postfix
779    {
780        sc_int_base tmp(*this);
781        ++m_val;
782        extend_sign();
783        return tmp;
784    }
785
786    sc_int_base &
787    operator -- () // prefix
788    {
789        --m_val;
790        extend_sign();
791        return *this;
792    }
793
794    const sc_int_base
795    operator -- ( int ) // postfix
796    {
797        sc_int_base tmp(*this);
798        --m_val;
799        extend_sign();
800        return tmp;
801    }
802
803
804    // relational operators
805    friend bool
806    operator == (const sc_int_base &a, const sc_int_base &b)
807    {
808        return a.m_val == b.m_val;
809    }
810
811    friend bool
812    operator != (const sc_int_base &a, const sc_int_base &b)
813    {
814        return a.m_val != b.m_val;
815    }
816
817    friend bool
818    operator < (const sc_int_base &a, const sc_int_base &b)
819    {
820        return a.m_val < b.m_val;
821    }
822
823    friend bool
824    operator <= (const sc_int_base &a, const sc_int_base &b)
825    {
826        return a.m_val <= b.m_val;
827    }
828
829    friend bool
830    operator > (const sc_int_base &a, const sc_int_base &b)
831    {
832        return a.m_val > b.m_val;
833    }
834
835    friend bool
836    operator >= (const sc_int_base &a, const sc_int_base &b)
837    {
838        return a.m_val >= b.m_val;
839    }
840
841
842    // bit selection
843    sc_int_bitref &operator [] (int i);
844    const sc_int_bitref_r &operator [] (int i) const;
845
846    sc_int_bitref &bit(int i);
847    const sc_int_bitref_r &bit(int i) const;
848
849
850    // part selection
851    sc_int_subref &operator () (int left, int right);
852    const sc_int_subref_r &operator () (int left, int right) const;
853
854    sc_int_subref &range(int left, int right);
855    const sc_int_subref_r &range(int left, int right) const;
856
857
858    // bit access, without bounds checking or sign extension
859    bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); }
860
861    void set(int i) { m_val |= (UINT_ONE << i); }
862
863    void
864    set(int i, bool v)
865    {
866        v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i);
867    }
868
869    // capacity
870    int length() const { return m_len; }
871
872    // concatenation support
873    virtual int
874    concat_length(bool* xz_present_p) const
875    {
876        if (xz_present_p)
877            *xz_present_p = false;
878        return length();
879    }
880    virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
881    virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
882    virtual uint64
883    concat_get_uint64() const
884    {
885        if (m_len < 64)
886            return (uint64)(m_val & ~((uint_type) - 1 << m_len));
887        else
888            return (uint64)m_val;
889    }
890    virtual void concat_set(int64 src, int low_i);
891    virtual void concat_set(const sc_signed &src, int low_i);
892    virtual void concat_set(const sc_unsigned &src, int low_i);
893    virtual void concat_set(uint64 src, int low_i);
894
895
896    // reduce methods
897    bool and_reduce() const;
898    bool nand_reduce() const { return !and_reduce(); }
899    bool or_reduce() const;
900    bool nor_reduce() const { return !or_reduce(); }
901    bool xor_reduce() const;
902    bool xnor_reduce() const { return !xor_reduce(); }
903
904
905    // implicit conversion to int_type
906    operator int_type() const { return m_val; }
907
908
909    // explicit conversions
910    int_type value() const { return operator int_type(); }
911    int to_int() const { return (int)m_val; }
912    unsigned int to_uint() const { return (unsigned int)m_val; }
913    long to_long() const { return (long)m_val; }
914    unsigned long to_ulong() const { return (unsigned long)m_val; }
915    int64 to_int64() const { return (int64)m_val; }
916    uint64 to_uint64() const { return (uint64)m_val; }
917    double to_double() const { return (double)m_val; }
918    long long_low() const { return (long)(m_val & UINT64_32ONES); }
919    long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); }
920
921
922    // explicit conversion to character string
923    const std::string to_string(sc_numrep numrep=SC_DEC) const;
924    const std::string to_string(sc_numrep numrep, bool w_prefix) const;
925
926
927    // other methods
928    void
929    print(::std::ostream &os=::std::cout) const
930    {
931        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
932    }
933
934    void scan(::std::istream &is=::std::cin);
935
936  protected:
937    int_type m_val; // value
938    int m_len; // length
939    int m_ulen; // unused length
940};
941
942inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &);
943inline ::std::istream &operator >> (::std::istream &, sc_int_base &);
944
945
946// ----------------------------------------------------------------------------
947//  CLASS : sc_int_bitref_r
948//
949//  Proxy class for sc_int bit selection (r-value only).
950// ----------------------------------------------------------------------------
951
952// implicit conversion to uint64
953
954inline sc_int_bitref_r::operator uint64 () const
955{
956    return m_obj_p->test(m_index);
957}
958
959inline bool
960sc_int_bitref_r::operator ! () const
961{
962    return ! m_obj_p->test(m_index);
963}
964
965inline bool
966sc_int_bitref_r::operator ~ () const
967{
968    return !m_obj_p->test(m_index);
969}
970
971
972inline ::std::ostream &
973operator << (::std::ostream &os, const sc_int_bitref_r &a)
974{
975    a.print(os);
976    return os;
977}
978
979
980// ----------------------------------------------------------------------------
981//  CLASS : sc_int_bitref
982//
983//  Proxy class for sc_int bit selection (r-value and l-value).
984// ----------------------------------------------------------------------------
985
986// assignment operators
987
988inline sc_int_bitref &
989sc_int_bitref::operator = (const sc_int_bitref_r &b)
990{
991    m_obj_p->set(m_index, (bool)b);
992    m_obj_p->extend_sign();
993    return *this;
994}
995
996inline sc_int_bitref &
997sc_int_bitref::operator = (const sc_int_bitref &b)
998{
999    m_obj_p->set(m_index, (bool)b);
1000    m_obj_p->extend_sign();
1001    return *this;
1002}
1003
1004inline sc_int_bitref &
1005sc_int_bitref::operator = (bool b)
1006{
1007    m_obj_p->set(m_index, b);
1008    m_obj_p->extend_sign();
1009    return *this;
1010}
1011
1012
1013inline sc_int_bitref &
1014sc_int_bitref::operator &= (bool b)
1015{
1016    if (!b) {
1017        m_obj_p->set(m_index, b);
1018        m_obj_p->extend_sign();
1019    }
1020    return *this;
1021}
1022
1023inline sc_int_bitref &
1024sc_int_bitref::operator |= (bool b)
1025{
1026    if (b) {
1027        m_obj_p->set(m_index, b);
1028        m_obj_p->extend_sign();
1029    }
1030    return *this;
1031}
1032
1033inline sc_int_bitref &
1034sc_int_bitref::operator ^= (bool b)
1035{
1036    if (b) {
1037        m_obj_p->m_val ^= (UINT_ONE << m_index);
1038        m_obj_p->extend_sign();
1039    }
1040    return *this;
1041}
1042
1043
1044
1045inline ::std::istream &
1046operator >> (::std::istream &is, sc_int_bitref &a)
1047{
1048    a.scan(is);
1049    return is;
1050}
1051
1052
1053// ----------------------------------------------------------------------------
1054//  CLASS : sc_int_subref_r
1055//
1056//  Proxy class for sc_int part selection (r-value only).
1057// ----------------------------------------------------------------------------
1058
1059// implicit conversion to int_type
1060
1061inline sc_int_subref_r::operator uint_type() const
1062{
1063    uint_type /*int_type*/ val = m_obj_p->m_val;
1064    int uleft = SC_INTWIDTH - (m_left + 1);
1065    int uright = uleft + m_right;
1066    return (val << uleft >> uright);
1067}
1068
1069
1070// reduce methods
1071
1072inline bool
1073sc_int_subref_r::and_reduce() const
1074{
1075    sc_int_base a(*this);
1076    return a.and_reduce();
1077}
1078
1079inline bool
1080sc_int_subref_r::or_reduce() const
1081{
1082    sc_int_base a(*this);
1083    return a.or_reduce();
1084}
1085
1086inline bool
1087sc_int_subref_r::xor_reduce() const
1088{
1089    sc_int_base a(*this);
1090    return a.xor_reduce();
1091}
1092
1093
1094// explicit conversions
1095
1096inline int
1097sc_int_subref_r::to_int() const
1098{
1099    int result = static_cast<int>(operator uint_type());
1100    return result;
1101}
1102
1103inline unsigned int
1104sc_int_subref_r::to_uint() const
1105{
1106    unsigned int result = static_cast<unsigned int>(operator uint_type());
1107    return result;
1108}
1109
1110inline long
1111sc_int_subref_r::to_long() const
1112{
1113    long result = static_cast<long>(operator uint_type());
1114    return result;
1115}
1116
1117inline unsigned long
1118sc_int_subref_r::to_ulong() const
1119{
1120    unsigned long result = static_cast<unsigned long>(operator uint_type());
1121    return result;
1122}
1123
1124inline int64
1125sc_int_subref_r::to_int64() const
1126{
1127    int64 result = operator uint_type();
1128    return result;
1129}
1130
1131inline uint64
1132sc_int_subref_r::to_uint64() const
1133{
1134    uint64 result = operator uint_type();
1135    return result;
1136}
1137
1138inline double
1139sc_int_subref_r::to_double() const
1140{
1141    double result = static_cast<double>(operator uint_type());
1142    return result;
1143}
1144
1145
1146// explicit conversion to character string
1147
1148inline const std::string
1149sc_int_subref_r::to_string(sc_numrep numrep) const
1150{
1151    sc_uint_base a(length());
1152    a = operator uint_type();
1153    return a.to_string(numrep);
1154}
1155
1156inline const std::string
1157sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
1158{
1159    sc_uint_base a(length());
1160    a = operator uint_type();
1161    return a.to_string(numrep, w_prefix);
1162}
1163
1164
1165// functional notation for the reduce methods
1166
1167inline bool
1168and_reduce(const sc_int_subref_r &a)
1169{
1170    return a.and_reduce();
1171}
1172
1173inline bool
1174nand_reduce(const sc_int_subref_r &a)
1175{
1176    return a.nand_reduce();
1177}
1178
1179inline bool
1180or_reduce(const sc_int_subref_r &a)
1181{
1182    return a.or_reduce();
1183}
1184
1185inline bool
1186nor_reduce(const sc_int_subref_r &a)
1187{
1188    return a.nor_reduce();
1189}
1190
1191inline bool
1192xor_reduce(const sc_int_subref_r &a)
1193{
1194    return a.xor_reduce();
1195}
1196
1197inline bool
1198xnor_reduce(const sc_int_subref_r &a)
1199{
1200    return a.xnor_reduce();
1201}
1202
1203
1204
1205inline ::std::ostream &
1206operator << (::std::ostream &os, const sc_int_subref_r &a)
1207{
1208    a.print(os);
1209    return os;
1210}
1211
1212
1213// ----------------------------------------------------------------------------
1214//  CLASS : sc_int_subref
1215//
1216//  Proxy class for sc_int part selection (r-value and l-value).
1217// ----------------------------------------------------------------------------
1218
1219// assignment operators
1220
1221inline sc_int_subref &
1222sc_int_subref::operator = (const sc_int_base &a)
1223{
1224    return operator = (a.operator int_type());
1225}
1226
1227inline sc_int_subref &
1228sc_int_subref::operator = (const char *a)
1229{
1230    sc_int_base aa(length());
1231    return (*this = aa = a);
1232}
1233
1234
1235
1236inline ::std::istream &
1237operator >> (::std::istream &is, sc_int_subref &a)
1238{
1239    a.scan(is);
1240    return is;
1241}
1242
1243
1244// ----------------------------------------------------------------------------
1245//  CLASS : sc_int_base
1246//
1247//  Base class for sc_int.
1248// ----------------------------------------------------------------------------
1249
1250// bit selection
1251
1252inline sc_int_bitref &
1253sc_int_base::operator [] (int i)
1254{
1255    check_index(i);
1256    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1257    result_p->initialize(this, i);
1258    return *result_p;
1259}
1260
1261inline const sc_int_bitref_r &
1262sc_int_base::operator [] (int i) const
1263{
1264    check_index(i);
1265    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1266    result_p->initialize(this, i);
1267    return *result_p;
1268}
1269
1270
1271inline sc_int_bitref &
1272sc_int_base::bit(int i)
1273{
1274    check_index(i);
1275    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1276    result_p->initialize(this, i);
1277    return *result_p;
1278}
1279
1280inline const sc_int_bitref_r &
1281sc_int_base::bit(int i) const
1282{
1283    check_index(i);
1284    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
1285    result_p->initialize(this, i);
1286    return *result_p;
1287}
1288
1289
1290// part selection
1291
1292inline sc_int_subref &
1293sc_int_base::operator () (int left, int right)
1294{
1295    check_range(left, right);
1296    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1297    result_p->initialize(this, left, right);
1298    return *result_p;
1299}
1300
1301inline const sc_int_subref_r &
1302sc_int_base::operator () (int left, int right) const
1303{
1304    check_range(left, right);
1305    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1306    result_p->initialize(this, left, right);
1307    return *result_p;
1308}
1309
1310
1311inline sc_int_subref &
1312sc_int_base::range(int left, int right)
1313{
1314    check_range(left, right);
1315    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1316    result_p->initialize(this, left, right);
1317    return *result_p;
1318}
1319
1320inline const sc_int_subref_r &
1321sc_int_base::range(int left, int right) const
1322{
1323    check_range(left, right);
1324    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
1325    result_p->initialize(this, left, right);
1326    return *result_p;
1327}
1328
1329
1330// functional notation for the reduce methods
1331
1332inline bool
1333and_reduce(const sc_int_base &a)
1334{
1335    return a.and_reduce();
1336}
1337
1338inline bool
1339nand_reduce(const sc_int_base &a)
1340{
1341    return a.nand_reduce();
1342}
1343
1344inline bool
1345or_reduce(const sc_int_base &a)
1346{
1347    return a.or_reduce();
1348}
1349
1350inline bool
1351nor_reduce(const sc_int_base &a)
1352{
1353    return a.nor_reduce();
1354}
1355
1356inline bool
1357xor_reduce(const sc_int_base &a)
1358{
1359    return a.xor_reduce();
1360}
1361
1362inline bool
1363xnor_reduce(const sc_int_base &a)
1364{
1365    return a.xnor_reduce();
1366}
1367
1368
1369
1370inline ::std::ostream &
1371operator << (::std::ostream &os, const sc_int_base &a)
1372{
1373    a.print(os);
1374    return os;
1375}
1376
1377inline ::std::istream &
1378operator >> (::std::istream &is, sc_int_base &a)
1379{
1380    a.scan(is);
1381    return is;
1382}
1383
1384} // namespace sc_dt
1385
1386#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
1387