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