source: branches/with_autoconf/src/sc_int.h @ 49

Last change on this file since 49 was 24, checked in by nipo, 16 years ago

Sync with trunk, avoid warning about pointer soup

File size: 8.8 KB
Line 
1/*------------------------------------------------------------\
2|                                                             |
3| Tool    :                  systemcass                       |
4|                                                             |
5| File    :                 sc_int.h                          |
6|                                                             |
7| Author  :                 Buchmann Richard                  |
8|                                                             |
9| Date    :                   09_07_2004                      |
10|                                                             |
11\------------------------------------------------------------*/
12#ifndef __SC_INT_H__
13#define __SC_INT_H__
14
15#include <data_field.h>
16#include <sc_numrep.h>
17#include <sc_bit.h>
18#include <sc_logic.h>
19#include <sc_bv.h>
20#include <cstdlib>
21
22// ----------------------------------------------------------------------------
23//  CLASS : sc_int<W>
24//
25//  Template class sc_int<W> is the interface that the user sees. It is
26//  derived from sc_int_base and most of its methods are just wrappers
27//  that call the corresponding method in the parent class. Note that
28//  the width of sc_int datatype is specified as a template parameter.
29// ----------------------------------------------------------------------------
30
31#include "sc_nbdefs.h"
32
33namespace sc_dt {
34
35typedef sc_int<1> sc_int_bit_ref;
36typedef sc_int<1> sc_int_bit_ref_r;
37
38//
39#define MASK32(W) ((~ (const uint32)0) >> (sizeof (uint32) * 8 - W))
40#define MASK64(W) ((~ (const uint64)0) >> (sizeof (uint64) * 8 - W))
41//
42
43template<int W> struct s_int_type { typedef int64 int_type;};
44#define DECLAR_INT_TYPE(W) template<> struct s_int_type<W> { typedef smallest_int int_type; } // not declared as in8 because << operator threats like a character
45DECLAR_INT_TYPE( 1);
46DECLAR_INT_TYPE( 2);
47DECLAR_INT_TYPE( 3);
48DECLAR_INT_TYPE( 4);
49DECLAR_INT_TYPE( 5);
50DECLAR_INT_TYPE( 6);
51DECLAR_INT_TYPE( 7);
52DECLAR_INT_TYPE( 8);
53#undef DECLAR_INT_TYPE
54#define DECLAR_INT_TYPE(W) template<> struct s_int_type<W> { typedef int16 int_type; }
55DECLAR_INT_TYPE( 9);
56DECLAR_INT_TYPE(10);
57DECLAR_INT_TYPE(11);
58DECLAR_INT_TYPE(12);
59DECLAR_INT_TYPE(13);
60DECLAR_INT_TYPE(14);
61DECLAR_INT_TYPE(15);
62DECLAR_INT_TYPE(16);
63#undef DECLAR_INT_TYPE
64#define DECLAR_INT_TYPE(W) template<> struct s_int_type<W> { typedef int32 int_type; }
65DECLAR_INT_TYPE(17);
66DECLAR_INT_TYPE(18);
67DECLAR_INT_TYPE(19);
68DECLAR_INT_TYPE(20);
69DECLAR_INT_TYPE(21);
70DECLAR_INT_TYPE(22);
71DECLAR_INT_TYPE(23);
72DECLAR_INT_TYPE(24);
73DECLAR_INT_TYPE(25);
74DECLAR_INT_TYPE(26);
75DECLAR_INT_TYPE(27);
76DECLAR_INT_TYPE(28);
77DECLAR_INT_TYPE(29);
78DECLAR_INT_TYPE(30);
79DECLAR_INT_TYPE(31);
80DECLAR_INT_TYPE(32);
81#undef DECLAR_INT_TYPE
82
83// --------------------------------
84// CLASS : sc_int_subref_r
85//
86// Used for range, concat functions
87
88class sc_int_subref_r
89{
90  template <int W> friend class sc_dt::sc_int;
91  int       left, right;
92  public : int64    val;
93  sc_int_subref_r (int64 val_, int left_, int right_)
94  {
95    val = val_; left = left_; right = right_;
96  }
97  public:
98  inline int64 read () const { return val; }
99  inline const sc_int_subref_r& operator | (const sc_int_subref_r &v) const
100  { print_warning (); return *this; }
101
102  private :void print_warning () const;
103};
104
105//
106// to fix : propagation of the sign flag
107//
108
109class sc_int_subref_r;
110
111template< int W /* = SC_INTWIDTH */>
112class sc_int
113{
114  /***********************/
115  /* SYSTEMCASS SPECIFIC */
116  /***********************/
117  typedef sc_int<W>                         this_type;
118  typedef typename s_int_type<W>::int_type  data_type;
119
120  typedef data_type sc_int_subref;
121//typedef data_type sc_int_subref_r;
122    /* removed since "operator ," was going wrong */
123
124// internal
125        union {
126    val_field<W,(sizeof (data_type) * 8) - W,data_type> vf; /* To compute */
127                data_type val;          /* To return an int reference (read function) */
128//        data_type valW:W; /* works with little endianess only */
129//  bool      valB[W]; /* removed since 1 bool takes 1 byte */
130        };
131
132  /***********************/
133  /*        L R M        */
134  /***********************/
135public:
136  sc_int()                 { val = 0; }
137//  sc_int(data_type val_)  { val = 0; write (val_); }
138  sc_int (const char *a)   { val = 0; write (std::atoi (a)); }
139  sc_int (unsigned short a){ val = 0; write (a); }
140  sc_int (short a)         { val = 0; write (a); }
141  sc_int (unsigned long a) { val = 0; write (a); }
142  sc_int (long a)          { val = 0; write (a); }
143  sc_int (unsigned int a)  { val = 0; write (a); }
144  sc_int (int a)           { val = 0; write (a); }
145  sc_int (int64 a)         { val = 0; write (a); }
146  sc_int (uint64 a)        { val = 0; write (a); }
147  sc_int (double a)        { val = 0; write (a); }
148
149  template <int W2> sc_int (const sc_int<W2> &val_) { val = 0; write (val_.read());}
150  /* this template doesn't redefine default copy constructor of sc_int.
151   * So, we define by this way
152   */
153
154  sc_int (const sc_int &val_) { val = val_.val; }
155  sc_int (const sc_int_subref_r &a) { val = 0; write (a); } 
156    /* the user needs to cast explicitly result of range () method. */
157
158  /***********************/
159  /* SYSTEMCASS SPECIFIC */
160  /***********************/
161#if 0
162  bool is_negative () const {
163    return (valW >> (W-1)) == 1;
164  }
165#endif
166  // read/write
167  inline const data_type& read() const { return val; }
168  inline void write(data_type val_)    { vf.valW = val_; }
169  template <int W2> inline void write (const sc_int<W2> val_) { write (val_.read ()); }
170//inline void write (const sc_int<W> val_) { write (val_.read()); };
171  inline void write (const sc_int_subref_r& s) { write (s.read()); }
172
173  /***********************/
174  /*        L R M        */
175  /***********************/
176  // operators
177  inline operator const data_type& () const { return read (); }
178//  inline void write(int64 val_) { val = val_ & MASK64(W); }
179//  inline void write(signed int val_)   { val = val_ & MASK32(W); }
180        template <typename T> inline sc_int& operator = (const T& val_) 
181  { write (val_); return *this; }
182        inline sc_int& operator = (const sc_int_subref_r& a) 
183  { write (a); return *this; }
184
185  // explicit conversions
186  inline uint32         to_uint   () const {return val & MASK32(W);};
187  inline int32          to_int    () const {return val & MASK32(W);};
188  inline uint64         to_uint64 () const {return val & MASK64(W);};
189  inline int64          to_int64  () const {return val & MASK64(W);};
190
191  // explicit conversion to character string
192  const sc_string to_string       ( sc_numrep numrep = SC_DEC ) const 
193  { return sc_dt::to_string (val, W, numrep); }
194  const sc_string to_dec() const  { return to_string (SC_DEC); }
195  const sc_string to_bin() const  { return to_string (SC_BIN); }
196  const sc_string to_oct() const  { return to_string (SC_OCT); }
197  const sc_string to_hex() const  { return to_string (SC_HEX); }
198
199  // arithmetic
200#define DEFINE_OPERATOR(OPER)        \
201  template <typename T>              \
202  inline sc_int& operator OPER (T v) \
203  { vf.valW OPER v; return *this; }
204
205  DEFINE_OPERATOR(<<=)
206  DEFINE_OPERATOR(>>=)
207  DEFINE_OPERATOR(+=)
208  DEFINE_OPERATOR(-=)
209  DEFINE_OPERATOR(*=)
210  DEFINE_OPERATOR(/=)
211  DEFINE_OPERATOR(%=)
212  DEFINE_OPERATOR(&=)
213  DEFINE_OPERATOR(|=)
214  DEFINE_OPERATOR(^=)
215#undef DEFINE_OPERATOR
216
217  inline sc_int_bit_ref& operator [] (int v)
218  { return (vf.valW >> v) & 1; }
219  inline sc_int_bit_ref_r& operator [] (int v) const
220  { return (vf.valW >> v) & 1; }
221
222  template <int W2> 
223  inline sc_int<W+W2> operator , (const sc_int<W2> &b) const
224  { sc_int<W+W2> res = read() << W2; res += b.read(); return res; }
225#if 0 
226std::cerr << "[" << to_bin() << "," << b.to_bin() << " = " << res.to_bin() << "]\n";
227#endif
228
229  inline sc_int<W+1> operator , (bool b) const
230  { sc_int<W+1> res = read(); res <<= 1; res += b; return res; }
231#if 0 
232std::cerr << "[" << to_bin() << "," << b.to_bin() << " = " << res.to_bin() << "]\n";
233#endif
234
235  template <int W2>
236  inline sc_int<W2> operator , (const sc_int_subref_r &v) const
237  { std::cerr << "Warning : \n"; return sc_int<W2> (v.read()); }
238
239  inline sc_int_subref range (int left, int right)
240  { return (data_type)((data_type) (((data_type)~(0)) >> (sizeof (data_type) * 8 - left - 1)) & val) >> right; }
241
242  inline sc_int_subref_r range (int left, int right) const
243  { return sc_int_subref_r (((data_type) (((data_type)~(0)) >> (sizeof (data_type) * 8 - left - 1)) & val) >> right, left, right); }
244#if 0
245std::cerr << "range(" << left << "," << right << ")\n";
246std::cerr << "val = " << val << "\n";
247std::cerr << "~0 >> " << (sizeof (data_type) * 8 - left - 1) << " = " << (data_type) (((data_type)~(0)) >> (sizeof (data_type) * 8 - left - 1)) << "\n";
248std::cerr <<  ((data_type) ((((data_type)~(0)) >> (sizeof (data_type) * 8 - left - 1)) & val) >> right) << "\n";
249std::cerr << "data_type = " << sizeof (data_type) << "\n";
250#endif
251
252};
253
254inline std::ostream& operator << (std::ostream &o, const sc_int_subref_r& s)
255{ return o << s.val; }
256
257} /* end of sc_dt namespace */
258
259#endif /* __SC_INT_H__ */
260
Note: See TracBrowser for help on using the repository browser.