| /***************************************************************************** |
| |
| 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 SCFX_UTILS_H |
| #define SCFX_UTILS_H |
| |
| |
| #include "sysc/datatypes/fx/sc_fxdefs.h" |
| #include "sysc/datatypes/fx/scfx_params.h" |
| #include "sysc/datatypes/fx/scfx_string.h" |
| |
| |
| 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 defined(SC_LONG_64) |
| MSB_STATEMENT( 32 ); |
| # endif // defined(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 defined(SC_LONG_64) |
| i = 63; |
| LSB_STATEMENT( 32 ); |
| # else |
| i = 31; |
| # endif // defined(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 |
| |
| // Taf! |