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