gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
75namespace sc_core
76{
77
78template class sc_vpool<sc_dt::sc_uint_bitref>;
79template class sc_vpool<sc_dt::sc_uint_subref>;
80
81} // namespace sc_core
82
83namespace sc_dt
84{
85
86// to avoid code bloat in sc_uint_concat<T1,T2>
87
88void
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
106sc_core::sc_vpool<sc_uint_bitref> sc_uint_bitref::m_pool(9);
107
108// concatenation methods:
109
110// #### OPTIMIZE
111void
112sc_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
118void
119sc_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
128void
129sc_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
138void
139sc_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
147void
148sc_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
162bool
163sc_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
184bool
185sc_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
245sc_core::sc_vpool<sc_uint_subref> sc_uint_subref::m_pool(9);
246
247// assignment operators
248
250sc_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
262sc_uint_subref::operator = (const sc_signed &a)
263{
264 sc_uint_base aa(length());
265 return (*this = aa = a);
266}
267
269sc_uint_subref::operator = (const sc_unsigned &a)
270{
271 sc_uint_base aa(length());
272 return (*this = aa = a);
273}
274
276sc_uint_subref::operator = (const sc_bv_base &a)
277{
278 sc_uint_base aa(length());
279 return (*this = aa = a);
280}
281
283sc_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
292void
293sc_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
299void
300sc_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
309void
310sc_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
319void
320sc_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
327void
328sc_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
344void
345sc_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
354void
355sc_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
364void
365sc_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
376void
377sc_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
389sc_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
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
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
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
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
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
525const 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
533const std::string
534sc_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
543bool
545{
546 return (m_val == (~UINT_ZERO >> m_ulen));
547}
548
549bool
551{
552 return (m_val != uint_type(0));
553}
554
555bool
557{
558 uint_type mask = ~UINT_ZERO;
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
570bool
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//-----------------------------------------------------------------------------
607bool
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
668void
670{
671 *this = (low_i < 64) ? src >> low_i : src >> 63;
672}
673
674void
676{
677 if (low_i < src.length())
678 *this = src >> low_i;
679 else
680 *this = (src < 0) ? (int_type)-1 : 0;
681}
682
683void
685{
686 if (low_i < src.length())
687 *this = src >> low_i;
688 else
689 *this = 0;
690}
691
692void
694{
695 *this = (low_i < 64) ? src >> low_i : 0;
696}
697
698
699// other methods
700void
701sc_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
sc_uint_base(int w=sc_length_param().len())
sc_uint_base & operator=(uint_type v)
bool and_reduce() const
void scan(::std::istream &is=::std::cin)
void check_length() const
virtual void concat_set(int64 src, int low_i)
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
SwitchingFiber b
SwitchingFiber a
uint16_t len
Definition helpers.cc:83
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
void sc_uint_concref_invalid_length(int length)
uint64_t uint64
Definition sc_nbdefs.hh:172
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]
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
unsigned int sc_digit
Definition sc_nbdefs.hh:163
#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 Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0