gem5  v22.1.0.0
sc_uint_base.cc
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_uint_base.cpp -- contains interface definitions between sc_uint and
23  sc_signed, sc_unsigned, and definitions for sc_uint_subref.
24 
25  Original Author: Ali Dasdan, Synopsys, Inc.
26 
27  *****************************************************************************/
28 
29 /*****************************************************************************
30 
31  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32  changes you are making here.
33 
34  Name, Affiliation, Date:
35  Description of Modification:
36 
37  *****************************************************************************/
38 
39 
40 // $Log: sc_uint_base.cpp,v $
41 // Revision 1.5 2011/02/18 20:19:15 acg
42 // Andy Goodrich: updating Copyright notice.
43 //
44 // Revision 1.4 2010/02/04 22:23:29 acg
45 // Andy Goodrich: fixed bug in concatenation reads for part selections,
46 // the mask being used was 32 bits and should have been 64 bits.
47 //
48 // Revision 1.3 2008/06/19 17:47:57 acg
49 // Andy Goodrich: fixes for bugs. See 2.2.1 RELEASENOTES.
50 //
51 // Revision 1.2 2007/11/04 21:27:00 acg
52 // Andy Goodrich: changes to make sure the proper value is returned from
53 // concat_get_data().
54 //
55 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
56 // SystemC 2.3
57 //
58 // Revision 1.3 2006/01/13 18:49:32 acg
59 // Added $Log command so that CVS check in comments are reproduced in the
60 // source.
61 //
62 
63 #include <sstream>
64 
73 
74 // explicit template instantiations
75 namespace sc_core
76 {
77 
78 template class sc_vpool<sc_dt::sc_uint_bitref>;
79 template class sc_vpool<sc_dt::sc_uint_subref>;
80 
81 } // namespace sc_core
82 
83 namespace sc_dt
84 {
85 
86 // to avoid code bloat in sc_uint_concat<T1,T2>
87 
88 void
90 {
91  std::stringstream msg;
92  msg << "sc_uint_concref<T1,T2> initialization: length = " << length <<
93  "violates 1 <= length <= " << SC_INTWIDTH;
95  sc_core::sc_abort(); // can't recover from here
96 }
97 
98 
99 
100 // ----------------------------------------------------------------------------
101 // CLASS : sc_uint_bitref
102 //
103 // Proxy class for sc_uint bit selection (r-value and l-value).
104 // ----------------------------------------------------------------------------
105 
106 sc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
107 
108 // concatenation methods:
109 
110 // #### OPTIMIZE
111 void
112 sc_uint_bitref::concat_set(int64 src, int low_i)
113 {
114  sc_uint_base aa(1);
115  *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
116 }
117 
118 void
119 sc_uint_bitref::concat_set(const sc_signed &src, int low_i)
120 {
121  sc_uint_base aa(1);
122  if (low_i < src.length())
123  *this = aa = 1 & (src >> low_i);
124  else
125  *this = aa = (src < 0) ? (int_type)-1 : 0;
126 }
127 
128 void
129 sc_uint_bitref::concat_set(const sc_unsigned &src, int low_i)
130 {
131  sc_uint_base aa(1);
132  if (low_i < src.length())
133  *this = aa = 1 & (src >> low_i);
134  else
135  *this = aa = 0;
136 }
137 
138 void
139 sc_uint_bitref::concat_set(uint64 src, int low_i)
140 {
141  sc_uint_base aa(1);
142  *this = aa = (low_i < 64) ? src >> low_i : 0;
143 }
144 
145 
146 // other methods
147 void
148 sc_uint_bitref::scan(::std::istream &is)
149 {
150  bool b;
151  is >> b;
152  *this = b;
153 }
154 
155 
156 // ----------------------------------------------------------------------------
157 // CLASS : sc_uint_subref_r
158 //
159 // Proxy class for sc_uint part selection (l-value).
160 // ----------------------------------------------------------------------------
161 
162 bool
163 sc_uint_subref_r::concat_get_ctrl(sc_digit *dst_p, int low_i) const
164 {
165  int dst_i; // Word in dst_p now processing.
166  int end_i; // Highest order word in dst_p to process.
167  int left_shift; // Left shift for val.
168  uint_type mask; // Mask for bits to extract or keep.
169 
170  dst_i = low_i / BITS_PER_DIGIT;
171  left_shift = low_i % BITS_PER_DIGIT;
172  end_i = (low_i + (m_left-m_right)) / BITS_PER_DIGIT;
173 
174  mask = ~(~UINT_ZERO << left_shift);
175  dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
176 
177  dst_i++;
178  for (; dst_i <= end_i; dst_i++)
179  dst_p[dst_i] = 0;
180 
181  return false;
182 }
183 
184 bool
185 sc_uint_subref_r::concat_get_data(sc_digit *dst_p, int low_i) const
186 {
187  int dst_i; // Word in dst_p now processing.
188  int end_i; // Highest order word in dst_p to process.
189  int high_i; // Index of high order bit in dst_p to set.
190  int left_shift; // Left shift for val.
191  uint_type mask; // Mask for bits to extract or keep.
192  bool result; // True if inserting non-zero value.
193  uint_type val; // Selection value extracted from m_obj_p.
194 
195  dst_i = low_i / BITS_PER_DIGIT;
196  left_shift = low_i % BITS_PER_DIGIT;
197  high_i = low_i + (m_left-m_right);
198  end_i = high_i / BITS_PER_DIGIT;
199  mask = ~mask_int[m_left][m_right];
200  val = (m_obj_p->m_val & mask) >> m_right;
201  result = val != 0;
202 
203  // PROCESS THE FIRST WORD:
204  mask = ~(~UINT_ZERO << left_shift);
205  dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
206  ((val << left_shift) & DIGIT_MASK));
207 
208  switch (end_i - dst_i) {
209  // BITS ARE ACROSS TWO WORDS:
210  case 1:
211  dst_i++;
212  val >>= (BITS_PER_DIGIT-left_shift);
213  dst_p[dst_i] = (sc_digit)val;
214  break;
215 
216  // BITS ARE ACROSS THREE WORDS:
217  case 2:
218  dst_i++;
219  val >>= (BITS_PER_DIGIT-left_shift);
220  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
221  val >>= BITS_PER_DIGIT;
222  dst_p[dst_i] = (sc_digit)val;
223  break;
224 
225  // BITS ARE ACROSS THREE WORDS:
226  case 3:
227  dst_i++;
228  val >>= (BITS_PER_DIGIT-left_shift);
229  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
230  val >>= BITS_PER_DIGIT;
231  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
232  val >>= BITS_PER_DIGIT;
233  dst_p[dst_i] = (sc_digit)val;
234  break;
235  }
236  return result;
237 }
238 
239 // ----------------------------------------------------------------------------
240 // CLASS : sc_uint_subref
241 //
242 // Proxy class for sc_uint part selection (r-value and l-value).
243 // ----------------------------------------------------------------------------
244 
245 sc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
246 
247 // assignment operators
248 
250 sc_uint_subref::operator = (uint_type v)
251 {
252  uint_type val = m_obj_p->m_val;
253  uint_type mask = mask_int[m_left][m_right];
254  val &= mask;
255  val |= (v << m_right) & ~mask;
256  m_obj_p->m_val = val;
257  m_obj_p->extend_sign();
258  return *this;
259 }
260 
262 sc_uint_subref::operator = (const sc_signed &a)
263 {
264  sc_uint_base aa(length());
265  return (*this = aa = a);
266 }
267 
269 sc_uint_subref::operator = (const sc_unsigned &a)
270 {
271  sc_uint_base aa(length());
272  return (*this = aa = a);
273 }
274 
276 sc_uint_subref::operator = (const sc_bv_base &a)
277 {
278  sc_uint_base aa(length());
279  return (*this = aa = a);
280 }
281 
283 sc_uint_subref::operator = (const sc_lv_base &a)
284 {
285  sc_uint_base aa(length());
286  return (*this = aa = a);
287 }
288 
289 // concatenation methods:
290 
291 // #### OPTIMIZE
292 void
293 sc_uint_subref::concat_set(int64 src, int low_i)
294 {
295  sc_uint_base aa(length());
296  *this = aa = (low_i < 64) ? src >> low_i : src >> 63;
297 }
298 
299 void
300 sc_uint_subref::concat_set(const sc_signed &src, int low_i)
301 {
302  sc_uint_base aa(length());
303  if (low_i < src.length())
304  *this = aa = src >> low_i;
305  else
306  *this = aa = (src < 0) ? (int_type)-1 : 0;
307 }
308 
309 void
310 sc_uint_subref::concat_set(const sc_unsigned &src, int low_i)
311 {
312  sc_uint_base aa(length());
313  if (low_i < src.length())
314  *this = aa = src >> low_i;
315  else
316  *this = aa = 0;
317 }
318 
319 void
320 sc_uint_subref::concat_set(uint64 src, int low_i)
321 {
322  sc_uint_base aa(length());
323  *this = aa = (low_i < 64) ? src >> low_i : 0;
324 }
325 
326 // other methods
327 void
328 sc_uint_subref::scan(::std::istream &is)
329 {
330  std::string s;
331  is >> s;
332  *this = s.c_str();
333 }
334 
335 
336 // ----------------------------------------------------------------------------
337 // CLASS : sc_uint_base
338 //
339 // Base class for sc_uint.
340 // ----------------------------------------------------------------------------
341 
342 // support methods
343 
344 void
345 sc_uint_base::invalid_length() const
346 {
347  std::stringstream msg;
348  msg << "sc_uint[_base] initialization: length = " << m_len <<
349  " violates 1 <= length <= " << SC_INTWIDTH;
351  sc_core::sc_abort(); // can't recover from here}
352 }
353 
354 void
355 sc_uint_base::invalid_index(int i) const
356 {
357  std::stringstream msg;
358  msg << "sc_uint[_base] bit selection: index = " << i <<
359  " violates 0 <= index <= " << (m_len - 1);
361  sc_core::sc_abort(); // can't recover from here
362 }
363 
364 void
365 sc_uint_base::invalid_range(int l, int r) const
366 {
367  std::stringstream msg;
368  msg << "sc_uint[_base] part selection: " <<
369  "left = " << l << ", right = " << r << " violates " <<
370  (m_len - 1) << " >= left >= right >= 0";
372  sc_core::sc_abort(); // can't recover from here
373 }
374 
375 
376 void
377 sc_uint_base::check_value() const
378 {
379  uint_type limit = (~UINT_ZERO >> m_ulen);
380  if (m_val > limit) {
381  std::stringstream msg;
382  msg << "sc_uint[_base]: value does not fit into a length of " << m_len;
384  }
385 }
386 
387 
388 // constructors
389 sc_uint_base::sc_uint_base(const sc_bv_base &v) :
390  m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
391 {
392  check_length();
393  *this = v;
394 }
396  m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
397 {
398  check_length();
399  *this = v;
400 }
402  m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
403 {
404  check_length();
405  *this = v.to_uint64();
406 }
408  m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
409 {
410  check_length();
411  *this = v.to_uint64();
412 }
414  m_val(0), m_len(v.length()), m_ulen(SC_INTWIDTH - m_len)
415 {
416  check_length();
417  *this = v.to_uint64();
418 }
419 
421  m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
422 {
423  check_length();
424  *this = a.to_uint64();
425 }
426 
428  m_val(0), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
429 {
430  check_length();
431  *this = a.to_uint64();
432 }
433 
434 // assignment operators
435 
436 sc_uint_base &
438 {
439  int minlen = sc_min(m_len, a.length());
440  int i = 0;
441  for (; i < minlen; ++i) {
442  set(i, a.test(i));
443  }
444  bool sgn = a.sign();
445  for (; i < m_len; ++i) {
446  // sign extension
447  set(i, sgn);
448  }
449  extend_sign();
450  return *this;
451 }
452 
453 sc_uint_base &
455 {
456  int minlen = sc_min(m_len, a.length());
457  int i = 0;
458  for (; i < minlen; ++i) {
459  set(i, a.test(i));
460  }
461  for (; i < m_len; ++i) {
462  // zero extension
463  set(i, 0);
464  }
465  extend_sign();
466  return *this;
467 }
468 
469 
470 sc_uint_base &
472 {
473  int minlen = sc_min(m_len, a.length());
474  int i = 0;
475  for (; i < minlen; ++i) {
476  set(i, a.get_bit(i));
477  }
478  for (; i < m_len; ++i) {
479  // zero extension
480  set(i, 0);
481  }
482  extend_sign();
483  return *this;
484 }
485 
486 sc_uint_base &
488 {
489  int minlen = sc_min(m_len, a.length());
490  int i = 0;
491  for (; i < minlen; ++i) {
492  set(i, sc_logic(a.get_bit(i)).to_bool());
493  }
494  for (; i < m_len; ++i) {
495  // zero extension
496  set(i, 0);
497  }
498  extend_sign();
499  return *this;
500 }
501 
502 sc_uint_base &
504 {
505  if (a == 0) {
507  "character string is zero");
508  } else if (*a == 0) {
510  "character string is empty");
511  } else try {
512  int len = m_len;
513  sc_ufix aa(a, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
514  return this->operator = (aa);
515  } catch(const sc_core::sc_report &) {
516  std::stringstream msg;
517  msg << "character string '" << a << "' is not valid";
519  }
520  return *this;
521 }
522 
523 
524 // explicit conversion to character string
525 const std::string
527 {
528  int len = m_len;
529  sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
530  return aa.to_string(numrep);
531 }
532 
533 const std::string
534 sc_uint_base::to_string(sc_numrep numrep, bool w_prefix) const
535 {
536  int len = m_len;
537  sc_ufix aa(*this, len, len, SC_TRN, SC_WRAP, 0, SC_ON);
538  return aa.to_string(numrep, w_prefix);
539 }
540 
541 
542 // reduce methods
543 bool
545 {
546  return (m_val == (~UINT_ZERO >> m_ulen));
547 }
548 
549 bool
551 {
552  return (m_val != uint_type(0));
553 }
554 
555 bool
557 {
559  uint_type val = m_val;
560  int n = SC_INTWIDTH;
561  do {
562  n >>= 1;
563  mask >>= n;
564  val = ((val & (mask << n)) >> n) ^ (val & mask);
565  } while (n != 1);
566  return (val != uint_type(0));
567 }
568 
569 
570 bool
571 sc_uint_base::concat_get_ctrl(sc_digit *dst_p, int low_i) const
572 {
573  int dst_i; // Word in dst_p now processing.
574  int end_i; // Highest order word in dst_p to process.
575  int left_shift; // Left shift for val.
576  uint_type mask; // Mask for bits to extract or keep.
577 
578  dst_i = low_i / BITS_PER_DIGIT;
579  left_shift = low_i % BITS_PER_DIGIT;
580  end_i = (low_i + (m_len - 1)) / BITS_PER_DIGIT;
581 
582  // PROCESS THE FIRST WORD:
583  mask = ~(~UINT_ZERO << left_shift);
584  dst_p[dst_i] = (sc_digit)((dst_p[dst_i] & mask));
585 
586  dst_i++;
587  for (; dst_i <= end_i; dst_i++)
588  dst_p[dst_i] = 0;
589  return false;
590 }
591 
592 //-----------------------------------------------------------------------------
593 //"sc_uint_base::concat_get_data"
594 //
595 // This method transfers the value of this object instance to the supplied
596 // array of sc_unsigned digits starting with the bit specified by low_i within
597 // the array of digits.
598 //
599 // Notes:
600 // (1) we don't worry about masking the high order data we transfer since
601 // concat_get_data() is called from low order bit to high order bit. So
602 // the bits above where we place ours will be filled in by someone else.
603 //
604 // dst_p -> array of sc_unsigned digits to be filled in.
605 // low_i = first bit within dst_p to be set.
606 //-----------------------------------------------------------------------------
607 bool
608 sc_uint_base::concat_get_data(sc_digit *dst_p, int low_i) const
609 {
610  int dst_i; // Word in dst_p now processing.
611  int end_i; // Highest order word in dst_p to process.
612  int high_i; // Index of high order bit in dst_p to set.
613  int left_shift; // Left shift for val.
614  uint_type mask; // Mask for bits to extract or keep.
615  bool result; // True if inserting non-zero value.
616  uint_type val; // Value for this object.
617 
618  dst_i = low_i / BITS_PER_DIGIT;
619  left_shift = low_i % BITS_PER_DIGIT;
620  high_i = low_i + (m_len - 1);
621  end_i = high_i / BITS_PER_DIGIT;
622  val = m_val;
623  result = val != 0;
624 
625  // MASK OFF DATA TO BE TRANSFERRED BASE ON WIDTH:
626  if (m_len < 64) {
627  mask = ~(~UINT_ZERO << m_len);
628  val &= mask;
629  }
630 
631  // PROCESS THE FIRST WORD:
632  mask = ~(~UINT_ZERO << left_shift);
633  dst_p[dst_i] = (sc_digit)(((dst_p[dst_i] & mask)) |
634  ((val << left_shift) & DIGIT_MASK));
635 
636  switch (end_i - dst_i) {
637  // BITS ARE ACROSS TWO WORDS:
638  case 1:
639  dst_i++;
640  val >>= (BITS_PER_DIGIT - left_shift);
641  dst_p[dst_i] = (sc_digit)val;
642  break;
643 
644  // BITS ARE ACROSS THREE WORDS:
645  case 2:
646  dst_i++;
647  val >>= (BITS_PER_DIGIT - left_shift);
648  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
649  val >>= BITS_PER_DIGIT;
650  dst_p[dst_i] = (sc_digit)val;
651  break;
652 
653  // BITS ARE ACROSS FOUR WORDS:
654  case 3:
655  dst_i++;
656  val >>= (BITS_PER_DIGIT - left_shift);
657  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
658  val >>= BITS_PER_DIGIT;
659  dst_p[dst_i++] = (sc_digit)(val & DIGIT_MASK);
660  val >>= BITS_PER_DIGIT;
661  dst_p[dst_i] = (sc_digit)val;
662  break;
663  }
664  return result;
665 }
666 
667 // #### OPTIMIZE
668 void
670 {
671  *this = (low_i < 64) ? src >> low_i : src >> 63;
672 }
673 
674 void
675 sc_uint_base::concat_set(const sc_signed &src, int low_i)
676 {
677  if (low_i < src.length())
678  *this = src >> low_i;
679  else
680  *this = (src < 0) ? (int_type)-1 : 0;
681 }
682 
683 void
684 sc_uint_base::concat_set(const sc_unsigned &src, int low_i)
685 {
686  if (low_i < src.length())
687  *this = src >> low_i;
688  else
689  *this = 0;
690 }
691 
692 void
694 {
695  *this = (low_i < 64) ? src >> low_i : 0;
696 }
697 
698 
699 // other methods
700 void
701 sc_uint_base::scan(::std::istream &is)
702 {
703  std::string s;
704  is >> s;
705  *this = s.c_str();
706 }
707 
708 } // namespace sc_dt
bool to_bool() const
Definition: sc_logic.hh:240
int length() const
Definition: sc_signed.hh:1222
sc_uint_base(int w=sc_length_param().len())
bool and_reduce() const
void scan(::std::istream &is=::std::cin)
void check_length() const
virtual void concat_set(int64 src, int low_i)
sc_uint_base & operator=(uint_type v)
virtual bool concat_get_ctrl(sc_digit *dst_p, int low_i) const
bool or_reduce() const
bool xor_reduce() const
virtual bool concat_get_data(sc_digit *dst_p, int low_i) const
const std::string to_string(sc_numrep numrep=SC_DEC) const
int length() const
uint16_t len
Definition: helpers.cc:62
Bitfield< 31 > n
Definition: misc_types.hh:462
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 8 > a
Definition: misc_types.hh:66
Bitfield< 24, 22 > is
Bitfield< 1 > aa
Definition: types.hh:78
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 1 > s
Definition: pagetable.hh:64
Bitfield< 55 > l
Definition: pagetable.hh:54
Bitfield< 0 > v
Definition: pagetable.hh:65
Bitfield< 63 > val
Definition: misc.hh:776
BitfieldType< SegDescriptorLimit > limit
Definition: misc.hh:931
void sc_abort()
Definition: sc_report.cc:178
const char SC_ID_CONVERSION_FAILED_[]
Definition: messages.cc:37
const char SC_ID_OUT_OF_BOUNDS_[]
Definition: messages.cc:40
Definition: sc_bit.cc:68
void sc_uint_concref_invalid_length(int length)
Definition: sc_uint_base.cc:89
uint64_t uint64
Definition: sc_nbdefs.hh:172
@ SC_TRN
Definition: sc_fxdefs.hh:98
sc_numrep
Definition: sc_nbdefs.hh:82
const T sc_min(const T &a, const T &b)
Definition: functions.hh:59
int64_t int64
Definition: sc_nbdefs.hh:171
const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH]
Definition: sc_int_mask.cc:57
int64 int_type
Definition: sc_nbdefs.hh:206
uint64 uint_type
Definition: sc_nbdefs.hh:207
static const uint64 UINT_ZERO
Definition: sc_nbdefs.hh:209
@ SC_ON
Definition: sc_fxdefs.hh:146
unsigned int sc_digit
Definition: sc_nbdefs.hh:163
@ SC_WRAP
Definition: sc_fxdefs.hh:122
#define DIGIT_MASK
Definition: sc_nbdefs.hh:129
#define SC_INTWIDTH
Definition: sc_nbdefs.hh:208
#define BITS_PER_DIGIT
Definition: sc_nbdefs.hh:127
#define SC_REPORT_WARNING(msg_type, msg)
#define SC_REPORT_ERROR(msg_type, msg)

Generated on Wed Dec 21 2022 10:22:41 for gem5 by doxygen 1.9.1