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

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0