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