SystemC  2.3.1
Accellera SystemC proof-of-concept library
sc_nbutils.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 /*****************************************************************************
19 
20  sc_nbutils.h -- External and friend functions for both sc_signed and
21  sc_unsigned classes.
22 
23  Original Author: Ali Dasdan, Synopsys, Inc.
24 
25  *****************************************************************************/
26 
27 /*****************************************************************************
28 
29  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
30  changes you are making here.
31 
32  Name, Affiliation, Date:
33  Description of Modification:
34 
35  *****************************************************************************/
36 
37 // $Log: sc_nbutils.h,v $
38 // Revision 1.6 2011/09/08 16:12:15 acg
39 // Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries.
40 //
41 // Revision 1.5 2011/08/26 23:00:01 acg
42 // Torsten Maehne: remove use of ieeefp.h.
43 //
44 // Revision 1.4 2011/08/15 16:43:24 acg
45 // Torsten Maehne: changes to remove unused argument warnings.
46 //
47 // Revision 1.3 2011/02/18 20:19:15 acg
48 // Andy Goodrich: updating Copyright notice.
49 //
50 // Revision 1.2 2010/09/06 16:35:48 acg
51 // Andy Goodrich: changed i386 to __i386__ in ifdef's.
52 //
53 // Revision 1.1.1.1 2006/12/15 20:20:05 acg
54 // SystemC 2.3
55 //
56 // Revision 1.3 2006/01/13 18:49:32 acg
57 // Added $Log command so that CVS check in comments are reproduced in the
58 // source.
59 //
60 
61 #ifndef SC_NBUTILS_H
62 #define SC_NBUTILS_H
63 
64 #include <cmath>
65 #include <limits>
66 
70 #include "sysc/utils/sc_report.h"
71 
72 
73 namespace sc_dt
74 {
75 
76 //-----------------------------------------------------------------------------
77 //"sc_io_base"
78 //
79 // This inline function returns the type of an i/o stream's base as a SystemC
80 // base designator.
81 // stream_object = reference to the i/o stream whose base is to be returned.
82 //
83 //"sc_io_show_base"
84 //
85 // This inline function returns true if the base should be shown when a SystemC
86 // value is displayed via the supplied stream operator.
87 // stream_object = reference to the i/o stream to return showbase value for.
88 //-----------------------------------------------------------------------------
89 #if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC)
90  inline sc_numrep
91  sc_io_base( systemc_ostream& os, sc_numrep def_base )
92  {
93  std::ios::fmtflags flags = os.flags() & std::ios::basefield;
94  if ( flags & ::std::ios::dec ) return SC_DEC;
95  if ( flags & ::std::ios::hex ) return SC_HEX;
96  if ( flags & ::std::ios::oct ) return SC_OCT;
97  return def_base;
98  }
99 
100  inline bool
102  {
103  return (os.flags() & ::std::ios::showbase) != 0 ;
104  }
105 #else // Other
106  inline sc_numrep
107  sc_io_base( systemc_ostream& /*unused*/, sc_numrep /*unused*/ )
108  {
109  return SC_DEC;
110  }
111  inline bool
113  {
114  return false;
115  }
116 #endif
117 
118 const std::string to_string( sc_numrep );
119 
120 inline
123 {
124  os << to_string( numrep );
125  return os;
126 }
127 
128 // only used within vec_from_str (non-standard, deprecated)
129 inline void
131 {
132  switch (base) {
133  case SC_NOBASE: case SC_BIN:
134  case SC_OCT: case SC_DEC:
135  case SC_HEX:
136  break;
137  case SC_BIN_US: case SC_BIN_SM:
138  case SC_OCT_US: case SC_OCT_SM:
139  case SC_HEX_US: case SC_HEX_SM:
140  case SC_CSD:
142  "is_valid_base( sc_numrep base ) : "
143  "bases SC_CSD, or ending in _US and _SM are not supported" );
144  break;
145  default:
146  char msg[BUFSIZ];
147  std::sprintf( msg, "is_valid_base( sc_numrep base ) : "
148  "base = %s is not valid",
149  to_string( base ).c_str() );
150  SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_, msg );
151  }
152 }
153 
154 // ----------------------------------------------------------------------------
155 
156 // One transition of the FSM to find base and sign of a number.
157 extern
158 small_type
159 fsm_move(char c, small_type &b, small_type &s, small_type &state);
160 
161 // Parse a character string into its equivalent binary bits.
162 extern
163 void parse_binary_bits(
164  const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
165 );
166 
167 
168 // Parse a character string into its equivalent hexadecimal bits.
169 extern
170 void parse_hex_bits(
171  const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
172 );
173 
174 
175 // Find the base and sign of a number in v.
176 extern
177 const char *
178 get_base_and_sign(const char *v, small_type &base, small_type &sign);
179 
180 // Create a number out of v in base.
181 extern
182 small_type
183 vec_from_str(int unb, int und, sc_digit *u,
184  const char *v, sc_numrep base = SC_NOBASE) ;
185 
186 
187 // ----------------------------------------------------------------------------
188 // Naming convention for the vec_ functions below:
189 // vec_OP(u, v, w) : computes w = u OP v.
190 // vec_OP_on(u, v) : computes u = u OP v if u has more digits than v.
191 // vec_OP_on2(u, v) : computes u = u OP v if u has fewer digits than v.
192 // _large : parameters are vectors.
193 // _small : one of the parameters is a single digit.
194 // Xlen : the number of digits in X.
195 // ----------------------------------------------------------------------------
196 
197 // ----------------------------------------------------------------------------
198 // Functions for vector addition: w = u + v or u += v.
199 // ----------------------------------------------------------------------------
200 
201 extern
202 void
203 vec_add(int ulen, const sc_digit *u,
204  int vlen, const sc_digit *v, sc_digit *w);
205 
206 extern
207 void
208 vec_add_on(int ulen, sc_digit *u,
209  int vlen, const sc_digit *v);
210 
211 extern
212 void
213 vec_add_on2(int ulen, sc_digit *u,
214  int vlen, const sc_digit *v);
215 
216 extern
217 void
218 vec_add_small(int ulen, const sc_digit *u,
219  sc_digit v, sc_digit *w);
220 
221 extern
222 void
223 vec_add_small_on(int ulen, sc_digit *u, sc_digit v);
224 
225 
226 // ----------------------------------------------------------------------------
227 // Functions for vector subtraction: w = u - v, u -= v, or u = v - u.
228 // ----------------------------------------------------------------------------
229 
230 extern
231 void
232 vec_sub(int ulen, const sc_digit *u,
233  int vlen, const sc_digit *v, sc_digit *w);
234 
235 extern
236 void
237 vec_sub_on(int ulen, sc_digit *u,
238  int vlen, const sc_digit *v);
239 
240 extern
241 void
242 vec_sub_on2(int ulen, sc_digit *u,
243  int vlen, const sc_digit *v);
244 
245 extern
246 void
247 vec_sub_small(int ulen, const sc_digit *u,
248  sc_digit v, sc_digit *w);
249 
250 extern
251 void
252 vec_sub_small_on(int ulen, sc_digit *u, sc_digit v);
253 
254 
255 // ----------------------------------------------------------------------------
256 // Functions for vector multiplication: w = u * v or u *= v.
257 // ----------------------------------------------------------------------------
258 
259 extern
260 void
261 vec_mul(int ulen, const sc_digit *u,
262  int vlen, const sc_digit *v, sc_digit *w);
263 
264 extern
265 void
266 vec_mul_small(int ulen, const sc_digit *u,
267  sc_digit v, sc_digit *w);
268 
269 extern
270 void
271 vec_mul_small_on(int ulen, sc_digit *u, sc_digit v);
272 
273 
274 // ----------------------------------------------------------------------------
275 // Functions for vector division: w = u / v.
276 // ----------------------------------------------------------------------------
277 
278 extern
279 void
280 vec_div_large(int ulen, const sc_digit *u,
281  int vlen, const sc_digit *v, sc_digit *w);
282 
283 extern
284 void
285 vec_div_small(int ulen, const sc_digit *u,
286  sc_digit v, sc_digit *w);
287 
288 
289 // ----------------------------------------------------------------------------
290 // Functions for vector remainder: w = u % v or u %= v.
291 // ----------------------------------------------------------------------------
292 
293 extern
294 void
295 vec_rem_large(int ulen, const sc_digit *u,
296  int vlen, const sc_digit *v, sc_digit *w);
297 
298 extern
299 sc_digit
300 vec_rem_small(int ulen, const sc_digit *u, sc_digit v);
301 
302 extern
303 sc_digit
304 vec_rem_on_small(int ulen, sc_digit *u, sc_digit v);
305 
306 
307 // ----------------------------------------------------------------------------
308 // Functions to convert between vectors of char and sc_digit.
309 // ----------------------------------------------------------------------------
310 
311 extern
312 int
313 vec_to_char(int ulen, const sc_digit *u,
314  int vlen, uchar *v);
315 
316 extern
317 void
318 vec_from_char(int ulen, const uchar *u,
319  int vlen, sc_digit *v);
320 
321 
322 // ----------------------------------------------------------------------------
323 // Functions to shift left or right, or to create a mirror image of vectors.
324 // ----------------------------------------------------------------------------
325 
326 extern
327 void
328 vec_shift_left(int ulen, sc_digit *u, int nsl);
329 
330 extern
331 void
332 vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill = 0);
333 
334 extern
335 void
336 vec_reverse(int unb, int und, sc_digit *ud,
337  int l, int r = 0);
338 
339 
340 // ----------------------------------------------------------------------------
341 // Various utility functions.
342 // ----------------------------------------------------------------------------
343 
344 // Return the low half part of d.
345 inline
346 sc_digit
348 {
349  return (d & HALF_DIGIT_MASK);
350 }
351 
352 // Return the high half part of d. The high part of the digit may have
353 // more bits than BITS_PER_HALF_DIGIT due to, e.g., overflow in the
354 // multiplication. Hence, in other functions that use high_half(),
355 // make sure that the result contains BITS_PER_HALF_DIGIT if
356 // necessary. This is done by high_half_masked().
357 inline
358 sc_digit
360 {
361  return (d >> BITS_PER_HALF_DIGIT);
362 }
363 
364 inline
365 sc_digit
367 {
368  return (high_half(d) & HALF_DIGIT_MASK);
369 }
370 
371 // Concatenate the high part h and low part l. Assumes that h and l
372 // are less than or equal to HALF_DIGIT_MASK;
373 inline
374 sc_digit
376 {
377  return ((h << BITS_PER_HALF_DIGIT) | l);
378 }
379 
380 // Create a number with n 1's.
381 inline
382 sc_digit
384 {
385  return (((sc_digit) 1 << n) - 1);
386 }
387 
388 // Create a number with one 1 and n 0's.
389 inline
390 sc_digit
392 {
393  return ((sc_digit) 1 << n);
394 }
395 
396 
397 // ----------------------------------------------------------------------------
398 
399 // Find the digit that bit i is in.
400 inline
401 int
402 digit_ord(int i)
403 {
404  return (i / BITS_PER_DIGIT);
405 }
406 
407 // Find the bit in digit_ord(i) that bit i corressponds to.
408 inline
409 int
410 bit_ord(int i)
411 {
412  return (i % BITS_PER_DIGIT);
413 }
414 
415 
416 // ----------------------------------------------------------------------------
417 // Functions to compare, zero, complement vector(s).
418 // ----------------------------------------------------------------------------
419 
420 // Compare u and v and return r
421 // r = 0 if u == v
422 // r < 0 if u < v
423 // r > 0 if u > v
424 // - Assume that all the leading zero digits are already skipped.
425 // - ulen and/or vlen can be zero.
426 // - Every digit is less than or equal to DIGIT_MASK;
427 inline
428 int
429 vec_cmp(int ulen, const sc_digit *u,
430  int vlen, const sc_digit *v)
431 {
432 
433 #ifdef DEBUG_SYSTEMC
434  // assert((ulen <= 0) || (u != NULL));
435  // assert((vlen <= 0) || (v != NULL));
436 
437  // ulen and vlen can be equal to 0 because vec_cmp can be called
438  // after vec_skip_leading_zeros.
439  assert((ulen >= 0) && (u != NULL));
440  assert((vlen >= 0) && (v != NULL));
441  // If ulen > 0, then the leading digit of u must be non-zero.
442  assert((ulen <= 0) || (u[ulen - 1] != 0));
443  assert((vlen <= 0) || (v[vlen - 1] != 0));
444 #endif
445 
446  if (ulen != vlen)
447  return (ulen - vlen);
448 
449  // ulen == vlen >= 1
450  while ((--ulen >= 0) && (u[ulen] == v[ulen]))
451  ;
452 
453  if (ulen < 0)
454  return 0;
455 
456 #ifdef DEBUG_SYSTEMC
457  // Test to see if the result is wrong due to the presence of
458  // overflow bits.
459  assert((u[ulen] & DIGIT_MASK) != (v[ulen] & DIGIT_MASK));
460 #endif
461 
462  return (int) (u[ulen] - v[ulen]);
463 
464 }
465 
466 // Find the index of the first non-zero digit.
467 // - ulen (before) = the number of digits in u.
468 // - the returned value = the index of the first non-zero digit.
469 // A negative value of -1 indicates that every digit in u is zero.
470 inline
471 int
472 vec_find_first_nonzero(int ulen, const sc_digit *u)
473 {
474 
475 #ifdef DEBUG_SYSTEMC
476  // assert((ulen <= 0) || (u != NULL));
477  assert((ulen > 0) && (u != NULL));
478 #endif
479 
480  while ((--ulen >= 0) && (! u[ulen]))
481  ;
482 
483  return ulen;
484 
485 }
486 
487 // Skip all the leading zero digits.
488 // - ulen (before) = the number of digits in u.
489 // - the returned value = the number of non-zero digits in u.
490 // - the returned value is non-negative.
491 inline
492 int
493 vec_skip_leading_zeros(int ulen, const sc_digit *u)
494 {
495 
496 #ifdef DEBUG_SYSTEMC
497  // assert((ulen <= 0) || (u != NULL));
498  assert((ulen > 0) && (u != NULL));
499 #endif
500 
501  return (1 + vec_find_first_nonzero(ulen, u));
502 
503 }
504 
505 // Compare u and v and return r
506 // r = 0 if u == v
507 // r < 0 if u < v
508 // r > 0 if u > v
509 inline
510 int
511 vec_skip_and_cmp(int ulen, const sc_digit *u,
512  int vlen, const sc_digit *v)
513 {
514 
515 #ifdef DEBUG_SYSTEMC
516  assert((ulen > 0) && (u != NULL));
517  assert((vlen > 0) && (v != NULL));
518 #endif
519 
520  ulen = vec_skip_leading_zeros(ulen, u);
521  vlen = vec_skip_leading_zeros(vlen, v);
522  // ulen and/or vlen can be equal to zero here.
523  return vec_cmp(ulen, u, vlen, v);
524 
525 }
526 
527 // Set u[i] = 0 where i = from ... (ulen - 1).
528 inline
529 void
530 vec_zero(int from, int ulen, sc_digit *u)
531 {
532 
533 #ifdef DEBUG_SYSTEMC
534  assert((ulen > 0) && (u != NULL));
535 #endif
536 
537  for(int i = from; i < ulen; i++)
538  u[i] = 0;
539 
540 }
541 
542 // Set u[i] = 0 where i = 0 .. (ulen - 1).
543 inline
544 void
545 vec_zero(int ulen, sc_digit *u)
546 {
547  vec_zero(0, ulen, u);
548 }
549 
550 // Copy n digits from v to u.
551 inline
552 void
553 vec_copy(int n, sc_digit *u, const sc_digit *v)
554 {
555 
556 #ifdef DEBUG_SYSTEMC
557  assert((n > 0) && (u != NULL) && (v != NULL));
558 #endif
559 
560  for (int i = 0; i < n; ++i)
561  u[i] = v[i];
562 }
563 
564 // Copy v to u, where ulen >= vlen, and zero the rest of the digits in u.
565 inline
566 void
568  int vlen, const sc_digit *v)
569 {
570 
571 #ifdef DEBUG_SYSTEMC
572  assert((ulen > 0) && (u != NULL));
573  assert((vlen > 0) && (v != NULL));
574  assert(ulen >= vlen);
575 #endif
576 
577  vec_copy(vlen, u, v);
578  vec_zero(vlen, ulen, u);
579 
580 }
581 
582 // 2's-complement the digits in u.
583 inline
584 void
586 {
587 
588 #ifdef DEBUG_SYSTEMC
589  assert((ulen > 0) && (u != NULL));
590 #endif
591 
592  sc_digit carry = 1;
593 
594  for (int i = 0; i < ulen; ++i) {
595  carry += (~u[i] & DIGIT_MASK);
596  u[i] = carry & DIGIT_MASK;
597  carry >>= BITS_PER_DIGIT;
598  }
599 
600 }
601 
602 
603 // ----------------------------------------------------------------------------
604 // Functions to handle built-in types or signs.
605 // ----------------------------------------------------------------------------
606 
607 // u = v
608 // - v is an unsigned long or uint64, and positive integer.
609 template< class Type >
610 inline
611 void
612 from_uint(int ulen, sc_digit *u, Type v)
613 {
614 
615 #ifdef DEBUG_SYSTEMC
616  // assert((ulen <= 0) || (u != NULL));
617  assert((ulen > 0) && (u != NULL));
618  assert(v >= 0);
619 #endif
620 
621  int i = 0;
622 
623  while (v && (i < ulen)) {
624 #ifndef _WIN32
625  u[i++] = static_cast<sc_digit>( v & DIGIT_MASK );
626 #else
627  u[i++] = ((sc_digit) v) & DIGIT_MASK;
628 #endif
629  v >>= BITS_PER_DIGIT;
630  }
631 
632  vec_zero(i, ulen, u);
633 
634 }
635 
636 
637 // Get u's sign and return its absolute value.
638 // u can be long, unsigned long, int64, or uint64.
639 template< class Type >
640 inline
642 get_sign(Type &u)
643 {
644  if (u > 0)
645  return SC_POS;
646 
647  if (u == 0)
648  return SC_ZERO;
649 
650  // no positive number representable for minimum value,
651  // leave as is to avoid Undefined Behaviour
652  if( SC_LIKELY_( u > (std::numeric_limits<Type>::min)() ) )
653  u = -u;
654 
655  return SC_NEG;
656 }
657 
658 
659 // Return us * vs:
660 // - Return SC_ZERO if either sign is SC_ZERO.
661 // - Return SC_POS if us == vs
662 // - Return SC_NEG if us != vs.
663 inline
666 {
667  if ((us == SC_ZERO) || (vs == SC_ZERO))
668  return SC_ZERO;
669 
670  if (us == vs)
671  return SC_POS;
672 
673  return SC_NEG;
674 }
675 
676 
677 // ----------------------------------------------------------------------------
678 // Functions to test for errors and print out error messages.
679 // ----------------------------------------------------------------------------
680 
681 #ifdef SC_MAX_NBITS
682 
683 inline
684 void
685 test_bound(int nb)
686 {
687  if (nb > SC_MAX_NBITS) {
688  char msg[BUFSIZ];
689  std::sprintf( msg, "test_bound( int nb ) : "
690  "nb = %d > SC_MAX_NBITS = %d is not valid",
691  nb, SC_MAX_NBITS );
693  }
694 }
695 
696 #endif
697 
698 template< class Type >
699 inline
700 void
701 div_by_zero(Type s)
702 {
703  if (s == 0) {
704  SC_REPORT_ERROR( sc_core::SC_ID_OPERATION_FAILED_,
705  "div_by_zero<Type>( Type ) : division by zero" );
706  }
707 }
708 
709 
710 // ----------------------------------------------------------------------------
711 // Functions to check if a given vector is zero or make one.
712 // ----------------------------------------------------------------------------
713 
714 // If u[i] is zero for every i = 0,..., ulen - 1, return SC_ZERO,
715 // else return s.
716 inline
717 small_type
718 check_for_zero(small_type s, int ulen, const sc_digit *u)
719 {
720 
721 #ifdef DEBUG_SYSTEMC
722  // assert(ulen >= 0);
723  assert((ulen > 0) && (u != NULL));
724 #endif
725 
726  if (vec_find_first_nonzero(ulen, u) < 0)
727  return SC_ZERO;
728 
729  return s;
730 
731 }
732 
733 // If u[i] is zero for every i = 0,..., ulen - 1, return true,
734 // else return false.
735 inline
736 bool
737 check_for_zero(int ulen, const sc_digit *u)
738 {
739 
740 #ifdef DEBUG_SYSTEMC
741  // assert(ulen >= 0);
742  assert((ulen > 0) && (u != NULL));
743 #endif
744 
745  if (vec_find_first_nonzero(ulen, u) < 0)
746  return true;
747 
748  return false;
749 
750 }
751 
752 inline
754 make_zero(int nd, sc_digit *d)
755 {
756  vec_zero(nd, d);
757  return SC_ZERO;
758 }
759 
760 
761 // ----------------------------------------------------------------------------
762 // Functions for both signed and unsigned numbers to convert sign-magnitude
763 // (SM) and 2's complement (2C) representations.
764 // added = 1 => for signed.
765 // added = 0 => for unsigned.
766 // IF_SC_SIGNED can be used as 'added'.
767 // ----------------------------------------------------------------------------
768 
769 // Trim the extra leading bits of a signed or unsigned number.
770 inline
771 void
772 trim(small_type added, int nb, int nd, sc_digit *d)
773 {
774 #ifdef DEBUG_SYSTEMC
775  assert((nb > 0) && (nd > 0) && (d != NULL));
776 #endif
777 
778  d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + added);
779 }
780 
781 // Convert an (un)signed number from sign-magnitude representation to
782 // 2's complement representation and trim the extra bits.
783 inline
784 void
786  small_type s, int nb, int nd, sc_digit *d)
787 {
788  if (s == SC_NEG) {
789  vec_complement(nd, d);
790  trim(added, nb, nd, d);
791  }
792 }
793 
794 // Convert an (un)signed number from sign-magnitude representation to
795 // 2's complement representation but do not trim the extra bits.
796 inline
797 void
799 {
800  if (s == SC_NEG)
801  vec_complement(nd, d);
802 }
803 
804 
805 // ----------------------------------------------------------------------------
806 // Functions to convert between sign-magnitude (SM) and 2's complement
807 // (2C) representations of signed numbers.
808 // ----------------------------------------------------------------------------
809 
810 // Trim the extra leading bits off a signed number.
811 inline
812 void
813 trim_signed(int nb, int nd, sc_digit *d)
814 {
815 #ifdef DEBUG_SYSTEMC
816  assert((nb > 0) && (nd > 0) && (d != NULL));
817 #endif
818 
819  d[nd - 1] &= one_and_ones(bit_ord(nb - 1) + 1);
820 }
821 
822 // Convert a signed number from 2's complement representation to
823 // sign-magnitude representation, and return its sign. nd is d's
824 // actual size, without zeros eliminated.
825 inline
828 {
829 
830 #ifdef DEBUG_SYSTEMC
831  assert((nb > 0) && (nd > 0) && (d != NULL));
832 #endif
833 
834  small_type s;
835 
836  int xnb = bit_ord(nb - 1) + 1;
837 
838  // Test the sign bit.
839  if (d[nd - 1] & one_and_zeros(xnb - 1)) {
840  s = SC_NEG;
841  vec_complement(nd, d);
842  }
843  else
844  s = SC_POS;
845 
846  // Trim the last digit.
847  d[nd - 1] &= one_and_ones(xnb);
848 
849  // Check if the new number is zero.
850  if (s == SC_POS)
851  return check_for_zero(s, nd, d);
852 
853  return s;
854 
855 }
856 
857 // Convert a signed number from sign-magnitude representation to 2's
858 // complement representation, get its sign, convert back to
859 // sign-magnitude representation, and return its sign. nd is d's
860 // actual size, without zeros eliminated.
861 inline
862 small_type
864 {
865  convert_SM_to_2C(s, nd, d);
866  return convert_signed_2C_to_SM(nb, nd, d);
867 }
868 
869 // Convert a signed number from sign-magnitude representation to 2's
870 // complement representation and trim the extra bits.
871 inline
872 void
874 {
875  convert_SM_to_2C_trimmed(1, s, nb, nd, d);
876 }
877 
878 // Convert a signed number from sign-magnitude representation to 2's
879 // complement representation but do not trim the extra bits.
880 inline
881 void
883 {
884  convert_SM_to_2C(s, nd, d);
885 }
886 
887 
888 // ----------------------------------------------------------------------------
889 // Functions to convert between sign-magnitude (SM) and 2's complement
890 // (2C) representations of unsigned numbers.
891 // ----------------------------------------------------------------------------
892 
893 // Trim the extra leading bits off an unsigned number.
894 inline
895 void
896 trim_unsigned(int nb, int nd, sc_digit *d)
897 {
898 #ifdef DEBUG_SYSTEMC
899  assert((nb > 0) && (nd > 0) && (d != NULL));
900 #endif
901 
902  d[nd - 1] &= one_and_ones(bit_ord(nb - 1));
903 }
904 
905 // Convert an unsigned number from 2's complement representation to
906 // sign-magnitude representation, and return its sign. nd is d's
907 // actual size, without zeros eliminated.
908 inline
911 {
912  trim_unsigned(nb, nd, d);
913  return check_for_zero(SC_POS, nd, d);
914 }
915 
916 // Convert an unsigned number from sign-magnitude representation to
917 // 2's complement representation, get its sign, convert back to
918 // sign-magnitude representation, and return its sign. nd is d's
919 // actual size, without zeros eliminated.
920 inline
923 {
924  convert_SM_to_2C(s, nd, d);
925  return convert_unsigned_2C_to_SM(nb, nd, d);
926 }
927 
928 // Convert an unsigned number from sign-magnitude representation to
929 // 2's complement representation and trim the extra bits.
930 inline
931 void
933 {
934  convert_SM_to_2C_trimmed(0, s, nb, nd, d);
935 }
936 
937 // Convert an unsigned number from sign-magnitude representation to
938 // 2's complement representation but do not trim the extra bits.
939 inline
940 void
942 {
943  convert_SM_to_2C(s, nd, d);
944 }
945 
946 
947 // ----------------------------------------------------------------------------
948 // Functions to copy one (un)signed number to another.
949 // ----------------------------------------------------------------------------
950 
951 // Copy v to u.
952 inline
953 void
955  int unb, int und, sc_digit *ud,
956  int vnb, int vnd, const sc_digit *vd)
957 {
958 
959  if (und <= vnd) {
960 
961  vec_copy(und, ud, vd);
962 
963  if (unb <= vnb)
964  us = convert_signed_SM_to_2C_to_SM(us, unb, und, ud);
965 
966  }
967  else // und > vnd
968  vec_copy_and_zero(und, ud, vnd, vd);
969 
970 }
971 
972 // Copy v to u.
973 inline
974 void
976  int unb, int und, sc_digit *ud,
977  int /* vnb */, int vnd, const sc_digit *vd)
978 {
979 
980  if (und <= vnd)
981  vec_copy(und, ud, vd);
982 
983  else // und > vnd
984  vec_copy_and_zero(und, ud, vnd, vd);
985 
986  us = convert_unsigned_SM_to_2C_to_SM(us, unb, und, ud);
987 
988 }
989 
990 
991 // ----------------------------------------------------------------------------
992 // Faster set(i, v), without bound checking.
993 // ----------------------------------------------------------------------------
994 
995 // A version of set(i, v) without bound checking.
996 inline
997 void
998 safe_set(int i, bool v, sc_digit *d)
999 {
1000 
1001 #ifdef DEBUG_SYSTEMC
1002  assert((i >= 0) && (d != NULL));
1003 #endif
1004 
1005  int bit_num = bit_ord(i);
1006  int digit_num = digit_ord(i);
1007 
1008  if (v)
1009  d[digit_num] |= one_and_zeros(bit_num);
1010  else
1011  d[digit_num] &= ~(one_and_zeros(bit_num));
1012 
1013 }
1014 
1015 
1016 // ----------------------------------------------------------------------------
1017 // Function to check if a double number is bad (NaN or infinite).
1018 // ----------------------------------------------------------------------------
1019 
1020 inline
1021 bool
1022 is_nan( double v )
1023 {
1024  return std::numeric_limits<double>::has_quiet_NaN && (v != v);
1025 }
1026 
1027 inline
1028 bool
1029 is_inf( double v )
1030 {
1031  return v == std::numeric_limits<double>::infinity()
1032  || v == -std::numeric_limits<double>::infinity();
1033 }
1034 
1035 inline
1036 void
1037 is_bad_double(double v)
1038 {
1039 // Windows throws exception.
1040  if( is_nan(v) || is_inf(v) )
1041  SC_REPORT_ERROR( sc_core::SC_ID_VALUE_NOT_VALID_,
1042  "is_bad_double( double v ) : "
1043  "v is not finite - NaN or Inf" );
1044 }
1045 
1046 } // namespace sc_dt
1047 
1048 
1049 #endif
#define DIGIT_MASK
Definition: sc_nbdefs.h:139
unsigned char uchar
Definition: sc_nbdefs.h:114
bool is_nan(double v)
Definition: sc_nbutils.h:1022
void convert_signed_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.h:882
#define SC_POS
Definition: sc_nbdefs.h:111
sc_digit one_and_zeros(int n)
Definition: sc_nbutils.h:391
bool sc_io_show_base(systemc_ostream &)
Definition: sc_nbutils.h:112
void convert_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.h:798
small_type check_for_zero(small_type s, int ulen, const sc_digit *u)
Definition: sc_nbutils.h:718
::std::ostream systemc_ostream
Definition: sc_iostream.h:47
sc_digit one_and_ones(int n)
Definition: sc_nbutils.h:383
sc_numrep sc_io_base(systemc_ostream &, sc_numrep)
Definition: sc_nbutils.h:107
void convert_SM_to_2C_trimmed(small_type added, small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:785
sc_numrep
Definition: sc_nbdefs.h:91
void trim_signed(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:813
unsigned int sc_digit
Definition: sc_nbdefs.h:173
void vec_add(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
void trim(small_type added, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:772
const char SC_ID_NOT_IMPLEMENTED_[]
sc_digit high_half_masked(sc_digit d)
Definition: sc_nbutils.h:366
sc_digit vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
int vec_skip_leading_zeros(int ulen, const sc_digit *u)
Definition: sc_nbutils.h:493
void vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
sc_concref_r< sc_bitref_r< T1 >, sc_bitref_r< T2 > > concat(sc_bitref_r< T1 >, sc_bitref_r< T2 >)
#define BITS_PER_DIGIT
Definition: sc_nbdefs.h:137
void vec_sub_on(int ulen, sc_digit *u, int vlen, const sc_digit *v)
void vec_mul(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
void vec_rem_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
uint64 const sc_uint_base int b
Definition: sc_fxval.h:1003
#define BITS_PER_HALF_DIGIT
Definition: sc_nbdefs.h:145
void vec_copy(int n, sc_digit *u, const sc_digit *v)
Definition: sc_nbutils.h:553
void safe_set(int i, bool v, sc_digit *d)
Definition: sc_nbutils.h:998
void copy_digits_unsigned(small_type &us, int unb, int und, sc_digit *ud, int, int vnd, const sc_digit *vd)
Definition: sc_nbutils.h:975
small_type get_sign(Type &u)
Definition: sc_nbutils.h:642
void vec_add_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
void parse_hex_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0)
sc_digit vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
int vec_find_first_nonzero(int ulen, const sc_digit *u)
Definition: sc_nbutils.h:472
void vec_sub_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
void vec_div_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
int digit_ord(int i)
Definition: sc_nbutils.h:402
void vec_sub(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
void vec_div_large(int ulen, const sc_digit *u, int vlen, const sc_digit *v, sc_digit *w)
void vec_copy_and_zero(int ulen, sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.h:567
const std::string to_string(sc_enc)
void vec_sub_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v)
int small_type
Definition: sc_nbdefs.h:118
void convert_unsigned_SM_to_2C(small_type s, int nd, sc_digit *d)
Definition: sc_nbutils.h:941
#define SC_LIKELY_(x)
Definition: sc_cmnhdr.h:84
void vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
small_type vec_from_str(int unb, int und, sc_digit *u, const char *v, sc_numrep base=SC_NOBASE)
::std::ios::fmtflags fmtflags
Definition: sc_nbdefs.h:222
void vec_add_on2(int ulen, sc_digit *u, int vlen, const sc_digit *v)
small_type convert_unsigned_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:922
sc_digit low_half(sc_digit d)
Definition: sc_nbutils.h:347
small_type mul_signs(small_type us, small_type vs)
Definition: sc_nbutils.h:665
const char * get_base_and_sign(const char *v, small_type &base, small_type &sign)
void copy_digits_signed(small_type &us, int unb, int und, sc_digit *ud, int vnb, int vnd, const sc_digit *vd)
Definition: sc_nbutils.h:954
void vec_reverse(int unb, int und, sc_digit *ud, int l, int r=0)
small_type convert_signed_SM_to_2C_to_SM(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:863
const char SC_ID_OUT_OF_BOUNDS_[]
int vec_to_char(int ulen, const sc_digit *u, int vlen, uchar *v)
small_type make_zero(int nd, sc_digit *d)
Definition: sc_nbutils.h:754
int vec_skip_and_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.h:511
#define SC_NEG
Definition: sc_nbdefs.h:109
void vec_mul_small(int ulen, const sc_digit *u, sc_digit v, sc_digit *w)
bool is_inf(double v)
Definition: sc_nbutils.h:1029
void vec_complement(int ulen, sc_digit *u)
Definition: sc_nbutils.h:585
small_type convert_unsigned_2C_to_SM(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:910
void vec_shift_left(int ulen, sc_digit *u, int nsl)
void parse_binary_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0)
int bit_ord(int i)
Definition: sc_nbutils.h:410
void is_bad_double(double v)
Definition: sc_nbutils.h:1037
void vec_add_on(int ulen, sc_digit *u, int vlen, const sc_digit *v)
void div_by_zero(Type s)
Definition: sc_nbutils.h:701
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:213
void from_uint(int ulen, sc_digit *u, Type v)
Definition: sc_nbutils.h:612
int vec_cmp(int ulen, const sc_digit *u, int vlen, const sc_digit *v)
Definition: sc_nbutils.h:429
void convert_signed_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:873
small_type convert_signed_2C_to_SM(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:827
sc_digit high_half(sc_digit d)
Definition: sc_nbutils.h:359
void vec_zero(int from, int ulen, sc_digit *u)
Definition: sc_nbutils.h:530
small_type fsm_move(char c, small_type &b, small_type &s, small_type &state)
void vec_from_char(int ulen, const uchar *u, int vlen, sc_digit *v)
void vec_shift_right(int vlen, sc_digit *u, int nsr, sc_digit fill=0)
void vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
#define SC_ZERO
Definition: sc_nbdefs.h:110
void convert_unsigned_SM_to_2C_trimmed(small_type s, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:932
inline::std::ostream & operator<<(::std::ostream &os, const sc_bit &a)
Definition: sc_bit.h:386
#define HALF_DIGIT_MASK
Definition: sc_nbdefs.h:147
void trim_unsigned(int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:896
void is_valid_base(sc_numrep base)
Definition: sc_nbutils.h:130