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