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_proxy.h -- Proxy base class for vector data types.
23
24                This class is created for several purposes:
25                1) hiding operators from the global namespace that would be
26		   otherwise found by Koenig lookup
27                2) avoiding repeating the same operations in every class
28		   including proxies that could also be achieved by common
29		   base class, but this method allows
30                3) improve performance by using non-virtual functions
31
32  Original Author: Gene Bushuyev, Synopsys, Inc.
33
34 *****************************************************************************/
35
36/*****************************************************************************
37
38  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
39  changes you are making here.
40
41      Name, Affiliation, Date:
42  Description of Modification:
43
44 *****************************************************************************/
45
46// $Log: sc_proxy.h,v $
47// Revision 1.3  2010/12/07 20:09:07  acg
48// Andy Goodrich: Fix for returning enough data
49//
50// Revision 1.2  2009/02/28 00:26:14  acg
51//  Andy Goodrich: bug fixes.
52//
53// Revision 1.1.1.1  2006/12/15 20:31:36  acg
54// SystemC 2.2
55//
56// Revision 1.3  2006/01/13 18:53:53  acg
57// Andy Goodrich: added $Log command so that CVS comments are reproduced in
58// the source.
59//
60
61#ifndef SC_PROXY_H
62#define SC_PROXY_H
63
64
65#include "sysc/kernel/sc_cmnhdr.h"
66#include "sysc/utils/sc_iostream.h"
67#include "sysc/datatypes/int/sc_signed.h"
68#include "sysc/datatypes/int/sc_unsigned.h"
69#include "sysc/datatypes/int/sc_int_base.h"
70#include "sysc/datatypes/int/sc_uint_base.h"
71#include "sysc/datatypes/bit/sc_bit.h"
72#include "sysc/datatypes/bit/sc_bit_ids.h"
73#include "sysc/datatypes/bit/sc_logic.h"
74#include "sysc/kernel/sc_macros.h"
75
76
77namespace sc_dt
78{
79
80// classes defined in this module
81template <class X> class sc_proxy;
82
83// forward class declarations
84class sc_bv_base;
85class sc_lv_base;
86template <class X> class sc_bitref_r;
87template <class X> class sc_bitref;
88template <class X> class sc_subref_r;
89template <class X> class sc_subref;
90template <class X, class Y> class sc_concref_r;
91template <class X, class Y> class sc_concref;
92
93
94const int SC_DIGIT_SIZE = BITS_PER_BYTE * sizeof( sc_digit );
95
96const sc_digit SC_DIGIT_ZERO = (sc_digit)0;
97const sc_digit SC_DIGIT_ONE  = (sc_digit)1;
98const sc_digit SC_DIGIT_TWO  = (sc_digit)2;
99
100
101// assignment functions; forward declarations
102
103template <class X, class Y>
104inline
105void
106assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py );
107
108// Vector types that are not derived from sc_proxy must have a length()
109// function and an operator [].
110
111template <class X, class T>
112inline
113void
114assign_v_( sc_proxy<X>& px, const T& a );
115
116
117// other functions; forward declarations
118
119const std::string convert_to_bin( const char* s );
120const std::string convert_to_fmt( const std::string& s, sc_numrep numrep, bool );
121
122// ----------------------------------------------------------------------------
123//  CLASS TEMPLATE : sc_proxy_traits
124//
125// Template traits helper to select the correct bit/value/vector_types for
126// sc_proxy-based vector classes.
127//
128// All types derived from/based on a bit-vector contain typedef to a plain bool,
129// all others point to the sc_logic_value_t/sc_logic/sc_lv_base types.
130// ----------------------------------------------------------------------------
131
132template<typename X> struct sc_proxy_traits;
133
134template<> struct sc_proxy_traits<sc_bv_base>
135{
136    typedef sc_proxy_traits<sc_bv_base> traits_type;
137    typedef bool                        value_type;
138    typedef bool                        bit_type;
139    typedef sc_bv_base                  vector_type;
140    typedef traits_type                 type;
141};
142
143template<> struct sc_proxy_traits<sc_lv_base>
144{
145    typedef sc_proxy_traits<sc_lv_base> traits_type;
146    typedef sc_logic_value_t            value_type;
147    typedef sc_logic                    bit_type;
148    typedef sc_lv_base                  vector_type;
149    typedef traits_type                 type;
150};
151
152
153template<typename X> struct sc_proxy_traits<sc_bitref_r<X> >
154  : sc_proxy_traits<X> {};
155
156template<typename X> struct sc_proxy_traits<sc_bitref<X> >
157  : sc_proxy_traits<X> {};
158
159
160template<typename X> struct sc_proxy_traits<sc_subref_r<X> >
161  : sc_proxy_traits<X> {};
162
163template<typename X> struct sc_proxy_traits<sc_subref<X> >
164  : sc_proxy_traits<X> {};
165
166
167template<typename X> struct sc_proxy_traits<sc_proxy<X> >
168  : sc_proxy_traits<X> {};
169
170
171template< typename X, typename Y > struct sc_mixed_proxy_traits_helper
172  : sc_proxy_traits<sc_lv_base> {}; // logic vector by default
173
174template<typename X> struct sc_mixed_proxy_traits_helper<X,X>
175  : X {};
176
177
178template<typename X, typename Y> struct sc_proxy_traits< sc_concref_r<X,Y> >
179  : sc_mixed_proxy_traits_helper< typename X::traits_type::type
180                                , typename Y::traits_type::type >
181{};
182
183template<typename X, typename Y> struct sc_proxy_traits<sc_concref<X,Y> >
184  : sc_mixed_proxy_traits_helper< typename X::traits_type::type
185                                , typename Y::traits_type::type >
186{};
187
188
189// ----------------------------------------------------------------------------
190//  CLASS TEMPLATE : sc_proxy
191//
192//  Base class template for bit/logic vector classes.
193//  (Barton/Nackmann implementation)
194// ----------------------------------------------------------------------------
195
196template <class X>
197class sc_proxy // #### : public sc_value_base
198{
199public:
200    typedef typename sc_proxy_traits<X>::type traits_type;
201    typedef typename traits_type::bit_type    bit_type;
202
203    // virtual destructor
204
205    virtual ~sc_proxy() {}
206
207
208    // casts
209
210    X& back_cast()
211	{ return SCAST<X&>( *this ); }
212
213    const X& back_cast() const
214	{ return SCAST<const X&>( *this ); }
215
216
217    // assignment operators
218
219    template <class Y>
220    X& assign_( const sc_proxy<Y>& a )
221	{ assign_p_( *this, a ); return back_cast(); }
222
223    X& assign_( const char* a );
224    X& assign_( const bool* a );
225    X& assign_( const sc_logic* a );
226
227    X& assign_( const sc_unsigned& a )
228	{ assign_v_( *this, a ); return back_cast(); }
229
230    X& assign_( const sc_signed& a )
231	{ assign_v_( *this, a ); return back_cast(); }
232
233    X& assign_( const sc_uint_base& a )
234	{ return assign_( (uint64) a ); }
235
236    X& assign_( const sc_int_base& a )
237	{ return assign_( (int64) a ); }
238
239    X& assign_( unsigned int a );
240    X& assign_( int a );
241
242    X& assign_( unsigned long a );
243
244    X& assign_( long a );
245
246    X& assign_( uint64 a );
247    X& assign_( int64 a );
248
249
250    // bitwise operators and functions
251
252    // bitwise complement
253
254    X& b_not();
255
256    const sc_lv_base operator ~ () const;
257
258
259    // bitwise and
260
261    X& operator &= ( const char* b );
262    X& operator &= ( const bool* b );
263    X& operator &= ( const sc_logic* b );
264    X& operator &= ( const sc_unsigned& b );
265    X& operator &= ( const sc_signed& b );
266
267    X& operator &= ( const sc_uint_base& b )
268	{ return operator &= ( (uint64) b ); }
269
270    X& operator &= ( const sc_int_base& b )
271	{ return operator &= ( (int64) b ); }
272
273    X& operator &= ( unsigned long b );
274    X& operator &= ( long b );
275
276    X& operator &= ( unsigned int b )
277	{ return operator &= ( (unsigned long) b ); }
278
279    X& operator &= ( int b )
280	{ return operator &= ( (long) b ); }
281
282    X& operator &= ( uint64 b );
283    X& operator &= ( int64 b );
284
285
286    const sc_lv_base operator & ( const char* b ) const;
287    const sc_lv_base operator & ( const bool* b ) const;
288    const sc_lv_base operator & ( const sc_logic* b ) const;
289    const sc_lv_base operator & ( const sc_unsigned& b ) const;
290    const sc_lv_base operator & ( const sc_signed& b ) const;
291    const sc_lv_base operator & ( const sc_uint_base& b ) const;
292    const sc_lv_base operator & ( const sc_int_base& b ) const;
293    const sc_lv_base operator & ( unsigned long b ) const;
294    const sc_lv_base operator & ( long b ) const;
295    const sc_lv_base operator & ( unsigned int b ) const;
296    const sc_lv_base operator & ( int b ) const;
297    const sc_lv_base operator & ( uint64 b ) const;
298    const sc_lv_base operator & ( int64 b ) const;
299
300
301    // bitwise or
302
303    X& operator |= ( const char* b );
304    X& operator |= ( const bool* b );
305    X& operator |= ( const sc_logic* b );
306    X& operator |= ( const sc_unsigned& b );
307    X& operator |= ( const sc_signed& b );
308
309    X& operator |= ( const sc_uint_base& b )
310	{ return operator |= ( (uint64) b ); }
311
312    X& operator |= ( const sc_int_base& b )
313	{ return operator |= ( (int64) b ); }
314
315    X& operator |= ( unsigned long b );
316    X& operator |= ( long b );
317
318    X& operator |= ( unsigned int b )
319	{ return operator |= ( (unsigned long) b ); }
320
321    X& operator |= ( int b )
322	{ return operator |= ( (long) b ); }
323
324    X& operator |= ( uint64 b );
325    X& operator |= ( int64 b );
326
327
328    const sc_lv_base operator | ( const char* b ) const;
329    const sc_lv_base operator | ( const bool* b ) const;
330    const sc_lv_base operator | ( const sc_logic* b ) const;
331    const sc_lv_base operator | ( const sc_unsigned& b ) const;
332    const sc_lv_base operator | ( const sc_signed& b ) const;
333    const sc_lv_base operator | ( const sc_uint_base& b ) const;
334    const sc_lv_base operator | ( const sc_int_base& b ) const;
335    const sc_lv_base operator | ( unsigned long b ) const;
336    const sc_lv_base operator | ( long b ) const;
337    const sc_lv_base operator | ( unsigned int b ) const;
338    const sc_lv_base operator | ( int b ) const;
339    const sc_lv_base operator | ( uint64 b ) const;
340    const sc_lv_base operator | ( int64 b ) const;
341
342
343    // bitwise xor
344
345    X& operator ^= ( const char* b );
346    X& operator ^= ( const bool* b );
347    X& operator ^= ( const sc_logic* b );
348    X& operator ^= ( const sc_unsigned& b );
349    X& operator ^= ( const sc_signed& b );
350
351    X& operator ^= ( const sc_uint_base& b )
352	{ return operator ^= ( (uint64) b ); }
353
354    X& operator ^= ( const sc_int_base& b )
355	{ return operator ^= ( (int64) b ); }
356
357    X& operator ^= ( unsigned long b );
358    X& operator ^= ( long b );
359
360    X& operator ^= ( unsigned int b )
361	{ return operator ^= ( (unsigned long) b ); }
362
363    X& operator ^= ( int b )
364	{ return operator ^= ( (long) b ); }
365
366    X& operator ^= ( uint64 b );
367    X& operator ^= ( int64 b );
368
369
370    const sc_lv_base operator ^ ( const char* b ) const;
371    const sc_lv_base operator ^ ( const bool* b ) const;
372    const sc_lv_base operator ^ ( const sc_logic* b ) const;
373    const sc_lv_base operator ^ ( const sc_unsigned& b ) const;
374    const sc_lv_base operator ^ ( const sc_signed& b ) const;
375    const sc_lv_base operator ^ ( const sc_uint_base& b ) const;
376    const sc_lv_base operator ^ ( const sc_int_base& b ) const;
377    const sc_lv_base operator ^ ( unsigned long b ) const;
378    const sc_lv_base operator ^ ( long b ) const;
379    const sc_lv_base operator ^ ( unsigned int b ) const;
380    const sc_lv_base operator ^ ( int b ) const;
381    const sc_lv_base operator ^ ( uint64 b ) const;
382    const sc_lv_base operator ^ ( int64 b ) const;
383
384
385    // bitwise left shift
386
387    X& operator <<= ( int n );
388
389    const sc_lv_base operator << ( int n ) const;
390
391
392    // bitwise right shift
393
394    X& operator >>= ( int n );
395
396    const sc_lv_base operator >> ( int n ) const;
397
398
399    // bitwise left rotate
400
401    X& lrotate( int n );
402
403
404    // bitwise right rotate
405
406    X& rrotate( int n );
407
408
409    // bitwise reverse
410
411    X& reverse();
412
413
414    // bit selection
415
416    sc_bitref<X> operator [] ( int i )
417	{ return sc_bitref<X>( back_cast(), i ); }
418
419    sc_bitref_r<X> operator [] ( int i ) const
420	{ return sc_bitref_r<X>( back_cast(), i ); }
421
422    sc_bitref<X> bit( int i )
423	{ return sc_bitref<X>( back_cast(), i ); }
424
425    sc_bitref_r<X> bit( int i ) const
426	{ return sc_bitref_r<X>( back_cast(), i ); }
427
428
429    // part selection
430
431    sc_subref<X> operator () ( int hi, int lo )
432	{ return sc_subref<X>( back_cast(), hi, lo ); }
433
434    sc_subref_r<X> operator () ( int hi, int lo ) const
435	{ return sc_subref_r<X>( back_cast(), hi, lo ); }
436
437    sc_subref<X> range( int hi, int lo )
438	{ return sc_subref<X>( back_cast(), hi, lo ); }
439
440    sc_subref_r<X> range( int hi, int lo ) const
441	{ return sc_subref_r<X>( back_cast(), hi, lo ); }
442
443
444    // reduce functions
445
446    sc_logic_value_t and_reduce() const;
447
448    sc_logic_value_t nand_reduce() const
449	{ return sc_logic::not_table[and_reduce()]; }
450
451    sc_logic_value_t or_reduce() const;
452
453    sc_logic_value_t nor_reduce() const
454	{ return sc_logic::not_table[or_reduce()]; }
455
456    sc_logic_value_t xor_reduce() const;
457
458    sc_logic_value_t xnor_reduce() const
459	{ return sc_logic::not_table[xor_reduce()]; }
460
461
462    // relational operators
463
464    bool operator == ( const char* b ) const;
465    bool operator == ( const bool* b ) const;
466    bool operator == ( const sc_logic* b ) const;
467    bool operator == ( const sc_unsigned& b ) const;
468    bool operator == ( const sc_signed& b ) const;
469    bool operator == ( const sc_uint_base& b ) const;
470    bool operator == ( const sc_int_base& b ) const;
471    bool operator == ( unsigned long b ) const;
472    bool operator == ( long b ) const;
473    bool operator == ( unsigned int b ) const;
474    bool operator == ( int b ) const;
475    bool operator == ( uint64 b ) const;
476    bool operator == ( int64 b ) const;
477
478
479    // explicit conversions to character string
480
481    const std::string to_string() const;
482    const std::string to_string( sc_numrep ) const;
483    const std::string to_string( sc_numrep, bool ) const;
484
485
486    // explicit conversions
487
488    inline int64 to_int64() const
489	{ return to_anything_signed(); }
490    inline uint64 to_uint64() const;
491    int to_int() const
492	{ return (int)to_anything_signed(); }
493
494    unsigned int to_uint() const
495	{ return (unsigned int)to_anything_unsigned(); }
496
497    long to_long() const
498	{ return (long)to_anything_signed(); }
499
500    unsigned long to_ulong() const
501	{ return (unsigned long)to_anything_unsigned(); }
502
503#ifdef SC_DT_DEPRECATED
504
505    int to_signed() const
506	{ return to_int(); }
507
508    sc_digit to_unsigned() const
509	{ return to_uint(); }
510
511#endif
512
513
514    // other methods
515
516    void print( ::std::ostream& os = ::std::cout ) const
517	{
518	    // the test below will force printing in binary if decimal is
519	    // specified.
520	    if ( sc_io_base(os, SC_DEC) == SC_DEC )
521	        os << to_string();
522	    else
523	        os << to_string(sc_io_base(os,SC_BIN),sc_io_show_base(os));
524	}
525
526    void scan( ::std::istream& is = ::std::cin );
527
528protected:
529
530    void check_bounds( int n ) const;  // check if bit n accessible
531    void check_wbounds( int n ) const; // check if word n accessible
532
533    sc_digit to_anything_unsigned() const;
534    int64 to_anything_signed() const;
535};
536
537
538// ----------------------------------------------------------------------------
539
540// bitwise operators and functions
541
542// bitwise and
543
544template <class X, class Y>
545inline
546X&
547operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
548
549
550template <class X, class Y>
551inline
552const sc_lv_base
553operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
554
555
556#define DECL_BITWISE_AND_OP_T(tp)                                             \
557template <class X>                                                            \
558inline                                                                        \
559const sc_lv_base                                                              \
560operator & ( tp b, const sc_proxy<X>& px );
561
562DECL_BITWISE_AND_OP_T(const char*)
563DECL_BITWISE_AND_OP_T(const bool*)
564DECL_BITWISE_AND_OP_T(const sc_logic*)
565DECL_BITWISE_AND_OP_T(const sc_unsigned&)
566DECL_BITWISE_AND_OP_T(const sc_signed&)
567DECL_BITWISE_AND_OP_T(const sc_uint_base&)
568DECL_BITWISE_AND_OP_T(const sc_int_base&)
569DECL_BITWISE_AND_OP_T(unsigned long)
570DECL_BITWISE_AND_OP_T(long)
571DECL_BITWISE_AND_OP_T(unsigned int)
572DECL_BITWISE_AND_OP_T(int)
573DECL_BITWISE_AND_OP_T(uint64)
574DECL_BITWISE_AND_OP_T(int64)
575
576#undef DECL_BITWISE_AND_OP_T
577
578
579// bitwise or
580
581template <class X, class Y>
582inline
583X&
584operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
585
586
587template <class X, class Y>
588inline
589const sc_lv_base
590operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
591
592
593#define DECL_BITWISE_OR_OP_T(tp)                                              \
594template <class X>                                                            \
595inline                                                                        \
596const sc_lv_base                                                              \
597operator | ( tp a, const sc_proxy<X>& px );
598
599DECL_BITWISE_OR_OP_T(const char*)
600DECL_BITWISE_OR_OP_T(const bool*)
601DECL_BITWISE_OR_OP_T(const sc_logic*)
602DECL_BITWISE_OR_OP_T(const sc_unsigned&)
603DECL_BITWISE_OR_OP_T(const sc_signed&)
604DECL_BITWISE_OR_OP_T(const sc_uint_base&)
605DECL_BITWISE_OR_OP_T(const sc_int_base&)
606DECL_BITWISE_OR_OP_T(unsigned long)
607DECL_BITWISE_OR_OP_T(long)
608DECL_BITWISE_OR_OP_T(unsigned int)
609DECL_BITWISE_OR_OP_T(int)
610DECL_BITWISE_OR_OP_T(uint64)
611DECL_BITWISE_OR_OP_T(int64)
612
613#undef DECL_BITWISE_OR_OP_T
614
615
616// bitwise xor
617
618template <class X, class Y>
619inline
620X&
621operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py );
622
623
624template <class X, class Y>
625inline
626const sc_lv_base
627operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
628
629
630#define DECL_BITWISE_XOR_OP_T(tp)                                             \
631template <class X>                                                            \
632inline                                                                        \
633const sc_lv_base                                                              \
634operator ^ ( tp a, const sc_proxy<X>& px );
635
636DECL_BITWISE_XOR_OP_T(const char*)
637DECL_BITWISE_XOR_OP_T(const bool*)
638DECL_BITWISE_XOR_OP_T(const sc_logic*)
639DECL_BITWISE_XOR_OP_T(const sc_unsigned&)
640DECL_BITWISE_XOR_OP_T(const sc_signed&)
641DECL_BITWISE_XOR_OP_T(const sc_uint_base&)
642DECL_BITWISE_XOR_OP_T(const sc_int_base&)
643DECL_BITWISE_XOR_OP_T(unsigned long)
644DECL_BITWISE_XOR_OP_T(long)
645DECL_BITWISE_XOR_OP_T(unsigned int)
646DECL_BITWISE_XOR_OP_T(int)
647DECL_BITWISE_XOR_OP_T(uint64)
648DECL_BITWISE_XOR_OP_T(int64)
649
650#undef DECL_BITWISE_XOR_OP_T
651
652
653// relational operators
654
655template <class X, class Y>
656inline
657bool
658operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
659
660template <class X, class Y>
661inline
662bool
663operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py );
664
665
666#define DECL_REL_OP_T(tp)                                                     \
667template <class X>                                                            \
668inline                                                                        \
669bool                                                                          \
670operator == ( tp b, const sc_proxy<X>& px );                                  \
671                                                                              \
672template <class X>                                                            \
673inline                                                                        \
674bool                                                                          \
675operator != ( const sc_proxy<X>& px, tp b );                                  \
676                                                                              \
677template <class X>                                                            \
678inline                                                                        \
679bool                                                                          \
680operator != ( tp b, const sc_proxy<X>& px );
681
682DECL_REL_OP_T(const char*)
683DECL_REL_OP_T(const bool*)
684DECL_REL_OP_T(const sc_logic*)
685DECL_REL_OP_T(const sc_unsigned&)
686DECL_REL_OP_T(const sc_signed&)
687DECL_REL_OP_T(const sc_uint_base&)
688DECL_REL_OP_T(const sc_int_base&)
689DECL_REL_OP_T(unsigned long)
690DECL_REL_OP_T(long)
691DECL_REL_OP_T(unsigned int)
692DECL_REL_OP_T(int)
693DECL_REL_OP_T(uint64)
694DECL_REL_OP_T(int64)
695
696#undef DECL_REL_OP_T
697
698
699// l-value concatenation
700
701// Due to the fact that temporary objects cannot be passed to non-const
702// references, we have to enumerate, use call by value, and use dynamic
703// memory allocation (and deallocation).
704
705
706// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
707
708template <class X>
709inline
710void
711get_words_( const X& x, int wi, sc_digit& x_dw, sc_digit& x_cw )
712{
713    x_dw = x.get_word( wi );
714    x_cw = x.get_cword( wi );
715}
716
717template <class X>
718inline
719void
720set_words_( X& x, int wi, sc_digit x_dw, sc_digit x_cw )
721{
722    x.set_word( wi, x_dw );
723    x.set_cword( wi, x_cw );
724}
725
726template <class X>
727inline
728void
729extend_sign_w_( X& x, int wi, bool sign )
730{
731    int sz = x.size();
732    unsigned int sgn = (sign ? ~SC_DIGIT_ZERO : SC_DIGIT_ZERO);
733    for( int i = wi; i < sz; ++ i ) {
734	set_words_( x, i, sgn, SC_DIGIT_ZERO );
735    }
736}
737
738
739// assignment functions
740
741template <class X, class Y>
742inline
743void
744assign_p_( sc_proxy<X>& px, const sc_proxy<Y>& py )
745{
746    if( (void*) &px != (void*) &py ) {
747	X& x = px.back_cast();
748	const Y& y = py.back_cast();
749	int sz = x.size();
750	int min_sz = sc_min( sz, y.size() );
751	int i = 0;
752	for( ; i < min_sz; ++ i ) {
753	    set_words_( x, i, y.get_word( i ), y.get_cword( i ) );
754	}
755	// extend with zeros
756	extend_sign_w_( x, i, false );
757	x.clean_tail();
758    }
759}
760
761// Vector types that are not derived from sc_proxy, sc_int_base,
762// sc_uint_base, sc_signed, or sc_unsigned, must have a length()
763// function and an operator []. The vector argument type must support
764// accessing bits that are beyond the msb. The vector argument type
765// decides what to do there (e.g. sign extension or zero padding).
766
767template <class X, class T>
768inline
769void
770assign_v_( sc_proxy<X>& px, const T& a )
771{
772    X& x = px.back_cast();
773    int i;
774    int len_x = x.length();
775    int len_a = a.length();
776    if ( len_a > len_x ) len_a = len_x;
777    for( i = 0 ; i < len_a; ++ i ) {
778        x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
779    }
780    for( ; i < len_x; ++ i ) {
781        x.set_bit( i, sc_logic_value_t( false ) );
782    }
783}
784
785template <class X>
786inline
787void
788assign_v_( sc_proxy<X>& px, const sc_int_base& a )
789{
790    X& x = px.back_cast();
791	int i;
792    bool sign = a < 0;
793    int len_x = x.length();
794    int len_a = a.length();
795    if ( len_a > len_x ) len_a = len_x;
796    for( i = 0 ; i < len_a; ++ i ) {
797        x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
798    }
799    for( ; i < len_x; ++ i ) {
800        x.set_bit( i, sc_logic_value_t( sign ) );
801    }
802}
803
804template <class X>
805inline
806void
807assign_v_( sc_proxy<X>& px, const sc_signed& a )
808{
809    X& x = px.back_cast();
810	int i;
811    bool sign = a < 0;
812    int len_x = x.length();
813    int len_a = a.length();
814    if ( len_a > len_x ) len_a = len_x;
815    for( i = 0 ; i < len_a; ++ i ) {
816        x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
817    }
818    for( ; i < len_x; ++ i ) {
819        x.set_bit( i, sc_logic_value_t( sign ) );
820    }
821}
822
823template <class X>
824inline
825void
826assign_v_( sc_proxy<X>& px, const sc_uint_base& a )
827{
828    X& x = px.back_cast();
829	int i;
830    int len_x = x.length();
831    int len_a = a.length();
832    if ( len_a > len_x ) len_a = len_x;
833    for( i = 0 ; i < len_a; ++ i ) {
834        x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
835    }
836    for( ; i < len_x; ++ i ) {
837        x.set_bit( i, sc_logic_value_t( false ) );
838    }
839}
840
841template <class X>
842inline
843void
844assign_v_( sc_proxy<X>& px, const sc_unsigned& a )
845{
846    X& x = px.back_cast();
847	int i;
848    int len_x = x.length();
849    int len_a = a.length();
850    if ( len_a > len_x ) len_a = len_x;
851    for( i = 0 ; i < len_a; ++ i ) {
852        x.set_bit( i, sc_logic_value_t( (bool) a[i] ) );
853    }
854    for( ; i < len_x; ++ i ) {
855        x.set_bit( i, sc_logic_value_t( false ) );
856    }
857}
858
859
860// assignment operators
861
862template <class X>
863inline
864X&
865sc_proxy<X>::assign_( const char* a )
866{
867    X& x = back_cast();
868    std::string s = convert_to_bin( a );
869    int len = x.length();
870    int s_len = s.length() - 1;
871    int min_len = sc_min( len, s_len );
872    int i = 0;
873    for( ; i < min_len; ++ i ) {
874	char c = s[s_len - i - 1];
875	x.set_bit( i, sc_logic::char_to_logic[(int)c] );
876    }
877    // if formatted, fill the rest with sign(s), otherwise fill with zeros
878    sc_logic_value_t fill = (s[s_len] == 'F' ? sc_logic_value_t( s[0] - '0' )
879		                             : sc_logic_value_t( 0 ));
880    for( ; i < len; ++ i ) {
881	x.set_bit( i, fill );
882    }
883    return x;
884}
885
886template <class X>
887inline
888X&
889sc_proxy<X>::assign_( const bool* a )
890{
891    // the length of 'a' must be larger than or equal to the length of 'this'
892    X& x = back_cast();
893    int len = x.length();
894    for( int i = 0; i < len; ++ i ) {
895	x.set_bit( i, sc_logic_value_t( a[i] ) );
896    }
897    return x;
898}
899
900template <class X>
901inline
902X&
903sc_proxy<X>::assign_( const sc_logic* a )
904{
905    // the length of 'a' must be larger than or equal to the length of 'this'
906    X& x = back_cast();
907    int len = x.length();
908    for( int i = 0; i < len; ++ i ) {
909	x.set_bit( i, a[i].value() );
910    }
911    return x;
912}
913
914template <class X>
915inline
916X&
917sc_proxy<X>::assign_( unsigned int a )
918{
919    X& x = back_cast();
920    set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
921    // extend with zeros
922    extend_sign_w_( x, 1, false );
923    x.clean_tail();
924    return x;
925}
926
927template <class X>
928inline
929X&
930sc_proxy<X>::assign_( int a )
931{
932    X& x = back_cast();
933    set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
934    // extend with sign(a)
935    extend_sign_w_( x, 1, (a < 0) );
936    x.clean_tail();
937    return x;
938}
939
940#if defined(SC_LONG_64)
941	template <class X>
942	inline
943	X&
944	sc_proxy<X>::assign_( unsigned long a )
945	{
946		X& x = back_cast();
947		set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
948		if( x.size() > 1 ) {
949			set_words_( x, 1,
950				((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
951					SC_DIGIT_ZERO );
952		// extend with zeros
953		extend_sign_w_( x, 2, false );
954		}
955		x.clean_tail();
956		return x;
957	}
958
959	template <class X>
960	inline
961	X&
962	sc_proxy<X>::assign_( long a )
963	{
964		X& x = back_cast();
965		set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
966		if( x.size() > 1 ) {
967			set_words_( x, 1,
968				((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
969				SC_DIGIT_ZERO );
970		// extend with sign(a)
971		extend_sign_w_( x, 2, (a < 0) );
972		}
973		x.clean_tail();
974		return x;
975	}
976
977#else
978    template <class X>
979    inline
980    X&
981    sc_proxy<X>::assign_( unsigned long a )
982    {
983        X& x = back_cast();
984        set_words_( x, 0, (sc_digit)a, SC_DIGIT_ZERO );
985        // extend with zeros
986        extend_sign_w_( x, 1, false );
987        x.clean_tail();
988        return x;
989    }
990
991    template <class X>
992    inline
993    X&
994    sc_proxy<X>::assign_( long a )
995    {
996        X& x = back_cast();
997        set_words_( x, 0, (sc_digit) a, SC_DIGIT_ZERO );
998        // extend with sign(a)
999        extend_sign_w_( x, 1, (a < 0) );
1000        x.clean_tail();
1001        return x;
1002    }
1003#endif
1004template <class X>
1005inline
1006X&
1007sc_proxy<X>::assign_( uint64 a )
1008{
1009    X& x = back_cast();
1010    set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
1011    if( x.size() > 1 ) {
1012	set_words_( x, 1,
1013		    ((sc_digit) (a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
1014		    SC_DIGIT_ZERO );
1015	// extend with zeros
1016	extend_sign_w_( x, 2, false );
1017    }
1018    x.clean_tail();
1019    return x;
1020}
1021
1022template <class X>
1023inline
1024X&
1025sc_proxy<X>::assign_( int64 a )
1026{
1027    X& x = back_cast();
1028    set_words_( x, 0, ((sc_digit) a & ~SC_DIGIT_ZERO), SC_DIGIT_ZERO );
1029    if( x.size() > 1 ) {
1030	set_words_( x, 1,
1031		    ((sc_digit) ((uint64) a >> SC_DIGIT_SIZE) & ~SC_DIGIT_ZERO),
1032		    SC_DIGIT_ZERO );
1033	// extend with sign(a)
1034	extend_sign_w_( x, 2, (a < 0) );
1035    }
1036    x.clean_tail();
1037    return x;
1038}
1039
1040
1041// bitwise operators and functions
1042
1043// bitwise complement
1044
1045template <class X>
1046inline
1047X&
1048sc_proxy<X>::b_not()
1049{
1050    X& x = back_cast();
1051    int sz = x.size();
1052    for( int i = 0; i < sz; ++ i ) {
1053	sc_digit x_dw, x_cw;
1054	get_words_( x, i, x_dw, x_cw );
1055	x.set_word( i, x_cw | ~x_dw );
1056    }
1057    x.clean_tail();
1058    return x;
1059}
1060
1061
1062// bitwise and
1063
1064template <class X, class Y>
1065inline
1066X&
1067b_and_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
1068{
1069    X& x = px.back_cast();
1070    const Y& y = py.back_cast();
1071    assert( x.length() == y.length() );
1072    int sz = x.size();
1073    for( int i = 0; i < sz; ++ i ) {
1074	sc_digit x_dw, x_cw, y_dw, y_cw;
1075	get_words_( x, i, x_dw, x_cw );
1076	get_words_( y, i, y_dw, y_cw );
1077	sc_digit cw = (x_dw & y_cw) | (x_cw & y_dw) | (x_cw & y_cw);
1078	sc_digit dw = cw | (x_dw & y_dw);
1079	set_words_( x, i, dw, cw );
1080    }
1081    // tail cleaning not needed
1082    return x;
1083}
1084
1085
1086// bitwise or
1087
1088template <class X, class Y>
1089inline
1090X&
1091b_or_assign_( sc_proxy<X>& px, const sc_proxy<Y>& py )
1092{
1093    X& x = px.back_cast();
1094    const Y& y = py.back_cast();
1095    assert( x.length() == y.length() );
1096    int sz = x.size();
1097    for( int i = 0; i < sz; ++ i ) {
1098	sc_digit x_dw, x_cw, y_dw, y_cw;
1099	get_words_( x, i, x_dw, x_cw );
1100	get_words_( y, i, y_dw, y_cw );
1101	sc_digit cw = (x_cw & y_cw) | (x_cw & ~y_dw) | (~x_dw & y_cw);
1102	sc_digit dw = cw | x_dw | y_dw;
1103	set_words_( x, i, dw, cw );
1104    }
1105    // tail cleaning not needed
1106    return x;
1107}
1108
1109
1110// bitwise xor
1111
1112template <class X, class Y>
1113inline
1114X&
1115b_xor_assign_( sc_proxy<X>& a, const sc_proxy<Y>& b )
1116{
1117    X& x = a.back_cast();
1118    const Y& y = b.back_cast();
1119    assert( x.length() == y.length() );
1120    int sz = x.size();
1121    for( int i = 0; i < sz; ++ i ) {
1122	sc_digit x_dw, x_cw, y_dw, y_cw;
1123	get_words_( x, i, x_dw, x_cw );
1124	get_words_( y, i, y_dw, y_cw );
1125	sc_digit cw = x_cw | y_cw;
1126	sc_digit dw = cw | (x_dw ^ y_dw);
1127	set_words_( x, i, dw, cw );
1128    }
1129    // tail cleaning not needed
1130    return x;
1131}
1132
1133
1134// bitwise left shift
1135
1136template <class X>
1137inline
1138X&
1139sc_proxy<X>::operator <<= ( int n )
1140{
1141    X& x = back_cast();
1142    if( n < 0 ) {
1143	char msg[BUFSIZ];
1144	std::sprintf( msg,
1145		 "left shift operation is only allowed with positive "
1146		 "shift values, shift value = %d", n );
1147	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
1148    }
1149    if( n >= x.length() ) {
1150	extend_sign_w_( x, 0, false );
1151	// no tail cleaning needed
1152	return x;
1153    }
1154    int sz = x.size();
1155    int wn = n / SC_DIGIT_SIZE;
1156    int bn = n % SC_DIGIT_SIZE;
1157    if( wn != 0 ) {
1158	// shift words
1159	int i = sz - 1;
1160	for( ; i >= wn; -- i ) {
1161	    set_words_( x, i, x.get_word( i - wn ), x.get_cword( i - wn ) );
1162	}
1163	for( ; i >= 0; -- i ) {
1164	    set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
1165	}
1166    }
1167    if( bn != 0 ) {
1168	// shift bits
1169	for( int i = sz - 1; i >= 1; -- i ) {
1170	    sc_digit x_dw, x_cw;
1171	    get_words_( x, i, x_dw, x_cw );
1172	    x_dw <<= bn;
1173	    x_dw |= x.get_word( i - 1 ) >> (SC_DIGIT_SIZE - bn);
1174	    x_cw <<= bn;
1175	    x_cw |= x.get_cword( i - 1 ) >> (SC_DIGIT_SIZE - bn);
1176	    set_words_( x, i, x_dw, x_cw );
1177	}
1178	sc_digit x_dw, x_cw;
1179	get_words_( x, 0, x_dw, x_cw );
1180	x_dw <<= bn;
1181	x_cw <<= bn;
1182	set_words_( x, 0, x_dw, x_cw );
1183    }
1184    x.clean_tail();
1185    return x;
1186}
1187
1188
1189// bitwise right shift
1190
1191
1192template <class X>
1193inline
1194X&
1195sc_proxy<X>::operator >>= ( int n )
1196{
1197    X& x = back_cast();
1198    if( n < 0 ) {
1199	char msg[BUFSIZ];
1200	std::sprintf( msg,
1201		 "right shift operation is only allowed with positive "
1202		 "shift values, shift value = %d", n );
1203	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
1204    }
1205    if( n >= x.length() ) {
1206	extend_sign_w_( x, 0, false );
1207	// no tail cleaning needed
1208	return x;
1209    }
1210    int sz = x.size();
1211    int wn = n / SC_DIGIT_SIZE;
1212    int bn = n % SC_DIGIT_SIZE;
1213    if( wn != 0 ) {
1214	// shift words
1215	int i = 0;
1216	for( ; i < (sz - wn); ++ i ) {
1217	    set_words_( x, i, x.get_word( i + wn ), x.get_cword( i + wn ) );
1218	}
1219	for( ; i < sz; ++ i ) {
1220	    set_words_( x, i, SC_DIGIT_ZERO, SC_DIGIT_ZERO );
1221	}
1222    }
1223    if( bn != 0 ) {
1224	// shift bits
1225	for( int i = 0; i < (sz - 1); ++ i ) {
1226	    sc_digit x_dw, x_cw;
1227	    get_words_( x, i, x_dw, x_cw );
1228	    x_dw >>= bn;
1229	    x_dw |= x.get_word( i + 1 ) << (SC_DIGIT_SIZE - bn);
1230	    x_cw >>= bn;
1231	    x_cw |= x.get_cword( i + 1 ) << (SC_DIGIT_SIZE - bn);
1232	    set_words_( x, i, x_dw, x_cw );
1233	}
1234	sc_digit x_dw, x_cw;
1235	get_words_( x, sz - 1, x_dw, x_cw );
1236	x_dw >>= bn;
1237	x_cw >>= bn;
1238	set_words_( x, sz - 1, x_dw, x_cw );
1239    }
1240    x.clean_tail();
1241    return x;
1242}
1243
1244
1245// bitwise left rotate
1246
1247template <class X>
1248inline
1249const sc_lv_base
1250lrotate( const sc_proxy<X>& x, int n );
1251
1252
1253// bitwise right rotate
1254
1255template <class X>
1256inline
1257const sc_lv_base
1258rrotate( const sc_proxy<X>& x, int n );
1259
1260
1261// bitwise reverse
1262
1263template <class X>
1264inline
1265X&
1266sc_proxy<X>::reverse()
1267{
1268    X& x = back_cast();
1269    int len = x.length();
1270    int half_len = len / 2;
1271    for( int i = 0, j = len - 1; i < half_len; ++ i, --j ) {
1272	sc_logic_value_t t = x.get_bit( i );
1273	x.set_bit( i, x.get_bit( j ) );
1274	x.set_bit( j, t );
1275    }
1276    return x;
1277}
1278
1279template <class X>
1280inline
1281const sc_lv_base
1282reverse( const sc_proxy<X>& a );
1283
1284
1285// reduce functions
1286
1287template <class X>
1288inline
1289sc_logic_value_t
1290sc_proxy<X>::and_reduce() const
1291{
1292    const X& x = back_cast();
1293    sc_logic_value_t result = sc_logic_value_t( 1 );
1294    int len = x.length();
1295    for( int i = 0; i < len; ++ i ) {
1296	result = sc_logic::and_table[result][x.get_bit( i )];
1297    }
1298    return result;
1299}
1300
1301template <class X>
1302inline
1303sc_logic_value_t
1304sc_proxy<X>::or_reduce() const
1305{
1306    const X& x = back_cast();
1307    sc_logic_value_t result = sc_logic_value_t( 0 );
1308    int len = x.length();
1309    for( int i = 0; i < len; ++ i ) {
1310	result = sc_logic::or_table[result][x.get_bit( i )];
1311    }
1312    return result;
1313}
1314
1315template <class X>
1316inline
1317sc_logic_value_t
1318sc_proxy<X>::xor_reduce() const
1319{
1320    const X& x = back_cast();
1321    sc_logic_value_t result = sc_logic_value_t( 0 );
1322    int len = x.length();
1323    for( int i = 0; i < len; ++ i ) {
1324	result = sc_logic::xor_table[result][x.get_bit( i )];
1325    }
1326    return result;
1327}
1328
1329
1330// relational operators
1331
1332template <class X, class Y>
1333inline
1334bool
1335operator != ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
1336{
1337    return !( px == py );
1338}
1339
1340
1341#define DEFN_REL_OP_T(tp)                                                     \
1342template <class X>                                                            \
1343inline                                                                        \
1344bool                                                                          \
1345operator == ( tp b, const sc_proxy<X>& px )                                   \
1346{                                                                             \
1347    return ( px == b );                                                       \
1348}                                                                             \
1349                                                                              \
1350template <class X>                                                            \
1351inline                                                                        \
1352bool                                                                          \
1353operator != ( const sc_proxy<X>& px, tp b )                                   \
1354{                                                                             \
1355    return !( px == b );                                                      \
1356}                                                                             \
1357                                                                              \
1358template <class X>                                                            \
1359inline                                                                        \
1360bool                                                                          \
1361operator != ( tp b, const sc_proxy<X>& px )                                   \
1362{                                                                             \
1363    return !( px == b );                                                      \
1364}
1365
1366DEFN_REL_OP_T(const char*)
1367DEFN_REL_OP_T(const bool*)
1368DEFN_REL_OP_T(const sc_logic*)
1369DEFN_REL_OP_T(const sc_unsigned&)
1370DEFN_REL_OP_T(const sc_signed&)
1371DEFN_REL_OP_T(const sc_uint_base&)
1372DEFN_REL_OP_T(const sc_int_base&)
1373DEFN_REL_OP_T(unsigned long)
1374DEFN_REL_OP_T(long)
1375DEFN_REL_OP_T(unsigned int)
1376DEFN_REL_OP_T(int)
1377DEFN_REL_OP_T(uint64)
1378DEFN_REL_OP_T(int64)
1379
1380#undef DEFN_REL_OP_T
1381
1382
1383// explicit conversions to character string
1384
1385template <class X>
1386inline
1387const std::string
1388sc_proxy<X>::to_string() const
1389{
1390    const X& x = back_cast();
1391    int len = x.length();
1392    std::string s; // ( len + 1 );
1393    for( int i = 0; i < len; ++ i ) {
1394	s += sc_logic::logic_to_char[x.get_bit( len - i - 1 )];
1395    }
1396    return s;
1397}
1398
1399template <class X>
1400inline
1401const std::string
1402sc_proxy<X>::to_string( sc_numrep numrep ) const
1403{
1404    return convert_to_fmt( to_string(), numrep, true );
1405}
1406
1407template <class X>
1408inline
1409const std::string
1410sc_proxy<X>::to_string( sc_numrep numrep, bool w_prefix ) const
1411{
1412    return convert_to_fmt( to_string(), numrep, w_prefix );
1413}
1414
1415
1416// other methods
1417
1418template <class X>
1419inline
1420void
1421sc_proxy<X>::scan( ::std::istream& is )
1422{
1423    std::string s;
1424    is >> s;
1425    back_cast() = s.c_str();
1426}
1427
1428
1429template <class X>
1430inline
1431void
1432sc_proxy<X>::check_bounds( int n ) const  // check if bit n accessible
1433{
1434    if( n < 0 || n >= back_cast().length() ) {
1435	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
1436    }
1437}
1438
1439template <class X>
1440inline
1441void
1442sc_proxy<X>::check_wbounds( int n ) const  // check if word n accessible
1443{
1444    if( n < 0 || n >= back_cast().size() ) {
1445	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, 0 );
1446    }
1447}
1448
1449
1450template <class X>
1451inline
1452sc_digit
1453sc_proxy<X>::to_anything_unsigned() const
1454{
1455    // only 0 word is returned
1456    // can't convert logic values other than 0 and 1
1457    const X& x = back_cast();
1458    int len = x.length();
1459    if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
1460	SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
1461    }
1462    sc_digit w = x.get_word( 0 );
1463    if( len >= SC_DIGIT_SIZE ) {
1464	return w;
1465    }
1466    return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
1467}
1468
1469template <class X>
1470inline
1471uint64
1472sc_proxy<X>::to_uint64() const
1473{
1474    // words 1 and 0 returned.
1475    // can't convert logic values other than 0 and 1
1476    const X& x = back_cast();
1477    int len = x.length();
1478    if( x.get_cword( 0 ) != SC_DIGIT_ZERO ) {
1479	SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
1480    }
1481    uint64 w = x.get_word( 0 );
1482    if( len > SC_DIGIT_SIZE )
1483    {
1484	if( x.get_cword( 1 ) != SC_DIGIT_ZERO ) {
1485	    SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
1486	}
1487	uint64 w1 = x.get_word( 1 );
1488        w = w | (w1 << SC_DIGIT_SIZE);
1489	return w;
1490    }
1491    else if( len == SC_DIGIT_SIZE )
1492    {
1493	return w;
1494    }
1495    else
1496    {
1497	return ( w & (~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - len)) );
1498    }
1499}
1500
1501template <class X>
1502inline
1503int64
1504sc_proxy<X>::to_anything_signed() const
1505{
1506    const X& x = back_cast();
1507    int len = x.length();
1508    int64 w = 0;
1509
1510    if( len > SC_DIGIT_SIZE )
1511    {
1512	if( x.get_cword( 1 ) != SC_DIGIT_ZERO )
1513	    SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
1514	w = x.get_word(1);
1515    }
1516    if( x.get_cword( 0 ) != SC_DIGIT_ZERO )
1517	SC_REPORT_WARNING( sc_core::SC_ID_VECTOR_CONTAINS_LOGIC_VALUE_, 0 );
1518    w = (w << SC_DIGIT_SIZE) | x.get_word( 0 );
1519    if( len >= 64 ) {
1520	return w;
1521    }
1522
1523    uint64 zero = 0;
1524    sc_logic_value_t sgn = x.get_bit( len - 1 );
1525    if( sgn == 0 ) {
1526	return (int64)( w & (~zero >> (64 - len)) );
1527    } else {
1528	return (int64)( w | (~zero << len) );
1529    }
1530}
1531
1532
1533// ----------------------------------------------------------------------------
1534
1535// functional notation for the reduce methods
1536
1537template <class X>
1538inline
1539sc_logic_value_t
1540and_reduce( const sc_proxy<X>& a )
1541{
1542    return a.and_reduce();
1543}
1544
1545template <class X>
1546inline
1547sc_logic_value_t
1548nand_reduce( const sc_proxy<X>& a )
1549{
1550    return a.nand_reduce();
1551}
1552
1553template <class X>
1554inline
1555sc_logic_value_t
1556or_reduce( const sc_proxy<X>& a )
1557{
1558    return a.or_reduce();
1559}
1560
1561template <class X>
1562inline
1563sc_logic_value_t
1564nor_reduce( const sc_proxy<X>& a )
1565{
1566    return a.nor_reduce();
1567}
1568
1569template <class X>
1570inline
1571sc_logic_value_t
1572xor_reduce( const sc_proxy<X>& a )
1573{
1574    return a.xor_reduce();
1575}
1576
1577template <class X>
1578inline
1579sc_logic_value_t
1580xnor_reduce( const sc_proxy<X>& a )
1581{
1582    return a.xnor_reduce();
1583}
1584
1585
1586// ----------------------------------------------------------------------------
1587
1588template <class X>
1589inline
1590::std::ostream&
1591operator << ( ::std::ostream& os, const sc_proxy<X>& a )
1592{
1593    a.print( os );
1594    return os;
1595}
1596
1597template <class X>
1598inline
1599::std::istream&
1600operator >> ( ::std::istream& is, sc_proxy<X>& a )
1601{
1602    a.scan( is );
1603    return is;
1604}
1605
1606} // namespace sc_dt
1607
1608
1609#endif
1610