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_lv_base.h -- Arbitrary size logic vector class.
23 
24   Original Author: Gene Bushuyev, Synopsys, Inc.
25 
26  *****************************************************************************/
27 
28 /*****************************************************************************
29 
30   MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31   changes you are making here.
32 
33       Name, Affiliation, Date:
34   Description of Modification:
35 	Andy Goodrich, Forte Design Systems
36 	  Fixed bug in clean_tail for sizes that are modulo 32, which caused
37 	  zeroing of values.
38 
39  *****************************************************************************/
40 
41 // $Log: sc_lv_base.h,v $
42 // Revision 1.4  2011/08/26 22:32:00  acg
43 //  Torsten Maehne: added parentheses to make opearator ordering more obvious.
44 //
45 // Revision 1.3  2010/01/27 19:41:29  acg
46 //  Andy Goodrich: fix 8 instances of sc_concref constructor invocations
47 //  that failed to indicate that their arguments should be freed when the
48 //  object was freed.
49 //
50 // Revision 1.2  2009/02/28 00:26:14  acg
51 //  Andy Goodrich: bug fixes.
52 //
53 // Revision 1.2  2007/03/14 17:47:49  acg
54 //  Andy Goodrich: Formatting.
55 //
56 // Revision 1.1.1.1  2006/12/15 20:31:36  acg
57 // SystemC 2.2
58 //
59 // Revision 1.3  2006/01/13 18:53:53  acg
60 // Andy Goodrich: added $Log command so that CVS comments are reproduced in
61 // the source.
62 //
63 
64 #ifndef SC_LV_BASE_H
65 #define SC_LV_BASE_H
66 
67 
68 #include "sysc/datatypes/bit/sc_bit_ids.h"
69 #include "sysc/datatypes/bit/sc_bv_base.h"
70 #include "sysc/datatypes/bit/sc_logic.h"
71 #include "sysc/datatypes/int/sc_length_param.h"
72 
73 
74 namespace sc_dt
75 {
76 
77 // classes defined in this module
78 class sc_lv_base;
79 
80 
81 // ----------------------------------------------------------------------------
82 //  CLASS : sc_lv_base
83 //
84 //  Arbitrary size logic vector base class.
85 // ----------------------------------------------------------------------------
86 
87 class SC_API sc_lv_base
88     : public sc_proxy<sc_lv_base>
89 {
90     friend class sc_bv_base;
91 
92 
93     void init( int length_, const sc_logic& init_value = SC_LOGIC_X );
94 
95     void assign_from_string( const std::string& );
96 
97 public:
98 
99     // typedefs
100 
101     typedef sc_proxy<sc_lv_base>  base_type;
102     typedef base_type::value_type value_type;
103 
104 
105     // constructors
106 
107     explicit sc_lv_base( int length_ = sc_length_param().len() )
108 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
109 	{ init( length_ ); }
110 
111     explicit sc_lv_base( const sc_logic& a,
112 			 int length_ = sc_length_param().len()  )
113 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
114 	{ init( length_, a ); }
115 
116     sc_lv_base( const char* a );
117 
118     sc_lv_base( const char* a, int length_ );
119 
120     template <class X>
sc_lv_base(const sc_proxy<X> & a)121     sc_lv_base( const sc_proxy<X>& a )
122 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
123 	{ init( a.back_cast().length() ); base_type::assign_( a ); }
124 
125     sc_lv_base( const sc_lv_base& a );
126 
127 #ifdef SC_DT_DEPRECATED
128 
sc_lv_base(const sc_unsigned & a)129     explicit sc_lv_base( const sc_unsigned& a )
130 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
131 	{ init( a.length() ); base_type::assign_( a ); }
132 
sc_lv_base(const sc_signed & a)133     explicit sc_lv_base( const sc_signed& a )
134 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
135 	{ init( a.length() ); base_type::assign_( a ); }
136 
sc_lv_base(const sc_uint_base & a)137     explicit sc_lv_base( const sc_uint_base& a )
138 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
139 	{ init( a.length() ); base_type::assign_( a ); }
140 
sc_lv_base(const sc_int_base & a)141     explicit sc_lv_base( const sc_int_base& a )
142 	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
143 	{ init( a.length() ); base_type::assign_( a ); }
144 
145 #endif
146 
147 
148     // destructor
149 
~sc_lv_base()150     virtual ~sc_lv_base()
151 	{ delete [] m_data; }
152 
153 
154     // assignment operators
155 
156     template <class X>
157     sc_lv_base& operator = ( const sc_proxy<X>& a )
158 	{ assign_p_( *this, a ); return *this; }
159 
160     sc_lv_base& operator = ( const sc_lv_base& a )
161 	{ assign_p_( *this, a ); return *this; }
162 
163     sc_lv_base& operator = ( const char* a );
164 
165     sc_lv_base& operator = ( const bool* a )
166 	{ base_type::assign_( a ); return *this; }
167 
168     sc_lv_base& operator = ( const sc_logic* a )
169 	{ base_type::assign_( a ); return *this; }
170 
171     sc_lv_base& operator = ( const sc_unsigned& a )
172 	{ base_type::assign_( a ); return *this; }
173 
174     sc_lv_base& operator = ( const sc_signed& a )
175 	{ base_type::assign_( a ); return *this; }
176 
177     sc_lv_base& operator = ( const sc_uint_base& a )
178 	{ base_type::assign_( a ); return *this; }
179 
180     sc_lv_base& operator = ( const sc_int_base& a )
181 	{ base_type::assign_( a ); return *this; }
182 
183     sc_lv_base& operator = ( unsigned long a )
184 	{ base_type::assign_( a ); return *this; }
185 
186     sc_lv_base& operator = ( long a )
187 	{ base_type::assign_( a ); return *this; }
188 
189     sc_lv_base& operator = ( unsigned int a )
190 	{ base_type::assign_( a ); return *this; }
191 
192     sc_lv_base& operator = ( int a )
193 	{ base_type::assign_( a ); return *this; }
194 
195     sc_lv_base& operator = ( uint64 a )
196 	{ base_type::assign_( a ); return *this; }
197 
198     sc_lv_base& operator = ( int64 a )
199 	{ base_type::assign_( a ); return *this; }
200 
201     // common methods
202 
length()203     int length() const
204 	{ return m_len; }
205 
size()206     int size() const
207 	{ return m_size; }
208 
209     value_type get_bit( int i ) const;
210     void set_bit( int i, value_type value );
211 
get_word(int wi)212     sc_digit get_word( int wi ) const
213 	{ return m_data[wi]; }
214 
215 	// note the test for out of range access here. this is necessary
216 	// because of the hair-brained way concatenations are set up.
217 	// an extend_sign on a concatenation uses the whole length of
218 	// the concatenation to determine how many words to set.
set_word(int wi,sc_digit w)219     void set_word( int wi, sc_digit w )
220 	{ sc_assert ( wi < m_size ); m_data[wi] = w; }
221 
222 
get_cword(int wi)223     sc_digit get_cword( int wi ) const
224 	{ return m_ctrl[wi]; }
225 
set_cword(int wi,sc_digit w)226     void set_cword( int wi, sc_digit w )
227 	{ sc_assert ( wi < m_size ); m_ctrl[wi] = w; }
228 
229     void clean_tail();
230 
231 
232     // other methods
233 
234     bool is_01() const;
235 
236 protected:
237 
238     int     m_len;   // length in bits
239     int     m_size;  // size of the data array
240     sc_digit* m_data;  // data array
241     sc_digit* m_ctrl;  // dito (control part)
242 };
243 
244 
245 // IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
246 
247 #if 0
248 
249 // bitwise left rotate
250 
251 inline
252 const sc_lv_base
253 lrotate( const sc_lv_base& x, int n )
254 {
255     sc_lv_base a( x );
256     return a.lrotate( n );
257 }
258 
259 
260 // bitwise right rotate
261 
262 inline
263 const sc_lv_base
264 rrotate( const sc_lv_base& x, int n )
265 {
266     sc_lv_base a( x );
267     return a.rrotate( n );
268 }
269 
270 #endif
271 
272 
273 inline
274 sc_lv_base::value_type
get_bit(int i)275 sc_lv_base::get_bit( int i ) const
276 {
277     int wi = i / SC_DIGIT_SIZE;
278     int bi = i % SC_DIGIT_SIZE;
279     return value_type( ((m_data[wi] >> bi) & SC_DIGIT_ONE) |
280 			     (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO) );
281 }
282 
283 inline
284 void
set_bit(int i,value_type value)285 sc_lv_base::set_bit( int i, value_type value )
286 {
287     int wi = i / SC_DIGIT_SIZE; // word index
288     int bi = i % SC_DIGIT_SIZE; // bit index
289     sc_digit mask = SC_DIGIT_ONE << bi;
290     m_data[wi] |= mask; // set bit to 1
291     m_ctrl[wi] |= mask; // set bit to 1
292     m_data[wi] &= value << bi | ~mask;
293     m_ctrl[wi] &= value >> 1 << bi | ~mask;
294 }
295 
296 
297 inline
298 void
clean_tail()299 sc_lv_base::clean_tail()
300 {
301     int wi = m_size - 1;
302     int bi = m_len % SC_DIGIT_SIZE;
303     sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
304 	if ( mask )
305 	{
306 		m_data[wi] &= mask;
307 		m_ctrl[wi] &= mask;
308 	}
309 }
310 
311 
312 // ----------------------------------------------------------------------------
313 //  CLASS TEMPLATE : sc_proxy
314 //
315 //  Base class template for bit/logic vector classes.
316 //  (Barton/Nackmann implementation)
317 // ----------------------------------------------------------------------------
318 
319 // bitwise operators and functions
320 
321 // bitwise complement
322 
323 template <class X>
324 inline
325 const sc_lv_base
326 sc_proxy<X>::operator ~ () const
327 {
328     sc_lv_base a( back_cast() );
329     return a.b_not();
330 }
331 
332 
333 // bitwise and
334 
335 template <class X, class Y>
336 inline
337 X&
338 operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
339 {
340     X& x = px.back_cast();
341     sc_lv_base a( x.length() );
342     a = py.back_cast();
343     return b_and_assign_( x, a );
344 }
345 
346 
347 #define DEFN_BITWISE_AND_ASN_OP_T(tp)                                         \
348 template <class X>                                                            \
349 inline                                                                        \
350 X&                                                                            \
351 sc_proxy<X>::operator &= ( tp b )                                             \
352 {                                                                             \
353     X& x = back_cast();                                                       \
354     sc_lv_base a( x.length() );                                               \
355     a = b;                                                                    \
356     return b_and_assign_( x, a );                                             \
357 }
358 
359 DEFN_BITWISE_AND_ASN_OP_T(const char*)
DEFN_BITWISE_AND_ASN_OP_T(const bool *)360 DEFN_BITWISE_AND_ASN_OP_T(const bool*)
361 DEFN_BITWISE_AND_ASN_OP_T(const sc_logic*)
362 DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned&)
363 DEFN_BITWISE_AND_ASN_OP_T(const sc_signed&)
364 DEFN_BITWISE_AND_ASN_OP_T(unsigned long)
365 DEFN_BITWISE_AND_ASN_OP_T(long)
366 DEFN_BITWISE_AND_ASN_OP_T(uint64)
367 DEFN_BITWISE_AND_ASN_OP_T(int64)
368 
369 #undef DEFN_BITWISE_AND_ASN_OP_T
370 
371 
372 template <class X, class Y>
373 inline
374 const sc_lv_base
375 operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
376 {
377     sc_lv_base a( px.back_cast() );
378     return ( a &= py.back_cast() );
379 }
380 
381 
382 #define DEFN_BITWISE_AND_OP_T_A(tp)                                           \
383 template <class X>                                                            \
384 inline                                                                        \
385 const sc_lv_base                                                              \
386 sc_proxy<X>::operator & ( tp b ) const                                        \
387 {                                                                             \
388     sc_lv_base a( back_cast() );                                              \
389     return ( a &= b );                                                        \
390 }
391 
392 DEFN_BITWISE_AND_OP_T_A(const char*)
393 DEFN_BITWISE_AND_OP_T_A(const bool*)
394 DEFN_BITWISE_AND_OP_T_A(const sc_logic*)
395 DEFN_BITWISE_AND_OP_T_A(const sc_unsigned&)
396 DEFN_BITWISE_AND_OP_T_A(const sc_signed&)
397 DEFN_BITWISE_AND_OP_T_A(const sc_uint_base&)
398 DEFN_BITWISE_AND_OP_T_A(const sc_int_base&)
399 DEFN_BITWISE_AND_OP_T_A(unsigned long)
400 DEFN_BITWISE_AND_OP_T_A(long)
401 DEFN_BITWISE_AND_OP_T_A(unsigned int)
402 DEFN_BITWISE_AND_OP_T_A(int)
403 DEFN_BITWISE_AND_OP_T_A(uint64)
404 DEFN_BITWISE_AND_OP_T_A(int64)
405 
406 #undef DEFN_BITWISE_AND_OP_T_A
407 
408 
409 #define DEFN_BITWISE_AND_OP_T_B(tp)                                           \
410 template <class X>                                                            \
411 inline                                                                        \
412 const sc_lv_base                                                              \
413 operator & ( tp b, const sc_proxy<X>& px )                                    \
414 {                                                                             \
415     return ( px & b );                                                        \
416 }
417 
418 DEFN_BITWISE_AND_OP_T_B(const char*)
419 DEFN_BITWISE_AND_OP_T_B(const bool*)
420 DEFN_BITWISE_AND_OP_T_B(const sc_logic*)
421 DEFN_BITWISE_AND_OP_T_B(const sc_unsigned&)
422 DEFN_BITWISE_AND_OP_T_B(const sc_signed&)
423 DEFN_BITWISE_AND_OP_T_B(const sc_uint_base&)
424 DEFN_BITWISE_AND_OP_T_B(const sc_int_base&)
425 DEFN_BITWISE_AND_OP_T_B(unsigned long)
426 DEFN_BITWISE_AND_OP_T_B(long)
427 DEFN_BITWISE_AND_OP_T_B(unsigned int)
428 DEFN_BITWISE_AND_OP_T_B(int)
429 DEFN_BITWISE_AND_OP_T_B(uint64)
430 DEFN_BITWISE_AND_OP_T_B(int64)
431 
432 #undef DEFN_BITWISE_AND_OP_T_B
433 
434 
435 // bitwise or
436 
437 template <class X, class Y>
438 inline
439 X&
440 operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
441 {
442     X& x = px.back_cast();
443     sc_lv_base a( x.length() );
444     a = py.back_cast();
445     return b_or_assign_( x, a );
446 }
447 
448 
449 #define DEFN_BITWISE_OR_ASN_OP_T(tp)                                          \
450 template <class X>                                                            \
451 inline                                                                        \
452 X&                                                                            \
453 sc_proxy<X>::operator |= ( tp b )                                             \
454 {                                                                             \
455     X& x = back_cast();                                                       \
456     sc_lv_base a( x.length() );                                               \
457     a = b;                                                                    \
458     return b_or_assign_( x, a );                                              \
459 }
460 
461 DEFN_BITWISE_OR_ASN_OP_T(const char*)
462 DEFN_BITWISE_OR_ASN_OP_T(const bool*)
463 DEFN_BITWISE_OR_ASN_OP_T(const sc_logic*)
464 DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned&)
465 DEFN_BITWISE_OR_ASN_OP_T(const sc_signed&)
466 DEFN_BITWISE_OR_ASN_OP_T(unsigned long)
467 DEFN_BITWISE_OR_ASN_OP_T(long)
468 DEFN_BITWISE_OR_ASN_OP_T(uint64)
469 DEFN_BITWISE_OR_ASN_OP_T(int64)
470 
471 #undef DEFN_BITWISE_OR_ASN_OP_T
472 
473 
474 template <class X, class Y>
475 inline
476 const sc_lv_base
477 operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
478 {
479     sc_lv_base a( px.back_cast() );
480     return ( a |= py.back_cast() );
481 }
482 
483 
484 #define DEFN_BITWISE_OR_OP_T_A(tp)                                            \
485 template <class X>                                                            \
486 inline                                                                        \
487 const sc_lv_base                                                              \
488 sc_proxy<X>::operator | ( tp b ) const                                        \
489 {                                                                             \
490     sc_lv_base a( back_cast() );                                              \
491     return ( a |= b );                                                        \
492 }
493 
494 DEFN_BITWISE_OR_OP_T_A(const char*)
495 DEFN_BITWISE_OR_OP_T_A(const bool*)
496 DEFN_BITWISE_OR_OP_T_A(const sc_logic*)
497 DEFN_BITWISE_OR_OP_T_A(const sc_unsigned&)
498 DEFN_BITWISE_OR_OP_T_A(const sc_signed&)
499 DEFN_BITWISE_OR_OP_T_A(const sc_uint_base&)
500 DEFN_BITWISE_OR_OP_T_A(const sc_int_base&)
501 DEFN_BITWISE_OR_OP_T_A(unsigned long)
502 DEFN_BITWISE_OR_OP_T_A(long)
503 DEFN_BITWISE_OR_OP_T_A(unsigned int)
504 DEFN_BITWISE_OR_OP_T_A(int)
505 DEFN_BITWISE_OR_OP_T_A(uint64)
506 DEFN_BITWISE_OR_OP_T_A(int64)
507 
508 #undef DEFN_BITWISE_OR_OP_T_A
509 
510 
511 #define DEFN_BITWISE_OR_OP_T_B(tp)                                           \
512 template <class X>                                                            \
513 inline                                                                        \
514 const sc_lv_base                                                              \
515 operator | ( tp b, const sc_proxy<X>& px )                                    \
516 {                                                                             \
517     return ( px | b );                                                        \
518 }
519 
520 DEFN_BITWISE_OR_OP_T_B(const char*)
521 DEFN_BITWISE_OR_OP_T_B(const bool*)
522 DEFN_BITWISE_OR_OP_T_B(const sc_logic*)
523 DEFN_BITWISE_OR_OP_T_B(const sc_unsigned&)
524 DEFN_BITWISE_OR_OP_T_B(const sc_signed&)
525 DEFN_BITWISE_OR_OP_T_B(const sc_uint_base&)
526 DEFN_BITWISE_OR_OP_T_B(const sc_int_base&)
527 DEFN_BITWISE_OR_OP_T_B(unsigned long)
528 DEFN_BITWISE_OR_OP_T_B(long)
529 DEFN_BITWISE_OR_OP_T_B(unsigned int)
530 DEFN_BITWISE_OR_OP_T_B(int)
531 DEFN_BITWISE_OR_OP_T_B(uint64)
532 DEFN_BITWISE_OR_OP_T_B(int64)
533 
534 #undef DEFN_BITWISE_OR_OP_T_B
535 
536 
537 // bitwise xor
538 
539 template <class X, class Y>
540 inline
541 X&
542 operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
543 {
544     X& x = px.back_cast();
545     sc_lv_base a( x.length() );
546     a = py.back_cast();
547     return b_xor_assign_( x, a );
548 }
549 
550 
551 #define DEFN_BITWISE_XOR_ASN_OP_T(tp)                                         \
552 template <class X>                                                            \
553 inline                                                                        \
554 X&                                                                            \
555 sc_proxy<X>::operator ^= ( tp b )                                             \
556 {                                                                             \
557     X& x = back_cast();                                                       \
558     sc_lv_base a( x.length() );                                               \
559     a = b;                                                                    \
560     return b_xor_assign_( x, a );                                             \
561 }
562 
563 DEFN_BITWISE_XOR_ASN_OP_T(const char*)
564 DEFN_BITWISE_XOR_ASN_OP_T(const bool*)
565 DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic*)
566 DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned&)
567 DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed&)
568 DEFN_BITWISE_XOR_ASN_OP_T(unsigned long)
569 DEFN_BITWISE_XOR_ASN_OP_T(long)
570 DEFN_BITWISE_XOR_ASN_OP_T(uint64)
571 DEFN_BITWISE_XOR_ASN_OP_T(int64)
572 
573 #undef DEFN_BITWISE_XOR_ASN_OP_T
574 
575 
576 template <class X, class Y>
577 inline
578 const sc_lv_base
579 operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
580 {
581     sc_lv_base a( px.back_cast() );
582     return ( a ^= py.back_cast() );
583 }
584 
585 
586 #define DEFN_BITWISE_XOR_OP_T_A(tp)                                           \
587 template <class X>                                                            \
588 inline                                                                        \
589 const sc_lv_base                                                              \
590 sc_proxy<X>::operator ^ ( tp b ) const                                        \
591 {                                                                             \
592     sc_lv_base a( back_cast() );                                              \
593     return ( a ^= b );                                                        \
594 }
595 
596 DEFN_BITWISE_XOR_OP_T_A(const char*)
597 DEFN_BITWISE_XOR_OP_T_A(const bool*)
598 DEFN_BITWISE_XOR_OP_T_A(const sc_logic*)
599 DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned&)
600 DEFN_BITWISE_XOR_OP_T_A(const sc_signed&)
601 DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base&)
602 DEFN_BITWISE_XOR_OP_T_A(const sc_int_base&)
603 DEFN_BITWISE_XOR_OP_T_A(unsigned long)
604 DEFN_BITWISE_XOR_OP_T_A(long)
605 DEFN_BITWISE_XOR_OP_T_A(unsigned int)
606 DEFN_BITWISE_XOR_OP_T_A(int)
607 DEFN_BITWISE_XOR_OP_T_A(uint64)
608 DEFN_BITWISE_XOR_OP_T_A(int64)
609 
610 #undef DEFN_BITWISE_XOR_OP_T_A
611 
612 
613 #define DEFN_BITWISE_XOR_OP_T_B(tp)                                           \
614 template <class X>                                                            \
615 inline                                                                        \
616 const sc_lv_base                                                              \
617 operator ^ ( tp b, const sc_proxy<X>& px )                                    \
618 {                                                                             \
619     return ( px ^ b );                                                        \
620 }
621 
622 DEFN_BITWISE_XOR_OP_T_B(const char*)
623 DEFN_BITWISE_XOR_OP_T_B(const bool*)
624 DEFN_BITWISE_XOR_OP_T_B(const sc_logic*)
625 DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned&)
626 DEFN_BITWISE_XOR_OP_T_B(const sc_signed&)
627 DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base&)
628 DEFN_BITWISE_XOR_OP_T_B(const sc_int_base&)
629 DEFN_BITWISE_XOR_OP_T_B(unsigned long)
630 DEFN_BITWISE_XOR_OP_T_B(long)
631 DEFN_BITWISE_XOR_OP_T_B(unsigned int)
632 DEFN_BITWISE_XOR_OP_T_B(int)
633 DEFN_BITWISE_XOR_OP_T_B(uint64)
634 DEFN_BITWISE_XOR_OP_T_B(int64)
635 
636 #undef DEFN_BITWISE_XOR_OP_T_B
637 
638 
639 // bitwise left shift
640 
641 template <class X>
642 inline
643 const sc_lv_base
644 sc_proxy<X>::operator << ( int n ) const
645 {
646     sc_lv_base a( back_cast().length()+n );
647 	a = back_cast();
648     return ( a <<= n );
649 }
650 
651 
652 // bitwise right shift
653 
654 template <class X>
655 inline
656 const sc_lv_base
657 sc_proxy<X>::operator >> ( int n ) const
658 {
659     sc_lv_base a( back_cast() );
660     return ( a >>= n );
661 }
662 
663 
664 // bitwise left rotate
665 
666 template <class X>
667 inline
668 X&
lrotate(int n)669 sc_proxy<X>::lrotate( int n )
670 {
671     X& x = back_cast();
672     if( n < 0 ) {
673         sc_proxy_out_of_bounds( "left rotate operation is only allowed with "
674                                 "positive rotate values, rotate value = ", n );
675         return x;
676     }
677     int len = x.length();
678     n %= len;
679     // x = (x << n) | (x >> (len - n));
680     sc_lv_base a( x << n );
681     sc_lv_base b( x >> (len - n) );
682     int sz = x.size();
683     for( int i = 0; i < sz; ++ i ) {
684 	x.set_word( i, a.get_word( i ) | b.get_word( i ) );
685 	x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
686     }
687     x.clean_tail();
688     return x;
689 }
690 
691 template <class X>
692 inline
693 const sc_lv_base
lrotate(const sc_proxy<X> & x,int n)694 lrotate( const sc_proxy<X>& x, int n )
695 {
696     sc_lv_base a( x.back_cast() );
697     return a.lrotate( n );
698 }
699 
700 
701 // bitwise right rotate
702 
703 template <class X>
704 inline
705 X&
rrotate(int n)706 sc_proxy<X>::rrotate( int n )
707 {
708     X& x = back_cast();
709     if( n < 0 ) {
710         sc_proxy_out_of_bounds( "right rotate operation is only allowed with "
711                                 "positive rotate values, rotate value = ", n );
712         return x;
713     }
714     int len = x.length();
715     n %= len;
716     // x = (x >> n) | (x << (len - n));
717     sc_lv_base a( x >> n );
718     sc_lv_base b( x << (len - n) );
719     int sz = x.size();
720     for( int i = 0; i < sz; ++ i ) {
721 	x.set_word( i, a.get_word( i ) | b.get_word( i ) );
722 	x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
723     }
724     x.clean_tail();
725     return x;
726 }
727 
728 template <class X>
729 inline
730 const sc_lv_base
rrotate(const sc_proxy<X> & x,int n)731 rrotate( const sc_proxy<X>& x, int n )
732 {
733     sc_lv_base a( x.back_cast() );
734     return a.rrotate( n );
735 }
736 
737 
738 // bitwise reverse
739 
740 template <class X>
741 inline
742 const sc_lv_base
reverse(const sc_proxy<X> & x)743 reverse( const sc_proxy<X>& x )
744 {
745     sc_lv_base a( x.back_cast() );
746     return a.reverse();
747 }
748 
749 
750 // relational operators
751 
752 template <class X, class Y>
753 inline
754 bool
755 operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
756 {
757     const X& x = px.back_cast();
758     const Y& y = py.back_cast();
759     int x_len = x.length();
760     int y_len = y.length();
761     if( x_len != y_len ) {
762 	return false;
763     }
764     int sz = x.size();
765     for( int i = 0; i < sz; ++ i ) {
766 	if( x.get_word( i ) != y.get_word( i ) ||
767 	    x.get_cword( i ) != y.get_cword( i ) ) {
768 	    return false;
769 	}
770     }
771     return true;
772 }
773 
774 
775 #define DEFN_REL_OP_T(tp)                                                     \
776 template <class X>                                                            \
777 inline                                                                        \
778 bool                                                                          \
779 sc_proxy<X>::operator == ( tp b ) const                                       \
780 {                                                                             \
781     const X& x = back_cast();                                                 \
782     sc_lv_base y( x.length() );                                               \
783     y = b;                                                                    \
784     return ( x == y );                                                        \
785 }
786 
787 DEFN_REL_OP_T(const char*)
DEFN_REL_OP_T(const bool *)788 DEFN_REL_OP_T(const bool*)
789 DEFN_REL_OP_T(const sc_logic*)
790 DEFN_REL_OP_T(const sc_unsigned&)
791 DEFN_REL_OP_T(const sc_signed&)
792 DEFN_REL_OP_T(const sc_uint_base&)
793 DEFN_REL_OP_T(const sc_int_base&)
794 DEFN_REL_OP_T(unsigned long)
795 DEFN_REL_OP_T(long)
796 DEFN_REL_OP_T(unsigned int)
797 DEFN_REL_OP_T(int)
798 DEFN_REL_OP_T(uint64)
799 DEFN_REL_OP_T(int64)
800 
801 #undef DEFN_REL_OP_T
802 
803 
804 // ----------------------------------------------------------------------------
805 //  CLASS TEMPLATE : sc_bitref_r<X>
806 //
807 //  Proxy class for sc_proxy bit selection (r-value only).
808 // ----------------------------------------------------------------------------
809 
810 // r-value concatenation operators and functions
811 
812 template <class T>
813 inline
814 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
815 operator , ( sc_bitref_r<T> a, const char* b )
816 {
817     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
818 	*a.clone(), *new sc_lv_base( b ), 3 );
819 }
820 
821 template <class T>
822 inline
823 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
824 operator , ( const char* a, sc_bitref_r<T> b )
825 {
826     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
827 	*new sc_lv_base( a ), *b.clone(), 3 );
828 }
829 
830 template <class T>
831 inline
832 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
833 operator , ( sc_bitref_r<T> a, const sc_logic& b )
834 {
835     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
836 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
837 }
838 
839 template <class T>
840 inline
841 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
842 operator , ( const sc_logic& a, sc_bitref_r<T> b )
843 {
844     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
845 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
846 }
847 
848 template <class T>
849 inline
850 sc_concref_r<sc_bitref_r<T>,sc_bv_base>
851 operator , ( sc_bitref_r<T> a, bool b )
852 {
853     return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
854         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
855 }
856 
857 template <class T>
858 inline
859 sc_concref_r<sc_bv_base,sc_bitref_r<T> >
860 operator , ( bool a, sc_bitref_r<T> b )
861 {
862     return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
863         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
864 }
865 
866 
867 template <class T>
868 inline
869 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
concat(sc_bitref_r<T> a,const char * b)870 concat( sc_bitref_r<T> a, const char* b )
871 {
872     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
873 	*a.clone(), *new sc_lv_base( b ), 3 );
874 }
875 
876 template <class T>
877 inline
878 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
concat(const char * a,sc_bitref_r<T> b)879 concat( const char* a, sc_bitref_r<T> b )
880 {
881     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
882 	*new sc_lv_base( a ), *b.clone(), 3 );
883 }
884 
885 template <class T>
886 inline
887 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
concat(sc_bitref_r<T> a,const sc_logic & b)888 concat( sc_bitref_r<T> a, const sc_logic& b )
889 {
890     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
891 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
892 }
893 
894 template <class T>
895 inline
896 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
concat(const sc_logic & a,sc_bitref_r<T> b)897 concat( const sc_logic& a, sc_bitref_r<T> b )
898 {
899     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
900 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
901 }
902 
903 template <class T>
904 inline
905 sc_concref_r<sc_bitref_r<T>,sc_bv_base>
concat(sc_bitref_r<T> a,bool b)906 concat( sc_bitref_r<T> a, bool b )
907 {
908     return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
909         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
910 }
911 
912 template <class T>
913 inline
914 sc_concref_r<sc_bv_base,sc_bitref_r<T> >
concat(bool a,sc_bitref_r<T> b)915 concat( bool a, sc_bitref_r<T> b )
916 {
917     return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
918         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
919 }
920 
921 
922 #ifdef SC_DT_MIXED_COMMA_OPERATORS
923 
924 template <class T>
925 inline
926 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
927 operator , ( sc_bitref<T> a, const char* b )
928 {
929     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
930 	*a.clone(), *new sc_lv_base( b ), 3 );
931 }
932 
933 template <class T>
934 inline
935 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
936 operator , ( const char* a, sc_bitref<T> b )
937 {
938     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
939 	*new sc_lv_base( a ), *b.clone(), 3 );
940 }
941 
942 template <class T>
943 inline
944 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
945 operator , ( sc_bitref<T> a, const sc_logic& b )
946 {
947     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
948 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
949 }
950 
951 template <class T>
952 inline
953 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
954 operator , ( const sc_logic& a, sc_bitref<T> b )
955 {
956     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
957 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
958 }
959 
960 template <class T>
961 inline
962 sc_concref_r<sc_bitref_r<T>,sc_bv_base>
963 operator , ( sc_bitref<T> a, bool b )
964 {
965     return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
966         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
967 }
968 
969 template <class T>
970 inline
971 sc_concref_r<sc_bv_base,sc_bitref_r<T> >
972 operator , ( bool a, sc_bitref<T> b )
973 {
974     return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
975         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
976 }
977 
978 
979 template <class T>
980 inline
981 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
concat(sc_bitref<T> a,const char * b)982 concat( sc_bitref<T> a, const char* b )
983 {
984     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
985 	*a.clone(), *new sc_lv_base( b ), 3 );
986 }
987 
988 template <class T>
989 inline
990 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
concat(const char * a,sc_bitref<T> b)991 concat( const char* a, sc_bitref<T> b )
992 {
993     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
994 	*new sc_lv_base( a ), *b.clone(), 3 );
995 }
996 
997 template <class T>
998 inline
999 sc_concref_r<sc_bitref_r<T>,sc_lv_base>
concat(sc_bitref<T> a,const sc_logic & b)1000 concat( sc_bitref<T> a, const sc_logic& b )
1001 {
1002     return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
1003 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1004 }
1005 
1006 template <class T>
1007 inline
1008 sc_concref_r<sc_lv_base,sc_bitref_r<T> >
concat(const sc_logic & a,sc_bitref<T> b)1009 concat( const sc_logic& a, sc_bitref<T> b )
1010 {
1011     return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
1012 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1013 }
1014 
1015 template <class T>
1016 inline
1017 sc_concref_r<sc_bitref_r<T>,sc_bv_base>
concat(sc_bitref<T> a,bool b)1018 concat( sc_bitref<T> a, bool b )
1019 {
1020     return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
1021         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1022 }
1023 
1024 template <class T>
1025 inline
1026 sc_concref_r<sc_bv_base,sc_bitref_r<T> >
concat(bool a,sc_bitref<T> b)1027 concat( bool a, sc_bitref<T> b )
1028 {
1029     return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
1030         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1031 }
1032 
1033 #endif
1034 
1035 
1036 // ----------------------------------------------------------------------------
1037 //  CLASS TEMPLATE : sc_subref_r<X>
1038 //
1039 //  Proxy class for sc_proxy part selection (r-value only).
1040 // ----------------------------------------------------------------------------
1041 
1042 // r-value concatenation operators and functions
1043 
1044 template <class T>
1045 inline
1046 sc_concref_r<sc_subref_r<T>,sc_lv_base>
1047 operator , ( sc_subref_r<T> a, const char* b )
1048 {
1049     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1050 	*a.clone(), *new sc_lv_base( b ), 3 );
1051 }
1052 
1053 template <class T>
1054 inline
1055 sc_concref_r<sc_lv_base,sc_subref_r<T> >
1056 operator , ( const char* a, sc_subref_r<T> b )
1057 {
1058     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1059 	*new sc_lv_base( a ), *b.clone(), 3 );
1060 }
1061 
1062 template <class T>
1063 inline
1064 sc_concref_r<sc_subref_r<T>,sc_lv_base>
1065 operator , ( sc_subref_r<T> a, const sc_logic& b )
1066 {
1067     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1068 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1069 }
1070 
1071 template <class T>
1072 inline
1073 sc_concref_r<sc_lv_base,sc_subref_r<T> >
1074 operator , ( const sc_logic& a, sc_subref_r<T> b )
1075 {
1076     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1077 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1078 }
1079 
1080 template <class T>
1081 inline
1082 sc_concref_r<sc_subref_r<T>,sc_bv_base>
1083 operator , ( sc_subref_r<T> a, bool b )
1084 {
1085     return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1086         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1087 }
1088 
1089 template <class T>
1090 inline
1091 sc_concref_r<sc_bv_base,sc_subref_r<T> >
1092 operator , ( bool a, sc_subref_r<T> b )
1093 {
1094     return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1095         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1096 }
1097 
1098 
1099 template <class T>
1100 inline
1101 sc_concref_r<sc_subref_r<T>,sc_lv_base>
concat(sc_subref_r<T> a,const char * b)1102 concat( sc_subref_r<T> a, const char* b )
1103 {
1104     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1105 	*a.clone(), *new sc_lv_base( b ), 3 );
1106 }
1107 
1108 template <class T>
1109 inline
1110 sc_concref_r<sc_lv_base,sc_subref_r<T> >
concat(const char * a,sc_subref_r<T> b)1111 concat( const char* a, sc_subref_r<T> b )
1112 {
1113     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1114 	*new sc_lv_base( a ), *b.clone(), 3 );
1115 }
1116 
1117 template <class T>
1118 inline
1119 sc_concref_r<sc_subref_r<T>,sc_lv_base>
concat(sc_subref_r<T> a,const sc_logic & b)1120 concat( sc_subref_r<T> a, const sc_logic& b )
1121 {
1122     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1123 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1124 }
1125 
1126 template <class T>
1127 inline
1128 sc_concref_r<sc_lv_base,sc_subref_r<T> >
concat(const sc_logic & a,sc_subref_r<T> b)1129 concat( const sc_logic& a, sc_subref_r<T> b )
1130 {
1131     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1132 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1133 }
1134 
1135 template <class T>
1136 inline
1137 sc_concref_r<sc_subref_r<T>,sc_bv_base>
concat(sc_subref_r<T> a,bool b)1138 concat( sc_subref_r<T> a, bool b )
1139 {
1140     return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1141         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1142 }
1143 
1144 template <class T>
1145 inline
1146 sc_concref_r<sc_bv_base,sc_subref_r<T> >
concat(bool a,sc_subref_r<T> b)1147 concat( bool a, sc_subref_r<T> b )
1148 {
1149     return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1150         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1151 }
1152 
1153 
1154 #ifdef SC_DT_MIXED_COMMA_OPERATORS
1155 
1156 template <class T>
1157 inline
1158 sc_concref_r<sc_subref_r<T>,sc_lv_base>
1159 operator , ( sc_subref<T> a, const char* b )
1160 {
1161     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1162 	*a.clone(), *new sc_lv_base( b ), 3 );
1163 }
1164 
1165 template <class T>
1166 inline
1167 sc_concref_r<sc_lv_base,sc_subref_r<T> >
1168 operator , ( const char* a, sc_subref<T> b )
1169 {
1170     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1171 	*new sc_lv_base( a ), *b.clone(), 3 );
1172 }
1173 
1174 template <class T>
1175 inline
1176 sc_concref_r<sc_subref_r<T>,sc_lv_base>
1177 operator , ( sc_subref<T> a, const sc_logic& b )
1178 {
1179     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1180 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1181 }
1182 
1183 template <class T>
1184 inline
1185 sc_concref_r<sc_lv_base,sc_subref_r<T> >
1186 operator , ( const sc_logic& a, sc_subref<T> b )
1187 {
1188     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1189 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1190 }
1191 
1192 template <class T>
1193 inline
1194 sc_concref_r<sc_subref_r<T>,sc_bv_base>
1195 operator , ( sc_subref<T> a, bool b )
1196 {
1197     return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1198         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1199 }
1200 
1201 template <class T>
1202 inline
1203 sc_concref_r<sc_bv_base,sc_subref_r<T> >
1204 operator , ( bool a, sc_subref<T> b )
1205 {
1206     return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1207         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1208 }
1209 
1210 
1211 template <class T>
1212 inline
1213 sc_concref_r<sc_subref_r<T>,sc_lv_base>
concat(sc_subref<T> a,const char * b)1214 concat( sc_subref<T> a, const char* b )
1215 {
1216     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1217 	*a.clone(), *new sc_lv_base( b ), 3 );
1218 }
1219 
1220 template <class T>
1221 inline
1222 sc_concref_r<sc_lv_base,sc_subref_r<T> >
concat(const char * a,sc_subref<T> b)1223 concat( const char* a, sc_subref<T> b )
1224 {
1225     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1226 	*new sc_lv_base( a ), *b.clone(), 3 );
1227 }
1228 
1229 template <class T>
1230 inline
1231 sc_concref_r<sc_subref_r<T>,sc_lv_base>
concat(sc_subref<T> a,const sc_logic & b)1232 concat( sc_subref<T> a, const sc_logic& b )
1233 {
1234     return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1235 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1236 }
1237 
1238 template <class T>
1239 inline
1240 sc_concref_r<sc_lv_base,sc_subref_r<T> >
concat(const sc_logic & a,sc_subref<T> b)1241 concat( const sc_logic& a, sc_subref<T> b )
1242 {
1243     return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1244 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1245 }
1246 
1247 template <class T>
1248 inline
1249 sc_concref_r<sc_subref_r<T>,sc_bv_base>
concat(sc_subref<T> a,bool b)1250 concat( sc_subref<T> a, bool b )
1251 {
1252     return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1253         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1254 }
1255 
1256 template <class T>
1257 inline
1258 sc_concref_r<sc_bv_base,sc_subref_r<T> >
concat(bool a,sc_subref<T> b)1259 concat( bool a, sc_subref<T> b )
1260 {
1261     return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1262         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1263 }
1264 
1265 #endif
1266 
1267 
1268 // ----------------------------------------------------------------------------
1269 //  CLASS TEMPLATE : sc_subref<X>
1270 //
1271 //  Proxy class for sc_proxy part selection (r-value and l-value).
1272 // ----------------------------------------------------------------------------
1273 
1274 template <class X>
1275 inline
1276 sc_subref<X>&
1277 sc_subref<X>::operator = ( const sc_subref_r<X>& b )
1278 {
1279     sc_lv_base t( b ); // (partial) self assignment protection
1280     int len = sc_min( this->length(), t.length() );
1281     if( ! this->reversed() ) {
1282         for( int i = len - 1; i >= 0; -- i ) {
1283             this->m_obj.set_bit( this->m_lo + i, t[i].value() );
1284         }
1285     } else {
1286         for( int i = len - 1; i >= 0; -- i ) {
1287             this->m_obj.set_bit( this->m_lo - i, t[i].value() );
1288         }
1289     }
1290     return *this;
1291 }
1292 
1293 template <class X>
1294 inline
1295 sc_subref<X>&
1296 sc_subref<X>::operator = ( const sc_subref<X>& b )
1297 {
1298     sc_lv_base t( b ); // (partial) self assignment protection
1299     int len = sc_min( this->length(), t.length() );
1300     if( ! this->reversed() ) {
1301         for( int i = len - 1; i >= 0; -- i ) {
1302             this->m_obj.set_bit( this->m_lo + i, t[i].value() );
1303         }
1304     } else {
1305         for( int i = len - 1; i >= 0; -- i ) {
1306             this->m_obj.set_bit( this->m_lo - i, t[i].value() );
1307         }
1308     }
1309     return *this;
1310 }
1311 
1312 
1313 // ----------------------------------------------------------------------------
1314 //  CLASS TEMPLATE : sc_concref_r<X,Y>
1315 //
1316 //  Proxy class for sc_proxy concatenation (r-value only).
1317 // ----------------------------------------------------------------------------
1318 
1319 // r-value concatenation operators and functions
1320 
1321 template <class T1, class T2>
1322 inline
1323 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1324 operator , ( sc_concref_r<T1,T2> a, const char* b )
1325 {
1326     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
1327 	*a.clone(), *new sc_lv_base( b ), 3 );
1328 }
1329 
1330 template <class T1, class T2>
1331 inline
1332 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1333 operator , ( const char* a, sc_concref_r<T1,T2> b )
1334 {
1335     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
1336 	*new sc_lv_base( a ), *b.clone(), 3 );
1337 }
1338 
1339 template <class T1, class T2>
1340 inline
1341 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1342 operator , ( sc_concref_r<T1,T2> a, const sc_logic& b )
1343 {
1344     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
1345 	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1346 }
1347 
1348 template <class T1, class T2>
1349 inline
1350 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1351 operator , ( const sc_logic& a, sc_concref_r<T1,T2> b )
1352 {
1353     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
1354 	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1355 }
1356 
1357 template <class T1, class T2>
1358 inline
1359 sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1360 operator , ( sc_concref_r<T1,T2> a, bool b )
1361 {
1362     return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1363         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1364 }
1365 
1366 template <class T1, class T2>
1367 inline
1368 sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1369 operator , ( bool a, sc_concref_r<T1,T2> b )
1370 {
1371     return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1372         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1373 }
1374 
1375 
1376 template <class T1, class T2>
1377 inline
1378 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
concat(sc_concref_r<T1,T2> a,const char * b)1379 concat( sc_concref_r<T1,T2> a, const char* b )
1380 {
1381     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1382         ( *a.clone(), *new sc_lv_base( b ), 3 );
1383 }
1384 
1385 template <class T1, class T2>
1386 inline
1387 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
concat(const char * a,sc_concref_r<T1,T2> b)1388 concat( const char* a, sc_concref_r<T1,T2> b )
1389 {
1390     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1391         ( *new sc_lv_base( a ), *b.clone(), 3 );
1392 }
1393 
1394 template <class T1, class T2>
1395 inline
1396 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
concat(sc_concref_r<T1,T2> a,const sc_logic & b)1397 concat( sc_concref_r<T1,T2> a, const sc_logic& b )
1398 {
1399     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1400         ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1401 }
1402 
1403 template <class T1, class T2>
1404 inline
1405 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
concat(const sc_logic & a,sc_concref_r<T1,T2> b)1406 concat( const sc_logic& a, sc_concref_r<T1,T2> b )
1407 {
1408     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1409         ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1410 }
1411 
1412 template <class T1, class T2>
1413 inline
1414 sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
concat(sc_concref_r<T1,T2> a,bool b)1415 concat( sc_concref_r<T1,T2> a, bool b )
1416 {
1417     return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1418         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1419 }
1420 
1421 template <class T1, class T2>
1422 inline
1423 sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
concat(bool a,sc_concref_r<T1,T2> b)1424 concat( bool a, sc_concref_r<T1,T2> b )
1425 {
1426     return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1427         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1428 }
1429 
1430 
1431 #ifdef SC_DT_MIXED_COMMA_OPERATORS
1432 
1433 template <class T1, class T2>
1434 inline
1435 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1436 operator , ( sc_concref<T1,T2> a, const char* b )
1437 {
1438     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1439         ( *a.clone(), *new sc_lv_base( b ), 3 );
1440 }
1441 
1442 template <class T1, class T2>
1443 inline
1444 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1445 operator , ( const char* a, sc_concref<T1,T2> b )
1446 {
1447     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1448         ( *new sc_lv_base( a ), *b.clone(), 3 );
1449 }
1450 
1451 template <class T1, class T2>
1452 inline
1453 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1454 operator , ( sc_concref<T1,T2> a, const sc_logic& b )
1455 {
1456     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1457         ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1458 }
1459 
1460 template <class T1, class T2>
1461 inline
1462 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1463 operator , ( const sc_logic& a, sc_concref<T1,T2> b )
1464 {
1465     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1466         ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1467 }
1468 
1469 template <class T1, class T2>
1470 inline
1471 sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1472 operator , ( sc_concref<T1,T2> a, bool b )
1473 {
1474     return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1475         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1476 }
1477 
1478 template <class T1, class T2>
1479 inline
1480 sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1481 operator , ( bool a, sc_concref<T1,T2> b )
1482 {
1483     return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1484         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1485 }
1486 
1487 
1488 template <class T1, class T2>
1489 inline
1490 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
concat(sc_concref<T1,T2> a,const char * b)1491 concat( sc_concref<T1,T2> a, const char* b )
1492 {
1493     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1494         ( *a.clone(), *new sc_lv_base( b ), 3 );
1495 }
1496 
1497 template <class T1, class T2>
1498 inline
1499 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
concat(const char * a,sc_concref<T1,T2> b)1500 concat( const char* a, sc_concref<T1,T2> b )
1501 {
1502     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1503         ( *new sc_lv_base( a ), *b.clone(), 3 );
1504 }
1505 
1506 template <class T1, class T2>
1507 inline
1508 sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
concat(sc_concref<T1,T2> a,const sc_logic & b)1509 concat( sc_concref<T1,T2> a, const sc_logic& b )
1510 {
1511     return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1512         ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1513 }
1514 
1515 template <class T1, class T2>
1516 inline
1517 sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
concat(const sc_logic & a,sc_concref<T1,T2> b)1518 concat( const sc_logic& a, sc_concref<T1,T2> b )
1519 {
1520     return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1521         ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1522 }
1523 
1524 template <class T1, class T2>
1525 inline
1526 sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
concat(sc_concref<T1,T2> a,bool b)1527 concat( sc_concref<T1,T2> a, bool b )
1528 {
1529     return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1530         ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1531 }
1532 
1533 template <class T1, class T2>
1534 inline
1535 sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
concat(bool a,sc_concref<T1,T2> b)1536 concat( bool a, sc_concref<T1,T2> b )
1537 {
1538     return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1539         ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1540 }
1541 
1542 #endif
1543 
1544 
1545 // ----------------------------------------------------------------------------
1546 //  CLASS TEMPLATE : sc_proxy<T>
1547 //
1548 //  Base class template for bit/logic vector classes.
1549 //  (Barton/Nackmann implementation)
1550 // ----------------------------------------------------------------------------
1551 
1552 // r-value concatenation operators and functions
1553 
1554 template <class T>
1555 inline
1556 sc_concref_r<T,sc_lv_base>
1557 operator , ( const sc_proxy<T>& a, const char* b )
1558 {
1559     return sc_concref_r<T,sc_lv_base>
1560       ( a.back_cast(), *new sc_lv_base( b ), 2 );
1561 }
1562 
1563 template <class T>
1564 inline
1565 sc_concref_r<sc_lv_base,T>
1566 operator , ( const char* a, const sc_proxy<T>& b )
1567 {
1568     return sc_concref_r<sc_lv_base,T>
1569       ( *new sc_lv_base( a ), b.back_cast(), 1 );
1570 }
1571 
1572 template <class T>
1573 inline
1574 sc_concref_r<T,sc_lv_base>
1575 operator , ( const sc_proxy<T>& a, const sc_logic& b )
1576 {
1577     return sc_concref_r<T,sc_lv_base>
1578       ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1579 }
1580 
1581 template <class T>
1582 inline
1583 sc_concref_r<sc_lv_base,T>
1584 operator , ( const sc_logic& a, const sc_proxy<T>& b )
1585 {
1586     return sc_concref_r<sc_lv_base,T>
1587       ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1588 }
1589 
1590 template <class T>
1591 inline
1592 sc_concref_r<T,sc_bv_base>
1593 operator , ( const sc_proxy<T>& a, bool b )
1594 {
1595     return sc_concref_r<T,sc_bv_base>
1596         ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1597 }
1598 
1599 template <class T>
1600 inline
1601 sc_concref_r<sc_bv_base,T>
1602 operator , ( bool a, const sc_proxy<T>& b )
1603 {
1604     return sc_concref_r<sc_bv_base,T>
1605       ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1606 }
1607 
1608 
1609 template <class T>
1610 inline
1611 sc_concref_r<T,sc_lv_base>
concat(const sc_proxy<T> & a,const char * b)1612 concat( const sc_proxy<T>& a, const char* b )
1613 {
1614     return sc_concref_r<T,sc_lv_base>
1615       ( a.back_cast(), *new sc_lv_base( b ), 2 );
1616 }
1617 
1618 template <class T>
1619 inline
1620 sc_concref_r<sc_lv_base,T>
concat(const char * a,const sc_proxy<T> & b)1621 concat( const char* a, const sc_proxy<T>& b )
1622 {
1623     return sc_concref_r<sc_lv_base,T>
1624       ( *new sc_lv_base( a ), b.back_cast(), 1 );
1625 }
1626 
1627 template <class T>
1628 inline
1629 sc_concref_r<T,sc_lv_base>
concat(const sc_proxy<T> & a,const sc_logic & b)1630 concat( const sc_proxy<T>& a, const sc_logic& b )
1631 {
1632     return sc_concref_r<T,sc_lv_base>
1633       ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1634 }
1635 
1636 template <class T>
1637 inline
1638 sc_concref_r<sc_lv_base,T>
concat(const sc_logic & a,const sc_proxy<T> & b)1639 concat( const sc_logic& a, const sc_proxy<T>& b )
1640 {
1641     return sc_concref_r<sc_lv_base,T>
1642       ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1643 }
1644 
1645 template <class T>
1646 inline
1647 sc_concref_r<T,sc_bv_base>
concat(const sc_proxy<T> & a,bool b)1648 concat( const sc_proxy<T>& a, bool b )
1649 {
1650     return sc_concref_r<T,sc_bv_base>
1651       ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1652 }
1653 
1654 template <class T>
1655 inline
1656 sc_concref_r<sc_bv_base,T>
concat(bool a,const sc_proxy<T> & b)1657 concat( bool a, const sc_proxy<T>& b )
1658 {
1659     return sc_concref_r<sc_bv_base,T>
1660       ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1661 }
1662 
1663 
1664 #ifdef SC_DT_MIXED_COMMA_OPERATORS
1665 
1666 template <class T>
1667 inline
1668 sc_concref_r<T,sc_lv_base>
1669 operator , ( sc_proxy<T>& a, const char* b )
1670 {
1671     return sc_concref_r<T,sc_lv_base>
1672       ( a.back_cast(), *new sc_lv_base( b ), 2 );
1673 }
1674 
1675 template <class T>
1676 inline
1677 sc_concref_r<sc_lv_base,T>
1678 operator , ( const char* a, sc_proxy<T>& b )
1679 {
1680     return sc_concref_r<sc_lv_base,T>
1681         ( *new sc_lv_base( a ), b.back_cast(), 1 );
1682 }
1683 
1684 template <class T>
1685 inline
1686 sc_concref_r<T,sc_lv_base>
1687 operator , ( sc_proxy<T>& a, const sc_logic& b )
1688 {
1689     return sc_concref_r<T,sc_lv_base>
1690         ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1691 }
1692 
1693 template <class T>
1694 inline
1695 sc_concref_r<sc_lv_base,T>
1696 operator , ( const sc_logic& a, sc_proxy<T>& b )
1697 {
1698     return sc_concref_r<sc_lv_base,T>
1699         ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1700 }
1701 
1702 template <class T>
1703 inline
1704 sc_concref_r<T,sc_bv_base>
1705 operator , ( sc_proxy<T>& a, bool b )
1706 {
1707     return sc_concref_r<T,sc_bv_base>
1708         ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1709 }
1710 
1711 template <class T>
1712 inline
1713 sc_concref_r<sc_bv_base,T>
1714 operator , ( bool a, sc_proxy<T>& b )
1715 {
1716     return sc_concref_r<sc_bv_base,T>
1717         ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1718 }
1719 
1720 
1721 template <class T>
1722 inline
1723 sc_concref_r<T,sc_lv_base>
concat(sc_proxy<T> & a,const char * b)1724 concat( sc_proxy<T>& a, const char* b )
1725 {
1726     return sc_concref_r<T,sc_lv_base>
1727         ( a.back_cast(), *new sc_lv_base( b ), 2 );
1728 }
1729 
1730 template <class T>
1731 inline
1732 sc_concref_r<sc_lv_base,T>
concat(const char * a,sc_proxy<T> & b)1733 concat( const char* a, sc_proxy<T>& b )
1734 {
1735     return sc_concref_r<sc_lv_base,T>
1736         ( *new sc_lv_base( a ), b.back_cast(), 1 );
1737 }
1738 
1739 template <class T>
1740 inline
1741 sc_concref_r<T,sc_lv_base>
concat(sc_proxy<T> & a,const sc_logic & b)1742 concat( sc_proxy<T>& a, const sc_logic& b )
1743 {
1744     return sc_concref_r<T,sc_lv_base>
1745         ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1746 }
1747 
1748 template <class T>
1749 inline
1750 sc_concref_r<sc_lv_base,T>
concat(const sc_logic & a,sc_proxy<T> & b)1751 concat( const sc_logic& a, sc_proxy<T>& b )
1752 {
1753     return sc_concref_r<sc_lv_base,T>
1754         ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1755 }
1756 
1757 template <class T>
1758 inline
1759 sc_concref_r<T,sc_bv_base>
concat(sc_proxy<T> & a,bool b)1760 concat( sc_proxy<T>& a, bool b )
1761 {
1762     return sc_concref_r<T,sc_bv_base>
1763         ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1764 }
1765 
1766 template <class T>
1767 inline
1768 sc_concref_r<sc_bv_base,T>
concat(bool a,sc_proxy<T> & b)1769 concat( bool a, sc_proxy<T>& b )
1770 {
1771     return sc_concref_r<sc_bv_base,T>
1772         ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1773 }
1774 
1775 #endif
1776 
1777 // extern template instantiations
1778 SC_API_TEMPLATE_DECL_ sc_proxy<sc_lv_base>;
1779 SC_API_TEMPLATE_DECL_ sc_proxy<sc_bv_base>;
1780 
1781 } // namespace sc_dt
1782 
1783 
1784 #endif
1785