| /***************************************************************************** |
| |
| Licensed to Accellera Systems Initiative Inc. (Accellera) under one or |
| more contributor license agreements. See the NOTICE file distributed |
| with this work for additional information regarding copyright ownership. |
| Accellera licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with the |
| License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| implied. See the License for the specific language governing |
| permissions and limitations under the License. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| scfx_utils.h - |
| |
| Original Author: Martin Janssen, Synopsys, Inc. |
| |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| |
| MODIFICATION LOG - modifiers, enter your name, affiliation, date and |
| changes you are making here. |
| |
| Name, Affiliation, Date: |
| Description of Modification: |
| |
| *****************************************************************************/ |
| |
| // $Log: scfx_utils.h,v $ |
| // Revision 1.2 2009/02/28 00:26:20 acg |
| // Andy Goodrich: bug fixes. |
| // |
| // Revision 1.1.1.1 2006/12/15 20:31:36 acg |
| // SystemC 2.2 |
| // |
| // Revision 1.3 2006/01/13 18:53:58 acg |
| // Andy Goodrich: added $Log command so that CVS comments are reproduced in |
| // the source. |
| // |
| |
| #ifndef __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ |
| #define __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ |
| |
| #include "sc_fxdefs.hh" |
| #include "scfx_params.hh" |
| #include "scfx_string.hh" |
| |
| namespace sc_dt |
| { |
| |
| // ---------------------------------------------------------------------------- |
| // Find the most and least significant non-zero bits in a unsigned long |
| // ---------------------------------------------------------------------------- |
| |
| #define MSB_STATEMENT(n) if (x >> n) { x >>= n; i += n; } |
| |
| inline int |
| scfx_find_msb(unsigned long x) |
| { |
| int i = 0; |
| # if SC_LONG_64 |
| MSB_STATEMENT(32); |
| # endif // SC_LONG_64 |
| MSB_STATEMENT(16); |
| MSB_STATEMENT(8); |
| MSB_STATEMENT(4); |
| MSB_STATEMENT(2); |
| MSB_STATEMENT(1); |
| return i; |
| } |
| |
| #undef MSB_STATEMENT |
| |
| #define LSB_STATEMENT(n) if (x << n) { x <<= n; i -= n; } |
| |
| inline int |
| scfx_find_lsb(unsigned long x) |
| { |
| int i; |
| # if SC_LONG_64 |
| i = 63; |
| LSB_STATEMENT(32); |
| # else |
| i = 31; |
| # endif // SC_LONG_64 |
| LSB_STATEMENT(16); |
| LSB_STATEMENT(8); |
| LSB_STATEMENT(4); |
| LSB_STATEMENT(2); |
| LSB_STATEMENT(1); |
| return i; |
| } |
| |
| #undef LSB_STATEMENT |
| |
| |
| // ---------------------------------------------------------------------------- |
| // Utilities for parsing a character string number |
| // ---------------------------------------------------------------------------- |
| |
| inline int |
| scfx_parse_sign(const char *&s, bool &sign_char) |
| { |
| int sign = 1; |
| |
| if (*s == '+') { |
| ++s; |
| sign_char = true; |
| } else if (*s == '-' ) { |
| sign = -1; |
| ++s; |
| sign_char = true; |
| } else { |
| sign_char = false; |
| } |
| |
| return sign; |
| } |
| |
| inline sc_numrep |
| scfx_parse_prefix(const char *&s) |
| { |
| if (s[0] == '0') { |
| switch (s[1]) { |
| case 'b': |
| case 'B': |
| { |
| if ((s[2] == 'u' || s[2] == 'U') && |
| (s[3] == 's' || s[3] == 'S')) { |
| s += 4; |
| return SC_BIN_US; |
| } |
| if ((s[2] == 's' || s[2] == 'S') && |
| (s[3] == 'm' || s[3] == 'M')) { |
| s += 4; |
| return SC_BIN_SM; |
| } |
| s += 2; |
| return SC_BIN; |
| } |
| case 'o': |
| case 'O': |
| { |
| if ((s[2] == 'u' || s[2] == 'U') && |
| (s[3] == 's' || s[3] == 'S')) { |
| s += 4; |
| return SC_OCT_US; |
| } |
| if ((s[2] == 's' || s[2] == 'S') && |
| (s[3] == 'm' || s[3] == 'M')) { |
| s += 4; |
| return SC_OCT_SM; |
| } |
| s += 2; |
| return SC_OCT; |
| } |
| case 'x': |
| case 'X': |
| { |
| if ((s[2] == 'u' || s[2] == 'U') && |
| (s[3] == 's' || s[3] == 'S')) { |
| s += 4; |
| return SC_HEX_US; |
| } |
| if ((s[2] == 's' || s[2] == 'S') && |
| (s[3] == 'm' || s[3] == 'M')) { |
| s += 4; |
| return SC_HEX_SM; |
| } |
| s += 2; |
| return SC_HEX; |
| } |
| case 'd': |
| case 'D': |
| { |
| s += 2; |
| return SC_DEC; |
| } |
| case 'c': |
| case 'C': |
| { |
| if ((s[2] == 's' || s[2] == 'S') && |
| (s[3] == 'd' || s[3] == 'D')) { |
| s += 4; |
| return SC_CSD; |
| } |
| break; |
| } |
| default: |
| break; |
| } |
| } |
| |
| return SC_DEC; |
| } |
| |
| inline int |
| scfx_parse_base(const char *&s) |
| { |
| const char *s1 = s + 1; |
| |
| int base = 10; |
| |
| if (*s == '0') { |
| switch (*s1) { |
| case 'b': |
| case 'B': base = 2; s += 2; break; |
| case 'o': |
| case 'O': base = 8; s += 2; break; |
| case 'd': |
| case 'D': base = 10; s += 2; break; |
| case 'x': |
| case 'X': base = 16; s += 2; break; |
| } |
| } |
| |
| return base; |
| } |
| |
| inline bool |
| scfx_is_equal(const char *a, const char *b) |
| { |
| while (*a != 0 && *b != 0 && *a == *b) { |
| ++ a; |
| ++ b; |
| } |
| return (*a == 0 && *b == 0); |
| } |
| |
| inline bool |
| scfx_is_nan(const char *s) |
| { |
| return scfx_is_equal(s, "NaN"); |
| } |
| |
| inline bool |
| scfx_is_inf(const char *s) |
| { |
| return (scfx_is_equal(s, "Inf") || scfx_is_equal(s, "Infinity")); |
| } |
| |
| inline bool |
| scfx_exp_start(const char *s) |
| { |
| if (*s == 'e' || *s == 'E') { |
| ++s; |
| if (*s == '+' || *s == '-') |
| return true; |
| } |
| return false; |
| } |
| |
| inline bool |
| scfx_is_digit(char c, sc_numrep numrep) |
| { |
| bool is_digit; |
| |
| switch(numrep) { |
| case SC_DEC: |
| { |
| switch(c) { |
| case '0': case '1': case '2': case '3': case '4': |
| case '5': case '6': case '7': case '8': case '9': |
| { |
| is_digit = true; |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| break; |
| } |
| case SC_BIN: |
| case SC_BIN_US: |
| case SC_BIN_SM: |
| { |
| switch(c) { |
| case '0': case '1': |
| { |
| is_digit = true; |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| break; |
| } |
| case SC_OCT: |
| case SC_OCT_US: |
| case SC_OCT_SM: |
| { |
| switch(c) { |
| case '0': case '1': case '2': case '3': |
| case '4': case '5': case '6': case '7': |
| { |
| is_digit = true; |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| break; |
| } |
| case SC_HEX: |
| case SC_HEX_US: |
| case SC_HEX_SM: |
| { |
| switch (c) { |
| case '0': case '1': case '2': case '3': case '4': |
| case '5': case '6': case '7': case '8': case '9': |
| case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': |
| case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
| { |
| is_digit = true; |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| break; |
| } |
| case SC_CSD: |
| { |
| switch (c) { |
| case '0': case '1': case '-': |
| { |
| is_digit = true; |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| break; |
| } |
| default: |
| is_digit = false; |
| } |
| |
| return is_digit; |
| } |
| |
| inline int |
| scfx_to_digit(char c, sc_numrep numrep) |
| { |
| int to_digit; |
| |
| switch (numrep) { |
| case SC_DEC: |
| case SC_BIN: |
| case SC_BIN_US: |
| case SC_BIN_SM: |
| case SC_OCT: |
| case SC_OCT_US: |
| case SC_OCT_SM: |
| { |
| to_digit = c - '0'; |
| break; |
| } |
| case SC_HEX: |
| case SC_HEX_US: |
| case SC_HEX_SM: |
| { |
| switch (c) { |
| case '0': case '1': case '2': case '3': case '4': |
| case '5': case '6': case '7': case '8': case '9': |
| to_digit = c - '0'; |
| break; |
| case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': |
| to_digit = c - 'a' + 10; |
| break; |
| case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': |
| to_digit = c - 'A' + 10; |
| break; |
| default: |
| to_digit = -2; |
| } |
| break; |
| } |
| case SC_CSD: |
| { |
| if (c == '-') |
| to_digit = -1; |
| else |
| to_digit = c - '0'; |
| break; |
| } |
| default: |
| to_digit = -2; |
| } |
| |
| return to_digit; |
| } |
| |
| |
| // ---------------------------------------------------------------------------- |
| // Utilities for printing a character string number |
| // ---------------------------------------------------------------------------- |
| |
| inline void scfx_print_nan(scfx_string &s) { s += "NaN"; } |
| inline void |
| scfx_print_inf(scfx_string &s, bool negative) |
| { |
| if (negative) |
| s += "-Inf"; |
| else |
| s += "Inf"; |
| } |
| |
| inline void |
| scfx_print_prefix(scfx_string &s, sc_numrep numrep) |
| { |
| switch (numrep) { |
| case SC_DEC: |
| s += "0d"; |
| break; |
| case SC_BIN: |
| s += "0b"; |
| break; |
| case SC_BIN_US: |
| s += "0bus"; |
| break; |
| case SC_BIN_SM: |
| s += "0bsm"; |
| break; |
| case SC_OCT: |
| s += "0o"; |
| break; |
| case SC_OCT_US: |
| s += "0ous"; |
| break; |
| case SC_OCT_SM: |
| s += "0osm"; |
| break; |
| case SC_HEX: |
| s += "0x"; |
| break; |
| case SC_HEX_US: |
| s += "0xus"; |
| break; |
| case SC_HEX_SM: |
| s += "0xsm"; |
| break; |
| case SC_CSD: |
| s += "0csd"; |
| break; |
| default: |
| s += "unknown"; |
| } |
| } |
| |
| inline void |
| scfx_print_exp(scfx_string &s, int exp) |
| { |
| if (exp != 0) { |
| s += 'e'; |
| |
| if (exp < 0) { |
| exp = - exp; |
| s += '-'; |
| } else { |
| s += '+'; |
| } |
| |
| bool first = true; |
| int scale = 1000000000; |
| do { |
| int digit = exp / scale; |
| exp = exp % scale; |
| if (digit != 0 || !first) { |
| s += static_cast<char>(digit + '0'); |
| first = false; |
| } |
| scale /= 10; |
| } |
| while (scale > 0); |
| } |
| } |
| |
| void scfx_tc2csd(scfx_string &, int); |
| void scfx_csd2tc(scfx_string &); |
| |
| } // namespace sc_dt |
| |
| #endif // __SYSTEMC_EXT_DT_FX_SCFX_UTILS_HH__ |