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