SystemC 3.0.0
Accellera SystemC proof-of-concept library
sc_nbutils.h
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_nbutils.h -- External and friend functions for both sc_signed and
23 sc_unsigned classes.
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// $Log: sc_nbutils.h,v $
40// Revision 1.6 2011/09/08 16:12:15 acg
41// Philipp A. Hartmann: fix issue with Sun machines wrt real math libraries.
42//
43// Revision 1.5 2011/08/26 23:00:01 acg
44// Torsten Maehne: remove use of ieeefp.h.
45//
46// Revision 1.4 2011/08/15 16:43:24 acg
47// Torsten Maehne: changes to remove unused argument warnings.
48//
49// Revision 1.3 2011/02/18 20:19:15 acg
50// Andy Goodrich: updating Copyright notice.
51//
52// Revision 1.2 2010/09/06 16:35:48 acg
53// Andy Goodrich: changed i386 to __i386__ in ifdef's.
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#ifndef SC_NBUTILS_H
64#define SC_NBUTILS_H
65
66#include <cmath>
67#include <limits>
68
74
75namespace sc_dt
76{
77
78// Parse a character string into its equivalent binary bits.
79extern
81 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
82);
83
84
85// Parse a character string into its equivalent hexadecimal bits.
86extern
88 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p=0
89);
90
91// ----------------------------------------------------------------------------
92// Various utility functions.
93// ----------------------------------------------------------------------------
94
95// Concatenate the high part h and low part l. Assumes that h and l
96// are less than or equal to HALF_DIGIT_MASK;
97inline
100{
101 return ((h << BITS_PER_HALF_DIGIT) | l);
102}
103
104// Create a number with n 1's.
105inline
108{
109 return (((sc_carry) 1 << n) - 1);
110}
111
112// Create a number with one 1 and n 0's.
113inline
116{
117 return ((sc_carry) 1 << n);
118}
119
120// ----------------------------------------------------------------------------
121// Functions to handle built-in types or signs.
122// ----------------------------------------------------------------------------
123
124// u = v
125// - v is an unsigned long or uint64, and positive integer.
126template< class Type >
127inline
128void
129from_uint(int ulen, sc_digit *u, Type v)
130{
131
132#ifdef DEBUG_SYSTEMC
133 // assert((ulen <= 0) || (u != NULL));
134 assert((ulen > 0) && (u != NULL));
135 assert(v >= 0);
136#endif
137
138 int i = 0;
139
140 while (v && (i < ulen)) {
141#ifndef WIN32
142 u[i++] = static_cast<sc_digit>( v & DIGIT_MASK );
143#else
144 u[i++] = ((sc_digit) v) & DIGIT_MASK;
145#endif
146 v >>= BITS_PER_DIGIT;
147 }
148
149 for ( int digit_i = i; digit_i < ulen; ++digit_i ) { u[digit_i] = 0; }
150
151}
152
153
154
155// ----------------------------------------------------------------------------
156// Functions to test for errors and print out error messages.
157// ----------------------------------------------------------------------------
158
159template< class Type >
160inline
161void
163{
164 if (s == 0) {
166 "div_by_zero<Type>( Type ) : division by zero" );
167 }
168}
169
170
171// ----------------------------------------------------------------------------
172// Functions for both signed and unsigned numbers to convert sign-magnitude
173// (SM) and 2's complement (2C) representations.
174// added = 1 => for signed.
175// added = 0 => for unsigned.
176// IF_SC_SIGNED can be used as 'added'.
177// ----------------------------------------------------------------------------
178
179// Trim the extra leading bits of a signed or unsigned number.
180inline
181void
182trim(small_type added, int nb, int nd, sc_digit *d)
183{
184#ifdef DEBUG_SYSTEMC
185 assert((nb > 0) && (nd > 0) && (d != NULL));
186#endif
187
188 d[nd - 1] &= one_and_ones(SC_BIT_INDEX(nb - 1) + added);
189}
190
191// ----------------------------------------------------------------------------
192// Faster set(i, v), without bound checking.
193// ----------------------------------------------------------------------------
194
195// A version of set(i, v) without bound checking.
196inline
197void
198safe_set(int i, bool v, sc_digit *d)
199{
200
201#ifdef DEBUG_SYSTEMC
202 assert((i >= 0) && (d != NULL));
203#endif
204
205 int bit_num = SC_BIT_INDEX(i);
206 int digit_num = SC_DIGIT_INDEX(i);
207
208 if (v)
209 d[digit_num] |= one_and_zeros(bit_num);
210 else
211 d[digit_num] &= ~(one_and_zeros(bit_num));
212
213}
214
215
216// ----------------------------------------------------------------------------
217// Function to check if a double number is bad (NaN or infinite).
218// ----------------------------------------------------------------------------
219
220inline
221bool
222is_nan( double v )
223{
224 return std::numeric_limits<double>::has_quiet_NaN && (v != v);
225}
226
227inline
228bool
229is_inf( double v )
230{
231 return v == std::numeric_limits<double>::infinity()
232 || v == -std::numeric_limits<double>::infinity();
233}
234
235inline
236void
238{
239// Windows throws exception.
240 if( is_nan(v) || is_inf(v) )
242 "is_bad_double( double v ) : "
243 "v is not finite - NaN or Inf" );
244}
245
246//--------------------------------------------------------------------------------------------------
247// sc_digit_heap - CLASS MANAGING A TEMPORARY HEAP OF BYTES
248//
249// This facility implements a heap of temporary sc_digit allocations. Once a
250// request has been allocated it is not freed. However the entire heap
251// wraps and the storage is reused. This means that no allocations should
252// be assumed as permanent. Allocations are double-word aligned. This is
253// raw storage, so objects which contain virtual methods cannot be allocated
254// with this object. See the sc_vpool object for that type of storage
255// allocation.
256//
257// sc_digit* allocate( int digits_n )
258// This method returns a pointer to block of digit_n sc_digits. The block
259// returned is the next available one in the heap. If the current heap
260// cannot fullfil the request it will be rewound and storage allocated from
261// its start. All allocations start on an 8-byte boundary.
262// digits_n = number of sc_digits to be allocated.
263//
264// void initialize( int heap_size=0x100000 )
265// This method allocates the storage to be managed. If there is already
266// a block of storage under management it is freed. If no argument is
267// provided for the heap size, 0x10000 sc_digit instances will be allocated.
268// heap_size = number of sc_digit instances to allocate for the heap.
269//
270// unsigned int length()
271// This method returns the size of this object's heap in bytes.
272//
273// sc_digit_heap()
274// This is the non-initialized object instance constructor. It does not
275// allocate the heap storage, that is done by the initialize() method.
276//
277// sc_digit_heap(int heap_size)
278// This is the initializing object instance constructor. It does allocates
279// a heap of the specified number of sc_digit instances.
280// heap_size = number of sc_digit instances to allocate for the heap.
281//--------------------------------------------------------------------------------------------------
283 public:
284 sc_digit* m_bgn_p; // Beginning of heap storage.
285 sc_digit* m_end_p; // End of heap storage.
286 sc_digit* m_next_p; // Next heap location to be allocated.
287
288 inline sc_digit* allocate( size_t digits_n )
289 {
290 sc_digit* result_p;
291 result_p = m_next_p;
292 m_next_p += digits_n;
293 if ( m_next_p >= m_end_p )
294 {
295 result_p = m_bgn_p;
296 m_next_p = m_bgn_p + digits_n;
297 }
298 return result_p;
299 }
300
301 inline void initialize( size_t heap_size=0x100000 )
302 {
303 delete [] m_bgn_p;
304 m_bgn_p = new sc_digit[heap_size];
305 m_end_p = &m_bgn_p[heap_size];
306 m_next_p = m_bgn_p;
307 }
308
309 inline size_t length()
310 {
311 return (size_t)(m_end_p - m_bgn_p);
312 }
313
314 inline sc_digit_heap() : m_bgn_p(0), m_end_p(0), m_next_p(0)
315 {
316 }
317
318 inline sc_digit_heap( size_t heap_size ) : m_bgn_p(0), m_end_p(0), m_next_p(0)
319 {
320 initialize( heap_size );
321 }
322
324 {
325 delete [] m_bgn_p;
326 }
327
328};
329
330// Reference to the sc_digit_heap instance present in sc_nbutils.cpp:
331
332extern sc_digit_heap SC_API sc_temporary_digits;
333
334} // namespace sc_dt
335
336#endif
#define SC_DIGIT_INDEX(BIT_INDEX)
Definition: sc_nbdefs.h:186
#define DIGIT_MASK
Definition: sc_nbdefs.h:168
#define SC_BIT_INDEX(BIT)
Definition: sc_nbdefs.h:185
#define BITS_PER_DIGIT
Definition: sc_nbdefs.h:164
#define BITS_PER_HALF_DIGIT
Definition: sc_nbdefs.h:203
#define SC_API
Definition: sc_cmnhdr.h:148
#define SC_REPORT_ERROR(msg_type, msg)
Definition: sc_report.h:217
const char SC_ID_OPERATION_FAILED_[]
const char SC_ID_VALUE_NOT_VALID_[]
bool is_inf(double v)
Definition: sc_nbutils.h:229
bool is_nan(double v)
Definition: sc_nbutils.h:222
int small_type
Definition: sc_nbdefs.h:137
SC_API void parse_hex_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0)
SC_API void parse_binary_bits(const char *src_p, int dst_n, sc_digit *data_p, sc_digit *ctrl_p=0)
sc_digit_heap SC_API sc_temporary_digits
sc_carry one_and_zeros(int n)
Definition: sc_nbutils.h:115
void from_uint(int ulen, sc_digit *u, Type v)
Definition: sc_nbutils.h:129
sc_concref_r< sc_bitref_r< T1 >, sc_bitref_r< T2 > > concat(sc_bitref_r< T1 >, sc_bitref_r< T2 >)
void safe_set(int i, bool v, sc_digit *d)
Definition: sc_nbutils.h:198
void is_bad_double(double v)
Definition: sc_nbutils.h:237
sc_carry one_and_ones(int n)
Definition: sc_nbutils.h:107
void div_by_zero(Type s)
Definition: sc_nbutils.h:162
unsigned int sc_digit
Definition: sc_nbdefs.h:161
void trim(small_type added, int nb, int nd, sc_digit *d)
Definition: sc_nbutils.h:182
uint64 sc_carry
Definition: sc_nbdefs.h:225
sc_digit_heap(size_t heap_size)
Definition: sc_nbutils.h:318
void initialize(size_t heap_size=0x100000)
Definition: sc_nbutils.h:301
sc_digit * m_next_p
Definition: sc_nbutils.h:286
sc_digit * m_end_p
Definition: sc_nbutils.h:285
sc_digit * allocate(size_t digits_n)
Definition: sc_nbutils.h:288
sc_digit * m_bgn_p
Definition: sc_nbutils.h:284