diff options
Diffstat (limited to 'ext/systemc/src/sysc/utils')
24 files changed, 6825 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/utils/sc_hash.cpp b/ext/systemc/src/sysc/utils/sc_hash.cpp new file mode 100644 index 000000000..fc97fe416 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_hash.cpp @@ -0,0 +1,670 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_hash.cpp -- Implementation of a chained hash table with MTF + (move-to-front). + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#include <assert.h> +#include <stdlib.h> // duplicate (c)stdlib.h headers for Solaris +#include <cstdlib> +#include <cstddef> +#include <string.h> + +#include "sysc/kernel/sc_cmnhdr.h" +#include "sysc/utils/sc_hash.h" +#include "sysc/utils/sc_mempool.h" + +namespace sc_core { + +// we can't assume global availability of uintptr_t, +// approximate it by size_t +typedef std::size_t uintptr_t; + +const double PHASH_DEFAULT_GROW_FACTOR = 2.0; + +class sc_phash_elem { + friend class sc_phash_base; + friend class sc_phash_base_iter; + +private: + void* key; + void* contents; + sc_phash_elem* next; + + sc_phash_elem( void* k, void* c, sc_phash_elem* n ) + : key(k), contents(c), next(n) { } + sc_phash_elem() : key(0), contents(0), next(0) { } + ~sc_phash_elem() { } + + static void* operator new(std::size_t sz) + { return sc_mempool::allocate(sz); } + static void operator delete(void* p, std::size_t sz) + { sc_mempool::release(p, sz); } +}; + + +sc_phash_base::sc_phash_base( + void* def, + int size, + int density, + double grow, + bool reorder, + unsigned (*hash_fn)(const void*), + int (*cmp_fn)(const void*, const void*) +) : + default_value(def), num_bins(0), num_entries(0), max_density(density), + reorder_flag(reorder), grow_factor(grow), bins(0), hash(hash_fn), + cmpr(cmp_fn) +{ + if (size <= 0) + size = PHASH_DEFAULT_INIT_TABLE_SIZE; + else if ((size % 2) == 0) + size += 1; + num_bins = size; + bins = new sc_phash_elem*[size]; + for (int i = 0; i < size; ++i) + bins[i] = 0; +} + +void +sc_phash_base::set_cmpr_fn(cmpr_fn_t c) +{ + cmpr = c; +} + +void +sc_phash_base::set_hash_fn(hash_fn_t h) +{ + hash = h; +} + +sc_phash_base::~sc_phash_base() +{ + sc_phash_elem* ptr; + sc_phash_elem* next; + + for (int i = 0; i < num_bins; ++i) { + ptr = bins[i]; + while (ptr != 0) { + next = ptr->next; + delete ptr; + ptr = next; + } + } + delete[] bins; +} + +void +sc_phash_base::rehash() +{ + sc_phash_elem* ptr; + sc_phash_elem* next; + sc_phash_elem** old_bins = bins; + + int old_num_bins = num_bins; + unsigned hash_val; + + num_bins = (int) (grow_factor * old_num_bins); + if (num_bins % 2 == 0) + ++num_bins; + + num_entries = 0; + bins = new sc_phash_elem*[num_bins]; + memset( bins, 0, sizeof(sc_phash_elem*) * num_bins ); + + for (int i = 0; i < old_num_bins; ++i) { + ptr = old_bins[i]; + while (ptr != 0) { + next = ptr->next; + hash_val = do_hash(ptr->key); + ptr->next = bins[hash_val]; + bins[hash_val] = ptr; + ++num_entries; + ptr = next; + } + } + delete[] old_bins; +} + +sc_phash_elem* +sc_phash_base::find_entry_q( unsigned hash_val, const void* key, sc_phash_elem*** plast ) +{ + sc_phash_elem** last = &(bins[hash_val]); + sc_phash_elem* ptr = *last; + + /* The (ptr->key != key) here is meant by the "q" */ + while ((ptr != 0) && (ptr->key != key)) { + /* ^^ right here */ + last = &(ptr->next); + ptr = *last; + } + if ((ptr != 0) && reorder_flag) { + *last = ptr->next; + ptr->next = bins[hash_val]; + bins[hash_val] = ptr; + last = &(bins[hash_val]); + } + if (plast) *plast = last; + return ptr; +} + +sc_phash_elem* +sc_phash_base::find_entry_c( unsigned hash_val, const void* key, sc_phash_elem*** plast ) +{ + sc_phash_elem** last = &(bins[hash_val]); + sc_phash_elem* ptr = *last; + + while ((ptr != 0) && ((*cmpr)(ptr->key, key) != 0)) { + last = &(ptr->next); + ptr = *last; + } + /* Bring to front */ + if ((ptr != 0) && reorder_flag) { + *last = ptr->next; + ptr->next = bins[hash_val]; + bins[hash_val] = ptr; + last = &(bins[hash_val]); + } + if (plast) *plast = last; + return ptr; +} + +sc_phash_elem* +sc_phash_base::add_direct( void* key, void* contents, unsigned hash_val ) +{ + if (num_entries / num_bins >= max_density) { + rehash(); + hash_val = do_hash(key); + } + + sc_phash_elem* new_entry = new sc_phash_elem(key, contents, bins[hash_val]); + bins[hash_val] = new_entry; + ++num_entries; + return new_entry; +} + +void +sc_phash_base::erase() +{ + for (int i = 0; i < num_bins; ++i) { + sc_phash_elem* ptr = bins[i]; + while (ptr != 0) { + sc_phash_elem* next = ptr->next; + delete ptr; + ptr = next; + --num_entries; + } + bins[i] = 0; + } + assert(num_entries == 0); +} + +void +sc_phash_base::erase(void (*kfree)(void*)) +{ + for (int i = 0; i < num_bins; ++i) { + sc_phash_elem* ptr = bins[i]; + while (ptr != 0) { + sc_phash_elem* next = ptr->next; + (*kfree)(ptr->key); + delete ptr; + ptr = next; + --num_entries; + } + bins[i] = 0; + } + assert(num_entries == 0); +} + +void +sc_phash_base::copy( const sc_phash_base* b ) +{ + erase(); + iterator iter((sc_phash_base*) b); /* cast away the const */ + for ( ; ! iter.empty(); iter++) + insert( iter.key(), iter.contents() ); +} + +void +sc_phash_base::copy(const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*)) +{ + erase(kfree); + iterator iter((sc_phash_base&) b); + for ( ; ! iter.empty(); iter++) + insert( (*kdup)(iter.key()), iter.contents() ); +} + +int +sc_phash_base::insert( void* k, void* c ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem* ptr = find_entry( hash_val, k ); + if (ptr == 0) { + (void) add_direct(k, c, hash_val); + return 0; + } + else { + ptr->contents = c; + return 1; + } +} + +int +sc_phash_base::insert( void* k, void* c, void* (*kdup)(const void*) ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem* ptr = find_entry( hash_val, k ); + if (ptr == 0) { + (void) add_direct((*kdup)(k), c, hash_val); + return 0; + } + else { + ptr->contents = c; + return 1; + } +} + +int +sc_phash_base::insert_if_not_exists( void* k, void* c ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem* ptr = find_entry( hash_val, k ); + if (ptr == 0) { + (void) add_direct( k, c, hash_val ); + return 0; + } + else + return 1; +} + +int +sc_phash_base::insert_if_not_exists( void* k, void* c, void* (*kdup)(const void*) ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem* ptr = find_entry( hash_val, k ); + if (ptr == 0) { + (void) add_direct( (*kdup)(k), c, hash_val ); + return 0; + } + else + return 1; +} + +int +sc_phash_base::remove( const void* k ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem** last; + sc_phash_elem* ptr = find_entry( hash_val, k, &last ); + + if (ptr == 0) + return 0; + + assert(*last == ptr); + *last = ptr->next; + delete ptr; + --num_entries; + return 1; +} + +int +sc_phash_base::remove( const void* k, void** pk, void** pc ) +{ + unsigned hash_val = do_hash(k); + sc_phash_elem** last; + sc_phash_elem* ptr = find_entry( hash_val, k, &last ); + + if (ptr == 0) { + *pk = 0; + *pc = 0; + return 0; + } + else { + *pk = ptr->key; + *pc = ptr->contents; + } + + assert(*last == ptr); + *last = ptr->next; + delete ptr; + --num_entries; + return 1; +} + +int +sc_phash_base::remove(const void* k, void (*kfree)(void*)) +{ + void* rk; + void* rc; + if (remove(k, &rk, &rc)) { + (*kfree)(rk); + return 1; + } + else + return 0; +} + +int +sc_phash_base::remove_by_contents( const void* c ) +{ + sc_phash_elem** last; + sc_phash_elem* ptr; + + int num_removed = 0; + for (int i = 0; i < num_bins; ++i) { + last = &(bins[i]); + ptr = *last; + while (ptr != 0) { + if (ptr->contents != c) { + last = &(ptr->next); + ptr = *last; + } + else { + *last = ptr->next; + delete ptr; + ptr = *last; + --num_entries; + ++num_removed; + } + } + } + return num_removed; +} + +int +sc_phash_base::remove_by_contents( bool (*predicate)(const void* c, void* arg), void* arg ) +{ + sc_phash_elem** last; + sc_phash_elem* ptr; + + int num_removed = 0; + for (int i = 0; i < num_bins; ++i) { + last = &(bins[i]); + ptr = *last; + while (ptr != 0) { + if (! (*predicate)(ptr->contents, arg)) { + last = &(ptr->next); + ptr = *last; + } + else { + *last = ptr->next; + delete ptr; + ptr = *last; + --num_entries; + ++num_removed; + } + } + } + return num_removed; +} + +int +sc_phash_base::remove_by_contents( const void* c, void (*kfree)(void*) ) +{ + sc_phash_elem** last; + sc_phash_elem* ptr; + + int num_removed = 0; + for (int i = 0; i < num_bins; ++i) { + last = &(bins[i]); + ptr = *last; + while (ptr != 0) { + if (ptr->contents != c) { + last = &(ptr->next); + ptr = *last; + } + else { + *last = ptr->next; + (*kfree)(ptr->key); + delete ptr; + ptr = *last; + --num_entries; + ++num_removed; + } + } + } + return num_removed; +} + +int +sc_phash_base::remove_by_contents( bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)) +{ + sc_phash_elem** last; + sc_phash_elem* ptr; + + int num_removed = 0; + for (int i = 0; i < num_bins; ++i) { + last = &(bins[i]); + ptr = *last; + while (ptr != 0) { + if (! (*predicate)(ptr->contents, arg)) { + last = &(ptr->next); + ptr = *last; + } + else { + *last = ptr->next; + (*kfree)(ptr->key); + delete ptr; + ptr = *last; + --num_entries; + ++num_removed; + } + } + } + return num_removed; +} + +int +sc_phash_base::lookup( const void* k, void** c_ptr ) const +{ + unsigned hash_val = do_hash(k); + sc_phash_elem* ptr = find_entry( hash_val, k ); + if (ptr == 0) { + if (c_ptr != 0) *c_ptr = default_value; + return 0; + } + else { + if (c_ptr != 0) *c_ptr = ptr->contents; + return 1; + } +} + +void* +sc_phash_base::operator[]( const void* key ) const +{ + void* contents; + lookup( key, &contents ); + return contents; +} + +/***************************************************************************/ + +void +sc_phash_base_iter::reset( sc_phash_base* t ) +{ + table = t; + index = 0; + entry = 0; + next = 0; + + for (int i = index; i < table->num_bins; ++i) { + if (table->bins[i] != 0) { + index = i + 1; + last = &(table->bins[i]); + entry = *last; + next = entry->next; + break; + } + } +} + +bool +sc_phash_base_iter::empty() const +{ + return (entry == 0); +} + +void +sc_phash_base_iter::step() +{ + if (entry) { + last = &(entry->next); + } + entry = next; + if (! entry) { + for (int i = index; i < table->num_bins; ++i) { + if (table->bins[i] != 0) { + index = i + 1; + last = &(table->bins[i]); + entry = *last; + next = entry->next; + break; + } + } + } + else { + next = entry->next; + } +} + +void +sc_phash_base_iter::remove() +{ + delete entry; + *last = next; + entry = 0; + --table->num_entries; + step(); +} + +void +sc_phash_base_iter::remove(void (*kfree)(void*)) +{ + (*kfree)(entry->key); + delete entry; + *last = next; + entry = 0; + --table->num_entries; + step(); +} + +void* +sc_phash_base_iter::key() const +{ + return entry->key; +} + +void* +sc_phash_base_iter::contents() const +{ + return entry->contents; +} + +void* +sc_phash_base_iter::set_contents( void* c ) +{ + return entry->contents = c; +} + +/****************************************************************************/ + +unsigned +default_ptr_hash_fn(const void* p) +{ + return static_cast<unsigned>(((uintptr_t)(p) >> 2) * 2654435789U); + +} + +unsigned +default_int_hash_fn(const void* p) +{ + return static_cast<unsigned>((uintptr_t)(p) * 3141592661U); +} + + +unsigned +default_str_hash_fn(const void* p) +{ + if (!p) return 0; + + const char* x = (const char*) p; + unsigned int h = 0; + unsigned int g; + + while (*x != 0) { + h = (h << 4) + *x++; + if ((g = h & 0xf0000000) != 0) + h = (h ^ (g >> 24)) ^ g; + } + return h; +} + +int +sc_strhash_cmp( const void* a, const void* b ) +{ + return strcmp( (const char*) a, (const char*) b ); +} + +void* +sc_strhash_kdup(const void* k) +{ + char* result = (char*) malloc( strlen((const char*)k)+1 ); + strcpy(result, (const char*) k); + return result; +} + +void +sc_strhash_kfree(void* k) +{ + if (k) free((char*) k); +} + } // namespace sc_core + +// $Log: sc_hash.cpp,v $ +// Revision 1.5 2011/08/26 20:42:30 acg +// Andy Goodrich: +// (1) Replaced strdup with new and strcpy to eliminate issue with the +// Greenhills compiler. +// (2) Moved modification log to the end of the file to eliminate line +// skew when check-ins are done. +// +// Revision 1.4 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.3 2011/05/05 17:46:04 acg +// Philip A. Hartmann: changes in "swap" support. +// +// Revision 1.2 2011/02/18 20:38:43 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_hash.h b/ext/systemc/src/sysc/utils/sc_hash.h new file mode 100644 index 000000000..14f8ee980 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_hash.h @@ -0,0 +1,460 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_hash.cpp -- Implementation of a chained hash table with MTF + (move-to-front). + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_HASH_H +#define SC_HASH_H + + +namespace sc_core { + +extern unsigned default_int_hash_fn(const void*); +extern unsigned default_ptr_hash_fn(const void*); +extern unsigned default_str_hash_fn(const void*); + +class sc_phash_elem; +class sc_phash_base_iter; +template<class K, class C> //template class +class sc_pdhash_iter; //decl. -- Amit + +const int PHASH_DEFAULT_MAX_DENSITY = 5; +const int PHASH_DEFAULT_INIT_TABLE_SIZE = 11; +extern const double PHASH_DEFAULT_GROW_FACTOR; +const bool PHASH_DEFAULT_REORDER_FLAG = true; + +class sc_phash_base { + friend class sc_phash_base_iter; + + typedef sc_phash_base_iter iterator; + +public: + typedef unsigned (*hash_fn_t)(const void*); + typedef int (*cmpr_fn_t)(const void*, const void*); + +protected: + void* default_value; + int num_bins; + int num_entries; + int max_density; + int reorder_flag; + double grow_factor; + + sc_phash_elem** bins; + + hash_fn_t hash; + cmpr_fn_t cmpr; + + void rehash(); + unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; } + + sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val); + sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast); + sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast); + sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const + { + /* Got rid of member func. pointer and replaced with if-else */ + /* Amit (5/14/99) */ + if( cmpr == 0 ) + return ((sc_phash_base*)this)->find_entry_q( hv, k, plast ); + else + return ((sc_phash_base*)this)->find_entry_c( hv, k, plast ); + } + +public: + sc_phash_base( void* def = 0, + int size = PHASH_DEFAULT_INIT_TABLE_SIZE, + int density = PHASH_DEFAULT_MAX_DENSITY, + double grow = PHASH_DEFAULT_GROW_FACTOR, + bool reorder = PHASH_DEFAULT_REORDER_FLAG, + hash_fn_t hash_fn = default_ptr_hash_fn, + cmpr_fn_t cmpr_fn = 0 ); + ~sc_phash_base(); + + void set_cmpr_fn(cmpr_fn_t); + void set_hash_fn(hash_fn_t); + + bool empty() const { return (num_entries == 0); } + unsigned count() const { return num_entries; } + + void erase(); + void erase(void (*kfree)(void*)); + void copy( const sc_phash_base* ); + void copy( const sc_phash_base& b ) { copy(&b); } + void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*)); + int insert( void* k, void* c ); + int insert( void* k ) { return insert(k, default_value); } + int insert( void* k, void* c, void* (*kdup)(const void*) ); + int insert_if_not_exists(void* k, void* c); + int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); } + int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*)); + int remove(const void* k); + int remove(const void* k, void** pk, void** pc); + int remove(const void* k, void (*kfree)(void*)); + int remove_by_contents(const void* c); + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg); + int remove_by_contents(const void* c, void (*kfree)(void*)); + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)); + int lookup(const void* k, void** pc) const; + bool contains(const void* k) const { return (lookup(k, 0) != 0); } + void* operator[](const void* key) const; +}; + +class sc_phash_base_iter { +protected: + sc_phash_base* table; + sc_phash_elem* entry; + sc_phash_elem* next; + sc_phash_elem** last; + int index; + +public: + void reset(sc_phash_base* t); + void reset(sc_phash_base& t) { reset(&t); } + + sc_phash_base_iter(sc_phash_base* t) + : table(t), entry(0), next(0), last(0), index(0) + { reset(t); } + sc_phash_base_iter(sc_phash_base& t) + : table(&t), entry(0), next(0), last(0), index(0) + { reset(t); } + ~sc_phash_base_iter() { } + + bool empty() const; + void step(); + void operator++(int) { step(); } + void remove(); + void remove(void (*kfree)(void*)); + void* key() const; + void* contents() const; + void* set_contents(void* c); +}; + +template< class K, class C > +class sc_phash_iter; + +template< class K, class C > +class sc_phash : public sc_phash_base { + friend class sc_phash_iter<K,C>; + +public: + typedef sc_phash_iter<K,C> iterator; + + sc_phash( C def = (C) 0, + int size = PHASH_DEFAULT_INIT_TABLE_SIZE, + int density = PHASH_DEFAULT_MAX_DENSITY, + double grow = PHASH_DEFAULT_GROW_FACTOR, + bool reorder = PHASH_DEFAULT_REORDER_FLAG, + hash_fn_t hash_fn = default_ptr_hash_fn, + cmpr_fn_t cmpr_fn = 0 ) + : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { } + ~sc_phash() { } + + void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); } + void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); } + void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); } + + int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); } + int insert(K k) { return sc_phash_base::insert((void*) k, default_value); } + int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } + int insert_if_not_exists(K k, C c) + { + return sc_phash_base::insert_if_not_exists((void*) k, (void*) c); + } + int insert_if_not_exists(K k) + { + return sc_phash_base::insert_if_not_exists((void*) k, default_value); + } + int insert_if_not_exists(K k, C c, void* (*kdup)(const void*)) + { + return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); + } + int remove(K k) { return sc_phash_base::remove((const void*) k); } + int remove(K k, K* pk, C* pc) + { + return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); + } + int remove(K k, void (*kfree)(void*)) + { + return sc_phash_base::remove((const void*) k, kfree); + } + int remove_by_contents(C c) + { + return sc_phash_base::remove_by_contents((const void*) c); + } + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) + { + return sc_phash_base::remove_by_contents(predicate, arg); + } + int remove_by_contents(const void* c, void (*kfree)(void*)) + { + return sc_phash_base::remove_by_contents(c, kfree); + } + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)) + { + return sc_phash_base::remove_by_contents(predicate, arg, kfree); + } + int lookup(K k, C* pc) const + { + return sc_phash_base::lookup((const void*) k, (void**) pc); + } + bool contains(K k) const + { + return sc_phash_base::contains((const void*) k); + } + C operator[](K k) const + { + return (C) sc_phash_base::operator[]((const void*) k); + } +}; + + +template< class K, class C > +class sc_phash_iter : public sc_phash_base_iter { +public: + sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { } + sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { } + ~sc_phash_iter() { } + + void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); } + void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); } + + K key() const { return (K) sc_phash_base_iter::key(); } + C contents() const { return (C) sc_phash_base_iter::contents(); } + C set_contents(C c) + { + return (C) sc_phash_base_iter::set_contents((void*) c); + } +}; + + + + + +template< class K, class C > +class sc_pdhash : public sc_phash_base { + friend class sc_pdhash_iter<K,C>; + +private: + void* (*kdup)(const void*); //eliminated braces around void* -- Amit + void (*kfree)(void*); + +public: + typedef sc_pdhash_iter<K,C> iterator; + sc_pdhash( C def = (C) 0, + int size = PHASH_DEFAULT_INIT_TABLE_SIZE, + int density = PHASH_DEFAULT_MAX_DENSITY, + double grow = PHASH_DEFAULT_GROW_FACTOR, + bool reorder = PHASH_DEFAULT_REORDER_FLAG, + hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added -- + cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit + void* (*kdup_fn)(const void*) = 0, + void (*kfree_fn)(void*) = 0 ) + : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) + { + kdup = kdup_fn; + kfree = kfree_fn; + } + ~sc_pdhash() + { + erase(); + } + void erase() + { + sc_phash_base::erase(kfree); + } + void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); } + int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } + int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); } + int insert_if_not_exists(K k, C c) + { + return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); + } + int insert_if_not_exists(K k) + { + return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup); + } + int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); } + int remove(K k, K* pk, C* pc) + { + return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); + } + int remove_by_contents(C c) + { + return sc_phash_base::remove_by_contents((const void*) c, kfree); + } + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) + { + return sc_phash_base::remove_by_contents(predicate, arg, kfree); + } + int lookup(K k, C* pc) const + { + return sc_phash_base::lookup((const void*) k, (void**) pc); + } + bool contains(K k) const + { + return sc_phash_base::contains((const void*) k); + } + C operator[](K k) const + { + return (C) sc_phash_base::operator[]((const void*) k); + } +}; + +template< class K, class C > +class sc_pdhash_iter : public sc_phash_base_iter { +public: + sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { } + sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { } + ~sc_pdhash_iter() { } + + void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); } + void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); } + + void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); } + K key() const { return (K) sc_phash_base_iter::key(); } + C contents() const { return (C) sc_phash_base_iter::contents(); } + C set_contents(C c) + { + return (C) sc_phash_base_iter::set_contents((void*) c); + } +}; + +extern int sc_strhash_cmp( const void*, const void* ); +extern void sc_strhash_kfree(void*); +extern void* sc_strhash_kdup(const void*); + +template< class C > // template class decl. +class sc_strhash_iter; // --Amit + +template< class C > +class sc_strhash : public sc_phash_base { + friend class sc_strhash_iter<C>; + +public: + typedef sc_strhash_iter<C> iterator; + + sc_strhash( C def = (C) 0, + int size = PHASH_DEFAULT_INIT_TABLE_SIZE, + int density = PHASH_DEFAULT_MAX_DENSITY, + double grow = PHASH_DEFAULT_GROW_FACTOR, + bool reorder = PHASH_DEFAULT_REORDER_FLAG, + unsigned (*hash_fn)(const void*) = default_str_hash_fn, + int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp ) + : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) + { + + } + ~sc_strhash() + { + erase(); + } + + void erase() { sc_phash_base::erase(sc_strhash_kfree); } + void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); } + void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); } + + int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); } + int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); } + int insert_if_not_exists(char* k, C c) + { + return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup); + } + int insert_if_not_exists(char* k) + { + return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup); + } + int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); } + int remove(const char* k, char** pk, C* pc) + { + return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); + } + int remove_by_contents(C c) + { + return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree); + } + int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) + { + return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree); + } + int lookup(const char* k, C* pc) const + { + return sc_phash_base::lookup((const void*) k, (void** )pc); + } + bool contains(const char* k) const + { + return sc_phash_base::contains((const void*) k); + } + C operator[](const char* k) const + { + return (C) sc_phash_base::operator[]((const void*) k); + } +}; + +template<class C> +class sc_strhash_iter : public sc_phash_base_iter { +public: + sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { } + sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { } + ~sc_strhash_iter() { } + + void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); } + void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); } + + void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); } + const char* key() { return (const char*) sc_phash_base_iter::key(); } + C contents() { return (C) sc_phash_base_iter::contents(); } + C set_contents(C c) + { + return (C) sc_phash_base_iter::set_contents((void*) c); + } +}; + +} // namespace sc_core + +// $Log: sc_hash.h,v $ +// Revision 1.5 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.4 2011/08/26 20:46:16 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:43 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_iostream.h b/ext/systemc/src/sysc/utils/sc_iostream.h new file mode 100644 index 000000000..4f19d511e --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_iostream.h @@ -0,0 +1,91 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_iostream.h - Portable iostream header file wrapper. + + Original Author: Martin Janssen, Synopsys, Inc. + + Note: Deprecated in the meantime, since all supported + compilers are supposed to have a working C++ + standard library. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_IOSTREAM_H +#define SC_IOSTREAM_H + +#include <ios> +#include <iostream> +#include <sstream> +#include <fstream> +#include <cstddef> +#include <cstring> + +// We use typedefs for istream and ostream here to get around some finickiness +// from aCC: + +namespace sc_dt { + +typedef ::std::istream systemc_istream; +typedef ::std::ostream systemc_ostream; + +} // namespace sc_dt + +// shortcuts that save some typing + +#ifdef CCAST +# undef CCAST +#endif +#define CCAST const_cast + +#ifdef DCAST +# undef DCAST +#endif +#define DCAST dynamic_cast + +#ifdef RCAST +# undef RCAST +#endif +#define RCAST reinterpret_cast + +#ifdef SCAST +# undef SCAST +#endif +#define SCAST static_cast + +// $Log: sc_iostream.h,v $ +// Revision 1.3 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.2 2011/02/18 20:38:43 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif // !defined(SC_IOSTREAM_H) diff --git a/ext/systemc/src/sysc/utils/sc_list.cpp b/ext/systemc/src/sysc/utils/sc_list.cpp new file mode 100644 index 000000000..88998fbe9 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_list.cpp @@ -0,0 +1,343 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_list.cpp -- Simple implementation of a doubly linked list. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#include <assert.h> +#include <cstddef> + +#include "sysc/kernel/sc_cmnhdr.h" +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_list.h" +#include "sysc/utils/sc_mempool.h" +#include "sysc/utils/sc_report.h" +#include "sysc/utils/sc_utils_ids.h" + +namespace sc_core { + +class sc_plist_elem { + friend class sc_plist_base_iter; + friend class sc_plist_base; + +private: + sc_plist_elem() : data(0), prev(0), next(0) + {} + sc_plist_elem( void* d, sc_plist_elem* p, sc_plist_elem* n ) : + data(d), prev(p), next(n) + {} + ~sc_plist_elem() + {} + + static void* operator new(std::size_t sz) { return sc_mempool::allocate(sz); } + static void operator delete(void* p, std::size_t sz) { sc_mempool::release(p, sz); } + + void* data; + sc_plist_elem* prev; + sc_plist_elem* next; +}; + +sc_plist_base::sc_plist_base() : head(0), tail(0) {} + +sc_plist_base::~sc_plist_base() +{ + handle_t p; + for( handle_t h = head; h != 0; h = p ) { + p = h->next; + delete h; + } +} + +void +sc_plist_base::erase_all() +{ + handle_t p; + for( handle_t h = head; h != 0; h = p ) { + p = h->next; + delete h; + } + head = 0; + tail = 0; +} + +int +sc_plist_base::size() const +{ + int n = 0; + for( handle_t h = head; h != 0; h = h->next ) { + n++; + } + return n; +} + +sc_plist_base::handle_t +sc_plist_base::push_back( void* d ) +{ + handle_t q = new sc_plist_elem( d, tail, 0 ); + if (tail) { + tail->next = q; + tail = q; + } + else { + head = tail = q; + } + return q; +} + +sc_plist_base::handle_t +sc_plist_base::push_front( void* d ) +{ + handle_t q = new sc_plist_elem( d, (sc_plist_elem*) 0, head ); + if (head) { + head->prev = q; + head = q; + } + else { + head = tail = q; + } + return q; +} + +void* +sc_plist_base::pop_back() +{ + handle_t q = tail; + void* d = q->data; + tail = tail->prev; + delete q; + if (tail != 0) { + tail->next = 0; + } + else { + head = 0; + } + return d; +} + +void* +sc_plist_base::pop_front() +{ + handle_t q = head; + void* d = q->data; + head = head->next; + delete q; + if (head != 0) { + head->prev = 0; + } + else { + tail = 0; + } + return d; +} + +sc_plist_base::handle_t +sc_plist_base::insert_before( handle_t h, void* d ) +{ + if (h == 0) { + return push_back(d); + } + else { + handle_t q = new sc_plist_elem( d, h->prev, h ); + h->prev->next = q; + h->prev = q; + return q; + } +} + +sc_plist_base::handle_t +sc_plist_base::insert_after( handle_t h, void* d ) +{ + if (h == 0) { + return push_front(d); + } + else { + handle_t q = new sc_plist_elem( d, h, h->next ); + h->next->prev = q; + h->next = q; + return q; + } +} + +void* +sc_plist_base::remove( handle_t h ) +{ + if (h == head) + return pop_front(); + else if (h == tail) + return pop_back(); + else { + void* d = h->data; + h->prev->next = h->next; + h->next->prev = h->prev; + delete h; + return d; + } +} + +void* +sc_plist_base::get( handle_t h ) const +{ + return h->data; +} + +void +sc_plist_base::set( handle_t h, void* d ) +{ + h->data = d; +} + +void +sc_plist_base::mapcar( sc_plist_map_fn f, void* arg ) +{ + for (handle_t h = head; h != 0; h = h->next) { + f( h->data, arg ); + } +} + +void* +sc_plist_base::front() const +{ + + if (head) { + return head->data; + } + else { + SC_REPORT_ERROR( SC_ID_FRONT_ON_EMPTY_LIST_ , 0 ); + // never reached + return 0; + } +} + +void* +sc_plist_base::back() const +{ + if (tail) { + return tail->data; + } + else { + SC_REPORT_ERROR( SC_ID_BACK_ON_EMPTY_LIST_, 0 ); + // never reached + return 0; + } +} + + + +sc_plist_base_iter::sc_plist_base_iter( sc_plist_base* l, bool from_tail ) : + lst(l), ptr( from_tail ? l->tail : l->head ) +{ +} + +void +sc_plist_base_iter::reset( sc_plist_base* l, bool from_tail ) +{ + lst = l; + if (from_tail) { + ptr = l->tail; + } + else { + ptr = l->head; + } +} + +sc_plist_base_iter::~sc_plist_base_iter() +{ + +} + +bool +sc_plist_base_iter::empty() const +{ + return ptr == 0; +} + +void +sc_plist_base_iter::operator++(int) +{ + ptr = ptr->next; +} + +void +sc_plist_base_iter::operator--(int) +{ + ptr = ptr->prev; +} + +void* +sc_plist_base_iter::get() const +{ + return ptr->data; +} + +void +sc_plist_base_iter::set( void* d ) +{ + ptr->data = d; +} + +void +sc_plist_base_iter::remove() +{ + sc_plist_base::handle_t nptr = ptr->next; + lst->remove(ptr); + ptr = nptr; +} + +void +sc_plist_base_iter::remove(int direction) +{ + sc_plist_base::handle_t nptr = (direction == 1) ? ptr->next : ptr->prev; + lst->remove(ptr); + ptr = nptr; +} + +void +sc_plist_base_iter::set_handle( sc_plist_elem* h ) +{ + ptr = h; +} + +} // namespace sc_core + +// $Log: sc_list.cpp,v $ +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:43 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_list.h b/ext/systemc/src/sysc/utils/sc_list.h new file mode 100644 index 000000000..40f4c92af --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_list.h @@ -0,0 +1,188 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_list.h -- Simple implementation of a doubly linked list. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#ifndef SC_LIST_H +#define SC_LIST_H + +namespace sc_core { + +//Some forward declarations +class sc_plist_elem; +template<class T> class sc_plist_iter; + +typedef void (*sc_plist_map_fn)( void* data, void* arg ); + +class sc_plist_base { + friend class sc_plist_base_iter; + +public: + sc_plist_base(); + ~sc_plist_base(); + + typedef sc_plist_elem* handle_t; + + handle_t push_back(void* d); + handle_t push_front(void* d); + void* pop_back(); + void* pop_front(); + handle_t insert_before(handle_t h, void* d); + handle_t insert_after(handle_t h, void* d); + void* remove(handle_t h); + void* get(handle_t h) const; + void set(handle_t h, void* d); + void mapcar( sc_plist_map_fn f, void* arg ); + + void* front() const; + void* back() const; + + void erase_all(); + bool empty() const { return (head == 0); } + int size() const; + +private: + handle_t head; + handle_t tail; +}; + + +class sc_plist_base_iter { +public: + typedef sc_plist_elem* handle_t; + + sc_plist_base_iter( sc_plist_base* l, bool from_tail = false ); + ~sc_plist_base_iter(); + + void reset( sc_plist_base* l, bool from_tail = false ); + bool empty() const; + void operator++(int); + void operator--(int); + void* get() const; + void set(void* d); + void remove(); + void remove(int direction); + + void set_handle(handle_t h); + handle_t get_handle() const { return ptr; } + +private: + sc_plist_base* lst; + sc_plist_elem* ptr; +}; + +/*---------------------------------------------------------------------------*/ + +template< class T > +class sc_plist : public sc_plist_base { + friend class sc_plist_iter <T>; + +public: + typedef sc_plist_iter<T> iterator; + + sc_plist() { } + ~sc_plist() { } + + handle_t push_back(T d) { return sc_plist_base::push_back((void*)d); } + handle_t push_front(T d) { return sc_plist_base::push_front((void*)d); } + T pop_back() { return (T) sc_plist_base::pop_back(); } + T pop_front() { return (T) sc_plist_base::pop_front(); } + handle_t insert_before(handle_t h, T d) + { + return sc_plist_base::insert_before(h, (void*) d); + } + handle_t insert_after(handle_t h, T d) + { + return sc_plist_base::insert_after(h, (void*) d); + } + T remove(handle_t h) + { + return (T)sc_plist_base::remove(h); + } + T get(handle_t h) const { return (T)sc_plist_base::get(h); } + void set(handle_t h, T d) { sc_plist_base::set(h, (void*)d); } + + T front() const { return (T)sc_plist_base::front(); } + T back() const { return (T)sc_plist_base::back(); } +}; + +template< class T > +class sc_plist_iter : public sc_plist_base_iter { +public: + sc_plist_iter( sc_plist<T>* l, bool from_tail = false ) + : sc_plist_base_iter( l, from_tail ) + { + + } + sc_plist_iter( sc_plist<T>& l, bool from_tail = false ) + : sc_plist_base_iter( &l, from_tail ) + { + + } + ~sc_plist_iter() + { + + } + + void reset( sc_plist<T>* l, bool from_tail = false ) + { + sc_plist_base_iter::reset( l, from_tail ); + } + void reset( sc_plist<T>& l, bool from_tail = false ) + { + sc_plist_base_iter::reset( &l, from_tail ); + } + + T operator*() const { return (T) sc_plist_base_iter::get(); } + T get() const { return (T) sc_plist_base_iter::get(); } + void set(T d) { sc_plist_base_iter::set((void*) d); } +}; + +} // namespace sc_core + +// $Log: sc_list.h,v $ +// Revision 1.5 2011/09/01 15:16:50 acg +// Philipp A. Hartmann: revert unnecessary virtual destructors. +// +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_machine.h b/ext/systemc/src/sysc/utils/sc_machine.h new file mode 100644 index 000000000..1939b0c99 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_machine.h @@ -0,0 +1,81 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_machine.h -- Machine-dependent Environment Settings + + Original Author: Andy Goodrich, Forte Design Systems, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#ifndef SC_MACHINE_H +#define SC_MACHINE_H + +#include <climits> +//#include "sysc/packages/boost/detail/endian.hpp" + +// We stripped the boost include and assume a build on x86 +#define SC_BOOST_LITTLE_ENDIAN + +// ---------------------------------------------------------------------------- +// Little or big endian machine? +// ---------------------------------------------------------------------------- + +#if defined( SC_BOOST_LITTLE_ENDIAN ) +# define SC_LITTLE_ENDIAN +#elif defined( SC_BOOST_BIG_ENDIAN ) +# define SC_BIG_ENDIAN +#else +# error "Could not detect the endianness of the CPU." +#endif + +// ---------------------------------------------------------------------------- +// Are long data types 32-bit or 64-bit? +// ---------------------------------------------------------------------------- + +#if ULONG_MAX > 0xffffffffUL +# define SC_LONG_64 +#endif + +// $Log: sc_machine.h,v $ +// Revision 1.5 2011/08/26 22:58:23 acg +// Torsten Maehne: changes for endian detection. +// +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.2 2010/09/06 16:35:09 acg +// Andy Goodrich: changed i386 to __i386__ in ifdef. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif // !defined(SC_MACHINE_H) diff --git a/ext/systemc/src/sysc/utils/sc_mempool.cpp b/ext/systemc/src/sysc/utils/sc_mempool.cpp new file mode 100644 index 000000000..7369c12a0 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_mempool.cpp @@ -0,0 +1,338 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_mempool.cpp - Memory pools for small objects. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + + + +// <sc_mempool> is a class that manages the memory for small objects, +// of sizes <increment>, 2 * <increment>, ..., <num_pools> * +// <increment>. When a memory request of <k> bytes is made through +// the memory pool, the smallest pool <j> such that <j> * <increment> +// >= <k> is used. The default values of <increment> and <num_pools> +// are 8 and 8, respectively. Each pool has an allocator, that +// simply keeps a free list of cells, and allocate new blocks +// whenever necessary. We are relying on malloc() to return a +// properly aligned memory blocks. Note that the memory blocks +// allocated by the mempool are never freed. Thus, if purify is +// used, we may get MIU (memory-in-use) warnings. To disable this, +// set the environment variable SYSTEMC_MEMPOOL_DONT_USE to 1. + + +static const char* dont_use_envstring = "SYSTEMC_MEMPOOL_DONT_USE"; +static bool use_default_new = false; + + +#include <stdio.h> +#include <stdlib.h> // duplicate (c)stdlib.h headers for Solaris +#include <cstdlib> +#include "sysc/utils/sc_mempool.h" + +namespace sc_core { + +// An allocator is one that handles a particular size. It keeps a +// <free_list> from which a cell may be allocated quickly if there +// is one available. If no cell is available from <free_list>, then +// the allocator tries to find whether space is available from the +// most-recently-allocated block, as pointed to by <next_avail>. If +// so, then the cell pointed to by <next_avail> is returned, while +// <next_avail> is advanced. If <next_avail> now points beyond +// the current block, then it's reset to 0. On the other hand, +// if <next_avail> was 0 when a request to the block is made, then +// a new block is allocated by calling system malloc(), and the new +// block becomes the head of <block_list>. + + +class sc_allocator { + friend class sc_mempool; + +public: + sc_allocator( int blksz, int cellsz ); + ~sc_allocator(); + void* allocate(); + void release(void* p); + + void display_statistics(); + +private: + union link { + link* next; + double align; // alignment required. + }; + + int block_size; // size of each block in bytes, + // including the link + int cell_size; // size of each cell in bytes + + char* block_list; + link* free_list; + char* next_avail; + + int total_alloc; + int total_freed; + int free_list_alloc; +}; + +sc_allocator::sc_allocator( int blksz, int cellsz ) + : block_size(sizeof(link) + (((blksz - 1) / cellsz) + 1) * cellsz), + cell_size(cellsz), block_list(0), free_list(0), next_avail(0), + total_alloc(0), total_freed(0), free_list_alloc(0) +{} + +sc_allocator::~sc_allocator() +{ + // Shouldn't free the block_list, since global objects that use + // the memory pool may not have been destroyed yet ... + // Let it leak, let it leak, let it leak ... +} + +void* +sc_allocator::allocate() +{ + void* result = 0; + total_alloc++; + if (free_list != 0) { + free_list_alloc++; + result = free_list; + free_list = free_list->next; + return result; + } + else if (next_avail != 0) { + result = next_avail; + next_avail += cell_size; + // next_avail goes beyond the block + if (next_avail >= block_list + block_size) + next_avail = 0; + return result; + } + else { // (next_avail == 0) + link* new_block = (link*) malloc(block_size); // need alignment? + new_block->next = (link*) block_list; + block_list = (char*) new_block; + result = (block_list + sizeof(link)); + // Assume that the block will hold more than one cell ... why + // wouldn't it? + next_avail = ((char*) result) + cell_size; + return result; + } +} + +void +sc_allocator::release(void* p) +{ + total_freed++; + ((link*) p)->next = free_list; + free_list = (link*) p; +} + +void +sc_allocator::display_statistics() +{ + int nblocks = 0; + for (link* b = (link*) block_list; b != 0; b = b->next) + nblocks++; + printf("size %3d: %2d block(s), %3d requests (%3d from free list), %3d freed.\n", + cell_size, nblocks, total_alloc, free_list_alloc, total_freed); +} + + +static const int cell_sizes[] = { +/* 0 */ 0, +/* 1 */ 8, +/* 2 */ 16, +/* 3 */ 24, +/* 4 */ 32, +/* 5 */ 48, +/* 6 */ 64, +/* 7 */ 80, +/* 8 */ 96, +/* 9 */ 128 +}; + +static const int cell_size_to_allocator[] = { +/* 0 */ 0, +/* 1 */ 1, +/* 2 */ 2, +/* 3 */ 3, +/* 4 */ 4, +/* 5 */ 5, +/* 6 */ 5, +/* 7 */ 6, +/* 8 */ 6, +/* 9 */ 7, +/* 10 */ 7, +/* 11 */ 8, +/* 12 */ 8, +/* 13 */ 9, +/* 14 */ 9, +/* 15 */ 9, +/* 16 */ 9 +}; + + +class sc_mempool_int { + friend class sc_mempool; + +public: + sc_mempool_int(int blksz, int npools, int incr); + ~sc_mempool_int(); + void* do_allocate(std::size_t); + void do_release(void*, std::size_t); + + void display_statistics(); + +private: + sc_allocator** allocators; + int num_pools; + int increment; + int max_size; +}; + + +static bool +compute_use_default_new() +{ + const char* e = getenv(dont_use_envstring); + return (e != 0) && (atoi(e) != 0); +} + +sc_mempool_int::sc_mempool_int(int blksz, int npools, int incr) : + allocators(0), num_pools(0), increment(0), max_size(0) +{ + use_default_new = compute_use_default_new(); + if (! use_default_new) { + num_pools = npools; + increment = incr; + max_size = cell_sizes[sizeof(cell_sizes)/sizeof(cell_sizes[0]) - 1]; + allocators = new sc_allocator*[npools + 1]; + for (int i = 1; i <= npools; ++i) + allocators[i] = new sc_allocator(blksz, cell_sizes[i]); + allocators[0] = allocators[1]; + } +} + +sc_mempool_int::~sc_mempool_int() +{ + for (int i = 1; i <= num_pools; ++i) + delete allocators[i]; + delete[] allocators; +} + +static sc_mempool_int* the_mempool = 0; + +void* +sc_mempool_int::do_allocate(std::size_t sz) +{ + int which_allocator = cell_size_to_allocator[(sz - 1) / increment + 1]; + void* p = allocators[which_allocator]->allocate(); + return p; +} + +void +sc_mempool_int::do_release(void* p, std::size_t sz) +{ + int which_allocator = cell_size_to_allocator[(sz - 1) / increment + 1]; + allocators[which_allocator]->release(p); +} + +void +sc_mempool_int::display_statistics() +{ + printf("*** Memory Pool Statistics ***\n"); + for (int i = 1; i <= num_pools; ++i) + allocators[i]->display_statistics(); +} + +/****************************************************************************/ + +void* +sc_mempool::allocate(std::size_t sz) +{ + if (use_default_new) + return ::operator new(sz); + + if (the_mempool == 0) { + use_default_new = compute_use_default_new(); + if (use_default_new) + return ::operator new(sz); + + // Note that the_mempool is never freed. This is going to cause + // memory leaks when the program exits. + the_mempool = new sc_mempool_int( 1984, sizeof(cell_sizes)/sizeof(cell_sizes[0]) - 1, 8 ); + } + + if (sz > (unsigned) the_mempool->max_size) + return ::operator new(sz); + + return the_mempool->do_allocate(sz); +} + +void +sc_mempool::release(void* p, std::size_t sz) +{ + if (p) { + + if (use_default_new || sz > (unsigned) the_mempool->max_size) { + ::operator delete(p); + return; + } + + the_mempool->do_release(p, sz); + } +} + +void +sc_mempool::display_statistics() +{ + if (the_mempool && !use_default_new) { + the_mempool->display_statistics(); + } else { + printf("SystemC info: no memory allocation was done through the memory pool.\n"); + } +} + +} // namespace sc_core + +// $Log: sc_mempool.cpp,v $ +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:10 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_mempool.h b/ext/systemc/src/sysc/utils/sc_mempool.h new file mode 100644 index 000000000..1c053ae1c --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_mempool.h @@ -0,0 +1,93 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_mempool.h - Memory pools for small objects. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_MEMPOOL_H +#define SC_MEMPOOL_H + + +#include "sysc/utils/sc_iostream.h" + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// CLASS : sc_mempool +// +// ... +// ---------------------------------------------------------------------------- + +class sc_mempool +{ +public: + + static void* allocate( std::size_t sz ); + static void release( void* p, std::size_t sz ); + static void display_statistics(); +}; + + +// ---------------------------------------------------------------------------- +// CLASS : sc_mpobject +// +// ... +// ---------------------------------------------------------------------------- + +class sc_mpobject +{ +public: + + static void* operator new( std::size_t sz ) + { return sc_mempool::allocate( sz ); } + + static void operator delete( void* p, std::size_t sz ) + { sc_mempool::release( p, sz ); } + + static void* operator new[]( std::size_t sz ) + { return sc_mempool::allocate( sz ); } + + static void operator delete[]( void* p, std::size_t sz ) + { sc_mempool::release( p, sz ); } +}; + +} // namespace sc_core + +// $Log: sc_mempool.h,v $ +// Revision 1.3 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_pq.cpp b/ext/systemc/src/sysc/utils/sc_pq.cpp new file mode 100644 index 000000000..d20580ca5 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_pq.cpp @@ -0,0 +1,133 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_pq.cpp - Simple heap implementation of priority queue. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +// $Log: sc_pq.cpp,v $ +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// + +#include "sysc/utils/sc_pq.h" + +namespace sc_core { + +sc_ppq_base::sc_ppq_base( int sz, int (*cmp)( const void*, const void* ) ) + : m_heap(0), m_size_alloc( sz ), m_heap_size( 0 ), m_compar( cmp ) +{ + // m_size_alloc must be at least 2, otherwise resizing doesn't work + if( m_size_alloc < 2 ) { + m_size_alloc = 2; + } + // allocate + m_heap = new void*[m_size_alloc + 1]; + // initialize + for( int i = 0; i < m_size_alloc; ++ i ) { + m_heap[i] = 0; + } +} + +sc_ppq_base::~sc_ppq_base() +{ + delete[] m_heap; +} + +void* +sc_ppq_base::extract_top() +{ + assert( m_heap_size > 0 ); + void* topelem = m_heap[1]; + m_heap[1] = m_heap[m_heap_size]; + m_heap_size --; + heapify( 1 ); + return topelem; +} + +void +sc_ppq_base::insert( void* elem ) +{ + m_heap_size ++; + int i = m_heap_size; + + // resize the heap in case there's not enough memory + if( m_heap_size > m_size_alloc ) { + m_size_alloc += m_size_alloc / 2; + void** new_heap = new void*[m_size_alloc + 1]; + for( int j = 1; j < m_heap_size; ++ j ) { + new_heap[j] = m_heap[j]; + } + delete[] m_heap; + m_heap = new_heap; + } + + while( (i > 1) && (m_compar( m_heap[parent( i )], elem ) < 0) ) { + m_heap[i] = m_heap[parent( i )]; + i = parent( i ); + } + m_heap[i] = elem; +} + +void +sc_ppq_base::heapify( int i ) +{ + int l; + while( l = left( i ), l <= m_heap_size ) { + int largest = (m_compar( m_heap[l], m_heap[i] ) > 0) ? l : i; + + int r = right( i ); + if( (r <= m_heap_size) && + (m_compar( m_heap[r], m_heap[largest] ) > 0) ) { + largest = r; + } + + if( largest != i ) { + void* tmp = m_heap[i]; + m_heap[i] = m_heap[largest]; + m_heap[largest] = tmp; + i = largest; + } else { + break; + } + } +} + +} // namespace sc_core + +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_pq.h b/ext/systemc/src/sysc/utils/sc_pq.h new file mode 100644 index 000000000..51ed54f4a --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_pq.h @@ -0,0 +1,154 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_pq.h -- A simple priority queue (which can be used to model multiple + clocks). From Cormen-Leiserson-Rivest, Ch.7. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_PQ_H +#define SC_PQ_H + + +#include <cassert> + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// CLASS : sc_ppq_base +// +// Priority queue base class. +// ---------------------------------------------------------------------------- + +class sc_ppq_base +{ +public: + + typedef int (*compare_fn_t)( const void*, const void* ); + + sc_ppq_base( int sz, compare_fn_t cmp ); + + ~sc_ppq_base(); + + void* top() const + { return m_heap[1]; } + + void* extract_top(); + + void insert( void* elem ); + + int size() const + { return m_heap_size; } + + bool empty() const + { return (m_heap_size == 0); } + +protected: + + int parent( int i ) const + { return i >> 1; } + + int left( int i ) const + { return i << 1; } + + int right( int i ) const + { return (i << 1) + 1; } + + void heapify( int i ); + +private: + + void** m_heap; + int m_size_alloc; + int m_heap_size; + compare_fn_t m_compar; +}; + + +// ---------------------------------------------------------------------------- +// CLASS TEMPLATE : sc_ppq<T> +// +// This class is a simple implementation of a priority queue based on +// binary heaps. The class is templatized on its data type. A comparison +// function needs to be supplied. +// ---------------------------------------------------------------------------- + +template <class T> +class sc_ppq + : public sc_ppq_base +{ +public: + + // constructor - specify the maximum size of the queue and + // give a comparison function. + + sc_ppq( int sz, compare_fn_t cmp ) + : sc_ppq_base( sz, cmp ) + {} + + ~sc_ppq() + {} + + // returns the value of the top element in the priority queue. + T top() const + { return (T) sc_ppq_base::top(); } + + // pops the first element of the priority queue. + + T extract_top() + { return (T) sc_ppq_base::extract_top(); } + + // insert a new element to the priority queue. + + void insert( T elem ) + { sc_ppq_base::insert( (void*) elem ); } + + // size() and empty() are inherited. +}; + +} // namespace sc_core + +// $Log: sc_pq.h,v $ +// Revision 1.5 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.4 2011/08/26 20:46:18 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_pvector.h b/ext/systemc/src/sysc/utils/sc_pvector.h new file mode 100644 index 000000000..3c0e127c9 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_pvector.h @@ -0,0 +1,187 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_vector.h -- Simple implementation of a vector class. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_VECTOR_H +#define SC_VECTOR_H + +#include <vector> + +namespace sc_core { + +extern "C" { + typedef int (*CFT)( const void*, const void* ); +} + + +// #define ACCESS(I) m_vector.at(I) // index checking +#define ACCESS(I) m_vector[I] +#define ADDR_ACCESS(I) (m_vector.size() != 0 ? &m_vector[I] : 0 ) + +// ---------------------------------------------------------------------------- +// CLASS : sc_pvector<T> +// +// Simple vector class. +// ---------------------------------------------------------------------------- + +template< class T > +class sc_pvector +{ +public: + + typedef const T* const_iterator; + typedef T* iterator; + // typedef typename ::std::vector<T>::const_iterator const_iterator; + // typedef typename ::std::vector<T>::iterator iterator; + + sc_pvector( int alloc_n = 0 ) + { + } + + sc_pvector( const sc_pvector<T>& rhs ) + : m_vector( rhs.m_vector ) + {} + + ~sc_pvector() + {} + + + std::size_t size() const + { return m_vector.size(); } + + + iterator begin() + { return (iterator) ADDR_ACCESS(0); } + + const_iterator begin() const + { return (const_iterator) ADDR_ACCESS(0); } + + iterator end() + { return static_cast<iterator> (ADDR_ACCESS(m_vector.size())); } + + const_iterator end() const + { + return static_cast<const_iterator> (ADDR_ACCESS(m_vector.size())); + } + + + sc_pvector<T>& operator = ( const sc_pvector<T>& rhs ) + { m_vector = rhs.m_vector; return *this; } + + + T& operator [] ( unsigned int i ) + { + if ( i >= m_vector.size() ) m_vector.resize(i+1); + return (T&) m_vector.operator [] ( i ); + } + + const T& operator [] ( unsigned int i ) const + { + if ( i >= m_vector.size() ) m_vector.resize(i+1); + return (const T&) m_vector.operator [] ( i ); + } + + T& fetch( int i ) + { return ACCESS(i); } + + const T& fetch( int i ) const + { return (const T&) ACCESS(i); } + + + T* raw_data() + { return (T*) &ACCESS(0); } + + const T* raw_data() const + { return (const T*) &ACCESS(0); } + + + operator const ::std::vector<T>& () const + { return m_vector; } + + void push_back( T item ) + { m_vector.push_back( item ); } + + + void erase_all() + { m_vector.resize(0); } + + void sort( CFT compar ) + {qsort( (void*)&m_vector[0], m_vector.size(), sizeof(void*), compar );} + + /* These methods have been added from Ptr_Array */ + + void put( T item, int i ) + { ACCESS(i) = item; } + + void decr_count() + { m_vector.resize(m_vector.size()-1); } + + void decr_count( int k ) + { m_vector.resize(m_vector.size()-k); } + + + + protected: + mutable ::std::vector<T> m_vector; // Actual vector of pointers. +}; + +#undef ACCESS +#undef ADDR_ACCESS + +} // namespace sc_core + +// $Log: sc_pvector.h,v $ +// Revision 1.4 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.2 2011/01/20 16:52:21 acg +// Andy Goodrich: changes for IEEE 1666 2011. +// +// Revision 1.1 2010/12/07 20:11:45 acg +// Andy Goodrich: moved sc_pvector class to new header file to allow the +// use of sc_vector.h for Philipp Hartmann's new sc_vector class. +// +// Revision 1.4 2010/08/03 17:52:15 acg +// Andy Goodrich: fix signature for size() method of sc_pvector. +// +// Revision 1.3 2008/10/09 21:20:33 acg +// Andy Goodrich: fixed the way the end() methods calculate their results. +// I had incorrectly cut and pasted code from the begin() method. +// +// Revision 1.2 2007/01/17 22:44:34 acg +// Andy Goodrich: fix for Microsoft compiler. +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_report.cpp b/ext/systemc/src/sysc/utils/sc_report.cpp new file mode 100644 index 000000000..378d45cde --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_report.cpp @@ -0,0 +1,330 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_report.cpp -- Run-time logging and reporting facilities + + Interface design by SystemC Verification Working Group. + Implementation by Alex Riesen, Synopsys Inc. + Original implementation by Martin Janssen, Synopsys Inc. + Reference implementation by Cadence Design Systems, Inc., 2002-09-23: + Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen, + John Pierce, Rachida Kebichi, Ted Elkind, David Bailey. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#include <stdlib.h> +#include <string.h> + +#include "sysc/kernel/sc_process.h" +#include "sysc/kernel/sc_simcontext_int.h" +#include "sysc/utils/sc_stop_here.h" +#include "sysc/utils/sc_report.h" +#include "sysc/utils/sc_utils_ids.h" +#include <algorithm> // std::swap + +namespace sc_core { + + +static void sc_deprecated_report_ids(const char* method) +{ + static bool warn_report_ids_deprecated=true; + if ( warn_report_ids_deprecated ) + { + std::string message; + message = "integer report ids are deprecated, use string values: "; + message += method; + warn_report_ids_deprecated=false; + SC_REPORT_INFO(SC_ID_IEEE_1666_DEPRECATION_, message.c_str()); + } +} + +static char empty_str[] = ""; +static inline char * empty_dup(const char * p) +{ + if ( p && *p ) + { + char* result; + result = (char*)malloc(strlen(p)+1); + strcpy(result, p); + return result; + } + else + { + return empty_str; + } +} + +sc_report::sc_report() +: severity(SC_INFO), + md(0), + msg(empty_dup(0)), + file(empty_dup(0)), + line(0), + timestamp(new sc_time(sc_time_stamp())), + process(0), + m_verbosity_level(SC_MEDIUM), + m_what(empty_dup(0)) +{ +} + +sc_report::sc_report(sc_severity severity_, + const sc_msg_def* md_, + const char* msg_, + const char* file_, + int line_, + int verbosity_level) +: severity(severity_), + md(md_), + msg(empty_dup(msg_)), + file(empty_dup(file_)), + line(line_), + timestamp(new sc_time(sc_time_stamp())), + process(sc_get_current_process_b()), + m_verbosity_level(verbosity_level), + m_what( empty_dup( sc_report_compose_message(*this).c_str() ) ) +{ +} + +sc_report::sc_report(const sc_report& other) +: std::exception(other), + severity(other.severity), + md(other.md), + msg(empty_dup(other.msg)), + file(empty_dup(other.file)), + line(other.line), + timestamp(new sc_time(*other.timestamp)), + process(other.process), + m_verbosity_level(other.m_verbosity_level), + m_what(empty_dup(other.m_what)) +{ +} + +sc_report & sc_report::operator=(const sc_report& other) +{ + sc_report copy(other); + swap( copy ); + return *this; +} + +void +sc_report::swap( sc_report & that ) +{ + using std::swap; + swap( severity, that.severity ); + swap( md, that.md ); + swap( msg, that.msg ); + swap( file, that.file ); + swap( line, that.line ); + swap( timestamp, that.timestamp ); + swap( process, that.process ); + swap( m_verbosity_level, that.m_verbosity_level ); + swap( m_what, that.m_what ); +} + +sc_report::~sc_report() throw() +{ + if ( file != empty_str ) + free(file); + if ( msg != empty_str ) + free(msg); + delete timestamp; + if ( m_what != empty_str ) + free(m_what); +} + +const char * sc_report::get_msg_type() const +{ + return md->msg_type; +} + +// +// backward compatibility with 2.0+ +// + +static bool warnings_are_errors = false; +static const char unknown_id[] = "unknown id"; + +void sc_report_handler::report(sc_severity severity_, + int id_, + const char* msg_, + const char* file_, + int line_ ) +{ + sc_msg_def * md = sc_report_handler::mdlookup(id_); + + if ( !md ) + { + md = sc_report_handler::add_msg_type(unknown_id); + md->id = id_; + } + + if ( severity_ == SC_WARNING && warnings_are_errors ) + severity_ = SC_ERROR; + + sc_actions actions = execute(md, severity_); + sc_report rep(severity_, md, msg_, file_, line_); + + if ( actions & SC_CACHE_REPORT ) + cache_report(rep); + + if ( severity_ == SC_ERROR ) + actions |= SC_THROW; + else if ( severity_ == SC_FATAL ) + actions |= SC_ABORT; + + handler(rep, actions); +} + +void sc_report::register_id( int id, const char* msg ) +{ + sc_deprecated_report_ids("sc_report::register_id()"); + if( id < 0 ) { + SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_, + "invalid report id" ); + } + if( msg == 0 ) { + SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_, + "invalid report message" ); + } + sc_msg_def * md = sc_report_handler::mdlookup(id); + + if ( !md ) + md = sc_report_handler::add_msg_type(msg); + + if ( !md ) { + SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_, + "report_map insertion error" ); + } + + if( md->id != -1 ) { + if( strcmp( msg, md->msg_type ) != 0 ) { + SC_REPORT_ERROR( SC_ID_REGISTER_ID_FAILED_, + "report id already exists" ); + } + return; + } + md->id = id; +} + +const char* sc_report::get_message( int id ) +{ + sc_deprecated_report_ids("sc_report::get_message()"); + sc_msg_def* md = sc_report_handler::mdlookup(id); + + return md ? md->msg_type: unknown_id; +} + +bool sc_report::is_suppressed( int id ) +{ + sc_deprecated_report_ids("sc_report::is_suppressed()"); + sc_msg_def* md = sc_report_handler::mdlookup(id); + + return md ? md->actions == SC_DO_NOTHING: false; // only do-nothing set +} + +void sc_report::suppress_id(int id_, bool suppress) +{ + sc_deprecated_report_ids("sc_report::suppress_id()"); + sc_msg_def* md = sc_report_handler::mdlookup(id_); + + if ( md ) + md->actions = suppress ? SC_DO_NOTHING: SC_UNSPECIFIED; +} + +void sc_report::suppress_infos(bool suppress) +{ + sc_deprecated_report_ids("sc_report::supress_infos"); + sc_report_handler::sev_actions[SC_INFO] = + suppress ? SC_DO_NOTHING: SC_DEFAULT_INFO_ACTIONS; +} + +void sc_report::suppress_warnings(bool suppress) +{ + sc_deprecated_report_ids("sc_report::suppress_warnings"); + sc_report_handler::sev_actions[SC_WARNING] = + suppress ? SC_DO_NOTHING: SC_DEFAULT_WARNING_ACTIONS; +} + +void sc_report::make_warnings_errors(bool flag) +{ + sc_deprecated_report_ids("sc_report::make_warnings_errors"); + warnings_are_errors = flag; +} + +int sc_report::get_id() const +{ + return md->id; +} + +} // namespace sc_core + +// $Log: sc_report.cpp,v $ +// Revision 1.8 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.7 2011/08/26 20:43:01 acg +// Andy Goodrich: +// (1) Replaced strdup with new and strcpy to eliminate issue with the +// Greenhills compiler. +// (2) Moved modification log to the end of the file to eliminate line +// skew when check-ins are done. +// +// Revision 1.6 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.5 2011/05/05 17:46:04 acg +// Philip A. Hartmann: changes in "swap" support. +// +// Revision 1.4 2011/03/23 16:16:48 acg +// Andy Goodrich: finish message verbosity support. +// +// Revision 1.3 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.2 2011/02/01 23:02:05 acg +// Andy Goodrich: IEEE 1666 2011 changes. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.7 2006/03/21 00:00:37 acg +// Andy Goodrich: changed name of sc_get_current_process_base() to be +// sc_get_current_process_b() since its returning an sc_process_b instance. +// +// Revision 1.6 2006/01/25 00:31:27 acg +// Andy Goodrich: Changed over to use a standard message id of +// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages. +// +// Revision 1.5 2006/01/24 22:02:30 acg +// Andy Goodrich: switch deprecated features warnings to use a single message +// id, SC_ID_IEEE_1666_DEPRECATION_. +// +// Revision 1.4 2006/01/24 20:53:41 acg +// Andy Goodrich: added warnings indicating that use of integer ids in reports +// is deprecated. Added tracing/sc_trace_ids.h to message list. +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_report.h b/ext/systemc/src/sysc/utils/sc_report.h new file mode 100644 index 000000000..f76bef71f --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_report.h @@ -0,0 +1,299 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_report.h -- Run-time logging and reporting facilities + + Interface design by SystemC Verification Working Group. + Implementation by Alex Riesen, Synopsys Inc. + Original implementation by Martin Janssen, Synopsys Inc. + Reference implementation by Cadence Design Systems, Inc., 2002-09-23: + Norris Ip, Dean Shea, John Rose, Jasvinder Singh, William Paulsen, + John Pierce, Rachida Kebichi, Ted Elkind, David Bailey. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_REPORT_H +#define SC_REPORT_H 1 + +#include <exception> +#include <string> + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// ENUM : sc_severity +// +// Enumeration of possible exception severity levels +// ---------------------------------------------------------------------------- + +enum sc_severity { + SC_INFO = 0, // informative only + SC_WARNING, // indicates potentially incorrect condition + SC_ERROR, // indicates a definite problem + SC_FATAL, // indicates a problem from which we cannot recover + SC_MAX_SEVERITY +}; + +typedef unsigned sc_actions; + +// ---------------------------------------------------------------------------- +// ENUM : sc_verbosity +// +// Enumeration of message verbosity. +// ---------------------------------------------------------------------------- + + enum sc_verbosity { + SC_NONE = 0, + SC_LOW = 100, + SC_MEDIUM = 200, + SC_HIGH = 300, + SC_FULL = 400, + SC_DEBUG = 500 + }; + +// ---------------------------------------------------------------------------- +// ENUM : +// +// Enumeration of actions on an exception (implementation specific) +// ---------------------------------------------------------------------------- + +enum { + SC_UNSPECIFIED = 0x0000, // look for lower-priority rule + SC_DO_NOTHING = 0x0001, // take no action (ignore if other bits set) + SC_THROW = 0x0002, // throw an exception + SC_LOG = 0x0004, // add report to report log + SC_DISPLAY = 0x0008, // display report to screen + SC_CACHE_REPORT = 0x0010, // save report to cache + SC_INTERRUPT = 0x0020, // call sc_interrupt_here(...) + SC_STOP = 0x0040, // call sc_stop() + SC_ABORT = 0x0080 // call abort() +}; + +class sc_object; +class sc_time; +struct sc_msg_def; +class sc_report; +class sc_report_handler; +const std::string sc_report_compose_message( const sc_report& ); + +// ---------------------------------------------------------------------------- +// CLASS : sc_report +// +// Exception reporting +// ---------------------------------------------------------------------------- + +class sc_report : public std::exception +{ + friend class sc_report_handler; + friend sc_report* sc_handle_exception(); + + sc_report(); // used internally by sc_handle_exception + +public: + + sc_report(const sc_report&); + + sc_report & operator=(const sc_report&); + + virtual ~sc_report() throw(); + + const char * get_msg_type() const; + + const char * get_msg() const + { return msg; } + + sc_severity get_severity() const + { return severity; } + + const char * get_file_name() const + { return file; } + + int get_line_number() const + { return line; } + + const sc_time & get_time() const + { return *timestamp; } + + const char* get_process_name() const; + + int get_verbosity() const { return m_verbosity_level; } + + bool valid () const + { + return process != 0; + } + + virtual const char* what() const throw() + { + return m_what; + } + + void swap( sc_report& ); + +protected: + + sc_report(sc_severity, + const sc_msg_def*, + const char* msg, + const char* file, + int line, + int verbosity_level=SC_MEDIUM); + + sc_severity severity; + const sc_msg_def* md; + char* msg; + char* file; + int line; + sc_time* timestamp; + sc_object* process; + int m_verbosity_level; + char* m_what; + +public: // backward compatibility with 2.0+ + + static const char* get_message(int id); + static bool is_suppressed(int id); + static void make_warnings_errors(bool); + static void register_id(int id, const char* msg); + static void suppress_id(int id, bool); // only for info or warning + static void suppress_infos(bool); + static void suppress_warnings(bool); + + int get_id() const; +}; +typedef std::exception sc_exception; + +#define SC_DEFAULT_INFO_ACTIONS \ + (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY) +#define SC_DEFAULT_WARNING_ACTIONS \ + (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY) +#define SC_DEFAULT_ERROR_ACTIONS \ + (::sc_core::SC_LOG | ::sc_core::SC_CACHE_REPORT | ::sc_core::SC_THROW) +#define SC_DEFAULT_FATAL_ACTIONS \ + (::sc_core::SC_LOG | ::sc_core::SC_DISPLAY | \ + ::sc_core::SC_CACHE_REPORT | ::sc_core::SC_ABORT) + + +// ---------------------------------------------------------------------------- +// Report macros. +// +// Use these macros to report an info, warning, error, or fatal. +// ---------------------------------------------------------------------------- + +#define SC_REPORT_INFO( msg_type, msg ) \ + ::sc_core::sc_report_handler::report( \ + ::sc_core::SC_INFO, msg_type, msg, __FILE__, __LINE__ ) + +#define SC_REPORT_INFO_VERB( msg_type, msg, verbosity ) \ + ::sc_core::sc_report_handler::report( \ + ::sc_core::SC_INFO, msg_type, msg, verbosity, \ + __FILE__ , __LINE__ ) + +#define SC_REPORT_WARNING( msg_type, msg ) \ + ::sc_core::sc_report_handler::report( \ + ::sc_core::SC_WARNING, msg_type, msg, __FILE__, __LINE__ ) + +#define SC_REPORT_ERROR( msg_type, msg ) \ + ::sc_core::sc_report_handler::report( \ + ::sc_core::SC_ERROR, msg_type, msg, __FILE__, __LINE__ ) + +#define SC_REPORT_FATAL( msg_type, msg ) \ + ::sc_core::sc_report_handler::report( \ + ::sc_core::SC_FATAL, msg_type, msg, __FILE__, __LINE__ ) + +// ---------------------------------------------------------------------------- +// MACRO : sc_assert(expr) +// +// Like assert(), but additionally prints the current process name +// and simulation time, if the simulation is running. +// ---------------------------------------------------------------------------- + +#ifdef NDEBUG + +#define sc_assert(expr) \ + ((void) 0) + +#else + +#define sc_assert(expr) \ + ((void)((expr) ? 0 : \ + (SC_REPORT_FATAL( ::sc_core::SC_ID_ASSERTION_FAILED_, #expr ), 0))) + +#endif // NDEBUG + +extern const char SC_ID_UNKNOWN_ERROR_[]; +extern const char SC_ID_WITHOUT_MESSAGE_[]; +extern const char SC_ID_NOT_IMPLEMENTED_[]; +extern const char SC_ID_INTERNAL_ERROR_[]; +extern const char SC_ID_ASSERTION_FAILED_[]; +extern const char SC_ID_OUT_OF_BOUNDS_[]; + +// backward compatibility with 2.0+ +extern const char SC_ID_REGISTER_ID_FAILED_[]; + +} // namespace sc_core + +#include "sysc/utils/sc_report_handler.h" + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: Alex Riesen, Synopsys Inc., Jan 28, 2003 + Description of Modification: Implementation for SytemC 2.1 + + *****************************************************************************/ + +// $Log: sc_report.h,v $ +// Revision 1.8 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.7 2011/05/05 17:46:04 acg +// Philip A. Hartmann: changes in "swap" support. +// +// Revision 1.6 2011/04/19 02:39:44 acg +// Andy Goodrich: set proper name for get_verbosity(). +// +// Revision 1.5 2011/03/23 16:16:48 acg +// Andy Goodrich: finish message verbosity support. +// +// Revision 1.4 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.3 2011/02/01 23:02:05 acg +// Andy Goodrich: IEEE 1666 2011 changes. +// +// Revision 1.2 2008/05/20 20:42:50 acg +// Andy Goodrich: added sc_core namespace prefix for ID value in sc_assert() +// macro. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif // SC_REPORT_H diff --git a/ext/systemc/src/sysc/utils/sc_report_handler.cpp b/ext/systemc/src/sysc/utils/sc_report_handler.cpp new file mode 100644 index 000000000..0de71a18b --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_report_handler.cpp @@ -0,0 +1,799 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_report_handler.cpp - + + Original Author: Alex Riesen, Synopsys, Inc. + see also sc_report.cpp + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#include <cstdio> +#include <stdlib.h> +#include <string.h> + +#include "sysc/utils/sc_iostream.h" +#include "sysc/kernel/sc_process.h" +#include "sysc/kernel/sc_simcontext_int.h" +#include "sysc/utils/sc_stop_here.h" +#include "sysc/utils/sc_report_handler.h" +#include "sysc/utils/sc_report.h" + +namespace std {} + +namespace sc_core { + +int sc_report_handler::verbosity_level = SC_MEDIUM; + +// not documented, but available +const std::string sc_report_compose_message(const sc_report& rep) +{ + static const char * severity_names[] = { + "Info", "Warning", "Error", "Fatal" + }; + std::string str; + + str += severity_names[rep.get_severity()]; + str += ": "; + + if ( rep.get_id() >= 0 ) // backward compatibility with 2.0+ + { + char idstr[64]; + std::sprintf(idstr, "(%c%d) ", + "IWEF"[rep.get_severity()], rep.get_id()); + str += idstr; + } + str += rep.get_msg_type(); + + if( *rep.get_msg() ) + { + str += ": "; + str += rep.get_msg(); + } + if( rep.get_severity() > SC_INFO ) + { + char line_number_str[16]; + str += "\nIn file: "; + str += rep.get_file_name(); + str += ":"; + std::sprintf(line_number_str, "%d", rep.get_line_number()); + str += line_number_str; + sc_simcontext* simc = sc_get_curr_simcontext(); + + if( simc && sc_is_running() ) + { + const char* proc_name = rep.get_process_name(); + + if( proc_name ) + { + str += "\nIn process: "; + str += proc_name; + str += " @ "; + str += rep.get_time().to_string(); + } + } + } + + return str; +} +bool sc_report_close_default_log(); + +static ::std::ofstream* log_stream = 0; +static +struct auto_close_log +{ + ~auto_close_log() + { + sc_report_close_default_log(); + } +} auto_close; + +const char* sc_report::get_process_name() const +{ + return process ? process->name() : 0; +} + + +// +// The official handler of the exception reporting +// + +void sc_report_handler::default_handler(const sc_report& rep, + const sc_actions& actions) +{ + if ( actions & SC_DISPLAY ) + ::std::cout << ::std::endl << sc_report_compose_message(rep) << + ::std::endl; + + if ( (actions & SC_LOG) && get_log_file_name() ) + { + if ( !log_stream ) + log_stream = new ::std::ofstream(get_log_file_name()); // ios::trunc + + *log_stream << rep.get_time() << ": " + << sc_report_compose_message(rep) << ::std::endl; + } + if ( actions & SC_STOP ) + { + sc_stop_here(rep.get_msg_type(), rep.get_severity()); + sc_stop(); + } + if ( actions & SC_INTERRUPT ) + sc_interrupt_here(rep.get_msg_type(), rep.get_severity()); + + if ( actions & SC_ABORT ) + abort(); + + if ( actions & SC_THROW ) { + sc_process_b* proc_p = sc_get_current_process_b(); + if( proc_p && proc_p->is_unwinding() ) + proc_p->clear_unwinding(); + throw rep; + } +} + +// not documented, but available +bool sc_report_close_default_log() +{ + delete log_stream; + sc_report_handler::set_log_file_name(NULL); + + if ( !log_stream ) + return false; + + log_stream = 0; + return true; +} + +int sc_report_handler::get_count(sc_severity severity_) +{ + return sev_call_count[severity_]; +} + +int sc_report_handler::get_count(const char* msg_type_) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + return md->call_count; +} + +int sc_report_handler::get_count(const char* msg_type_, sc_severity severity_) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + return md->sev_call_count[severity_]; +} + + +// +// CLASS: sc_report_handler +// implementation +// + +sc_msg_def * sc_report_handler::mdlookup(const char * msg_type_) +{ + if( !msg_type_ ) // if msg_type is NULL, report unknown error + msg_type_ = SC_ID_UNKNOWN_ERROR_; + + for ( msg_def_items * item = messages; item; item = item->next ) + { + for ( int i = 0; i < item->count; ++i ) + if ( !strcmp(msg_type_, item->md[i].msg_type) ) + return item->md + i; + } + return 0; +} + +// The calculation of actions to be executed +sc_actions sc_report_handler::execute(sc_msg_def* md, sc_severity severity_) +{ + sc_actions actions = md->sev_actions[severity_]; // high prio + + if ( SC_UNSPECIFIED == actions ) // middle prio + actions = md->actions; + + if ( SC_UNSPECIFIED == actions ) // the lowest prio + actions = sev_actions[severity_]; + + actions &= ~suppress_mask; // higher than the high prio + actions |= force_mask; // higher than above, and the limit is the highest + + unsigned * limit = 0; + unsigned * call_count = 0; + + // just increment counters and check for overflow + if ( md->sev_call_count[severity_] < UINT_MAX ) + md->sev_call_count[severity_]++; + if ( md->call_count < UINT_MAX ) + md->call_count++; + if ( sev_call_count[severity_] < UINT_MAX ) + sev_call_count[severity_]++; + + if ( md->limit_mask & (1 << (severity_ + 1)) ) + { + limit = md->sev_limit + severity_; + call_count = md->sev_call_count + severity_; + } + if ( !limit && (md->limit_mask & 1) ) + { + limit = &md->limit; + call_count = &md->call_count; + } + if ( !limit ) + { + limit = sev_limit + severity_; + call_count = sev_call_count + severity_; + } + if ( *limit == 0 ) + { + // stop limit disabled + } + else if ( *limit != UINT_MAX ) + { + if ( *call_count >= *limit ) + actions |= SC_STOP; // force sc_stop() + } + return actions; +} + +void sc_report_handler::report( sc_severity severity_, + const char* msg_type_, + const char* msg_, + int verbosity_, + const char* file_, + int line_ ) +{ + sc_msg_def * md = mdlookup(msg_type_); + + // If the severity of the report is SC_INFO and the specified verbosity + // level is greater than the maximum verbosity level of the simulator then + // return without any action. + + if ( (severity_ == SC_INFO) && (verbosity_ > verbosity_level) ) return; + + // Process the report: + + if ( !md ) + md = add_msg_type(msg_type_); + + sc_actions actions = execute(md, severity_); + sc_report rep(severity_, md, msg_, file_, line_, verbosity_); + + if ( actions & SC_CACHE_REPORT ) + cache_report(rep); + + handler(rep, actions); +} + +void sc_report_handler::report(sc_severity severity_, + const char * msg_type_, + const char * msg_, + const char * file_, + int line_) +{ + sc_msg_def * md = mdlookup(msg_type_); + + // If the severity of the report is SC_INFO and the maximum verbosity + // level is less than SC_MEDIUM return without any action. + + if ( (severity_ == SC_INFO) && (SC_MEDIUM > verbosity_level) ) return; + + // Process the report: + + + if ( !md ) + md = add_msg_type(msg_type_); + + sc_actions actions = execute(md, severity_); + sc_report rep(severity_, md, msg_, file_, line_); + + if ( actions & SC_CACHE_REPORT ) + cache_report(rep); + + handler(rep, actions); +} + +// The following method is never called by the simulator. + +void sc_report_handler::initialize() +{ +#if 0 // actually, i do not know whether we have to reset these. + suppress(); + force(); + set_actions(SC_INFO, SC_DEFAULT_INFO_ACTIONS); + set_actions(SC_WARNING, SC_DEFAULT_WARNING_ACTIONS); + set_actions(SC_ERROR, SC_DEFAULT_ERROR_ACTIONS); + set_actions(SC_FATAL, SC_DEFAULT_FATAL_ACTIONS); +#endif + + sev_call_count[SC_INFO] = 0; + sev_call_count[SC_WARNING] = 0; + sev_call_count[SC_ERROR] = 0; + sev_call_count[SC_FATAL] = 0; + + msg_def_items * items = messages; + + while ( items != &msg_terminator ) + { + for ( int i = 0; i < items->count; ++i ) + { + items->md[i].call_count = 0; + items->md[i].sev_call_count[SC_INFO] = 0; + items->md[i].sev_call_count[SC_WARNING] = 0; + items->md[i].sev_call_count[SC_ERROR] = 0; + items->md[i].sev_call_count[SC_FATAL] = 0; + } + items = items->next; + } + + // PROCESS ANY ENVIRONMENTAL OVERRIDES: + + const char* deprecation_warn = std::getenv("SC_DEPRECATION_WARNINGS"); + if ( (deprecation_warn!=0) && !strcmp(deprecation_warn,"DISABLE") ) + { + set_actions("/IEEE_Std_1666/deprecated", SC_DO_NOTHING); + } +} + +// free the sc_msg_def's allocated by add_msg_type +// (or implicit msg_type registration: set_actions, abort_after) +// clear last_global_report. +void sc_report_handler::release() +{ + delete last_global_report; + last_global_report = 0; + sc_report_close_default_log(); + + msg_def_items * items = messages, * newitems = &msg_terminator; + messages = &msg_terminator; + + while ( items != &msg_terminator ) + { + for ( int i = 0; i < items->count; ++i ) + if ( items->md[i].msg_type == items->md[i].msg_type_data ) + free(items->md[i].msg_type_data); + + msg_def_items * prev = items; + items = items->next; + + if ( prev->allocated ) + { + delete [] prev->md; + delete prev; + } + else + { + prev->next = newitems; + newitems = prev; + } + } + messages = newitems; +} + +sc_msg_def * sc_report_handler::add_msg_type(const char * msg_type_) +{ + sc_msg_def * md = mdlookup(msg_type_); + int msg_type_len; + + if ( md ) + return md; + + msg_def_items * items = new msg_def_items; + + if ( !items ) + return 0; + + items->count = 1; + items->md = new sc_msg_def[items->count]; + + if ( !items->md ) + { + delete items; + return 0; + } + memset(items->md, 0, sizeof(sc_msg_def) * items->count); + msg_type_len = strlen(msg_type_); + if ( msg_type_len > 0 ) + { + items->md->msg_type_data = (char*) malloc(msg_type_len+1); + strcpy( items->md->msg_type_data, msg_type_ ); + items->md->id = -1; // backward compatibility with 2.0+ + } + else + { + delete items->md; + delete items; + return 0; + } + items->md->msg_type = items->md->msg_type_data; + add_static_msg_types(items); + items->allocated = true; + + return items->md; +} + +void sc_report_handler::add_static_msg_types(msg_def_items * items) +{ + items->allocated = false; + items->next = messages; + messages = items; +} + +sc_actions sc_report_handler::set_actions(sc_severity severity_, + sc_actions actions_) +{ + sc_actions old = sev_actions[severity_]; + sev_actions[severity_] = actions_; + return old; +} + +sc_actions sc_report_handler::set_actions(const char * msg_type_, + sc_actions actions_) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + sc_actions old = md->actions; + md->actions = actions_; + + return old; +} + +sc_actions sc_report_handler::set_actions(const char * msg_type_, + sc_severity severity_, + sc_actions actions_) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + sc_actions old = md->sev_actions[severity_]; + md->sev_actions[severity_] = actions_; + + return old; +} + +int sc_report_handler::stop_after(sc_severity severity_, int limit) +{ + int old = sev_limit[severity_]; + + sev_limit[severity_] = limit < 0 ? UINT_MAX: (unsigned) limit; + + return old; +} + +int sc_report_handler::stop_after(const char * msg_type_, int limit) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + int old = md->limit_mask & 1 ? md->limit: UINT_MAX; + + if ( limit < 0 ) + md->limit_mask &= ~1; + else + { + md->limit_mask |= 1; + md->limit = limit; + } + return old; +} + +int sc_report_handler::stop_after(const char * msg_type_, + sc_severity severity_, + int limit) +{ + sc_msg_def * md = mdlookup(msg_type_); + + if ( !md ) + md = add_msg_type(msg_type_); + + int mask = 1 << (severity_ + 1); + int old = md->limit_mask & mask ? md->sev_limit[severity_]: UINT_MAX; + + if ( limit < 0 ) + md->limit_mask &= ~mask; + else + { + md->limit_mask |= mask; + md->sev_limit[severity_] = limit; + } + return old; +} + +sc_actions sc_report_handler::suppress(sc_actions mask) +{ + sc_actions old = suppress_mask; + suppress_mask = mask; + return old; +} + +sc_actions sc_report_handler::suppress() +{ + return suppress(0); +} + +sc_actions sc_report_handler::force(sc_actions mask) +{ + sc_actions old = force_mask; + force_mask = mask; + return old; +} + +sc_actions sc_report_handler::force() +{ + return force(0); +} + +sc_report_handler_proc +sc_report_handler::set_handler(sc_report_handler_proc handler_) +{ + sc_report_handler_proc old = handler; + handler = handler_ ? handler_: &sc_report_handler::default_handler; + return old; +} + +sc_report_handler_proc +sc_report_handler::get_handler() +{ + return handler; +} + +sc_report* sc_report_handler::get_cached_report() +{ + sc_process_b * proc = sc_get_current_process_b(); + + if ( proc ) + return proc->get_last_report(); + + return last_global_report; +} + +void sc_report_handler::clear_cached_report() +{ + sc_process_b * proc = sc_get_current_process_b(); + + if ( proc ) + proc->set_last_report(0); + else + { + delete last_global_report; + last_global_report = 0; + } +} + +sc_actions sc_report_handler::get_new_action_id() +{ + for ( sc_actions p = 1; p; p <<= 1 ) + { + if ( !(p & available_actions) ) // free + { + available_actions |= p; + return p; + } + } + return SC_UNSPECIFIED; +} + +bool sc_report_handler::set_log_file_name(const char* name_) +{ + if ( !name_ ) + { + free(log_file_name); + log_file_name = 0; + return false; + } + if ( log_file_name ) + return false; + + log_file_name = (char*)malloc(strlen(name_)+1); + strcpy(log_file_name, name_); + return true; +} + +const char * sc_report_handler::get_log_file_name() +{ + return log_file_name; +} + +void sc_report_handler::cache_report(const sc_report& rep) +{ + sc_process_b * proc = sc_get_current_process_b(); + if ( proc ) + proc->set_last_report(new sc_report(rep)); + else + { + delete last_global_report; + last_global_report = new sc_report(rep); + } +} + +// +// backward compatibility with 2.0+ +// + +sc_msg_def * sc_report_handler::mdlookup(int id) +{ + for ( msg_def_items * item = messages; item; item = item->next ) + { + for ( int i = 0; i < item->count; ++i ) + if ( id == item->md[i].id ) + return item->md + i; + } + return 0; +} + +int sc_report_handler::get_verbosity_level() { return verbosity_level; } + +int sc_report_handler::set_verbosity_level( int level ) +{ + int result = verbosity_level; + verbosity_level = level; + return result; +} + +// +// CLASS: sc_report_handler +// static variables +// + +sc_actions sc_report_handler::suppress_mask = 0; +sc_actions sc_report_handler::force_mask = 0; + +sc_actions sc_report_handler::sev_actions[SC_MAX_SEVERITY] = +{ + /* info */ SC_DEFAULT_INFO_ACTIONS, + /* warn */ SC_DEFAULT_WARNING_ACTIONS, + /* error */ SC_DEFAULT_ERROR_ACTIONS, + /* fatal */ SC_DEFAULT_FATAL_ACTIONS +}; + +// Note that SC_FATAL has a limit of 1 by default + +sc_actions sc_report_handler::sev_limit[SC_MAX_SEVERITY] = +{ + UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX +}; +sc_actions sc_report_handler::sev_call_count[SC_MAX_SEVERITY] = { 0, 0, 0, 0 }; + +sc_report* sc_report_handler::last_global_report = NULL; +sc_actions sc_report_handler::available_actions = + SC_DO_NOTHING | + SC_THROW | + SC_LOG | + SC_DISPLAY | + SC_CACHE_REPORT | + SC_INTERRUPT | + SC_STOP | + SC_ABORT; + +sc_report_handler_proc sc_report_handler::handler = + &sc_report_handler::default_handler; + +char * sc_report_handler::log_file_name = 0; + +sc_report_handler::msg_def_items * sc_report_handler::messages = + &sc_report_handler::msg_terminator; + + +// +// predefined messages +// + +const char SC_ID_REGISTER_ID_FAILED_[] = "register_id failed"; +const char SC_ID_UNKNOWN_ERROR_[] = "unknown error"; +const char SC_ID_WITHOUT_MESSAGE_[] = ""; +const char SC_ID_NOT_IMPLEMENTED_[] = "not implemented"; +const char SC_ID_INTERNAL_ERROR_[] = "internal error"; +const char SC_ID_ASSERTION_FAILED_[] = "assertion failed"; +const char SC_ID_OUT_OF_BOUNDS_[] = "out of bounds"; + +#define DEFINE_MSG(id,n) \ + { \ + (id), \ + 0u, {0u}, /* actions */ \ + 0u, {0u}, 0u, /* limits */ \ + 0u, {0u}, NULL, /* call counters */ \ + n \ + } + +static sc_msg_def default_msgs[] = { + DEFINE_MSG(SC_ID_REGISTER_ID_FAILED_, 800), + DEFINE_MSG(SC_ID_UNKNOWN_ERROR_, 0), + DEFINE_MSG(SC_ID_WITHOUT_MESSAGE_, 1), + DEFINE_MSG(SC_ID_NOT_IMPLEMENTED_, 2), + DEFINE_MSG(SC_ID_INTERNAL_ERROR_, 3), + DEFINE_MSG(SC_ID_ASSERTION_FAILED_, 4), + DEFINE_MSG(SC_ID_OUT_OF_BOUNDS_, 5) +}; + +sc_report_handler::msg_def_items sc_report_handler::msg_terminator = +{ + default_msgs, + sizeof(default_msgs)/sizeof(*default_msgs), + false, + NULL +}; + +} // namespace sc_core + +// $Log: sc_report_handler.cpp,v $ +// Revision 1.9 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.8 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.7 2011/08/07 19:08:08 acg +// Andy Goodrich: moved logs to end of file so line number synching works +// better between versions. +// +// Revision 1.6 2011/08/07 18:56:03 acg +// Philipp A. Hartmann: added cast to ? : to eliminate clang warning message. +// +// Revision 1.5 2011/03/23 16:16:49 acg +// Andy Goodrich: finish message verbosity support. +// +// Revision 1.4 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.3 2011/02/11 13:25:55 acg +// Andy Goodrich: Philipp's changes for sc_unwind_exception. +// +// Revision 1.2 2011/02/01 23:02:05 acg +// Andy Goodrich: IEEE 1666 2011 changes. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.7 2006/05/26 20:35:52 acg +// Andy Goodrich: removed debug message that should not have been left in. +// +// Revision 1.6 2006/03/21 00:00:37 acg +// Andy Goodrich: changed name of sc_get_current_process_base() to be +// sc_get_current_process_b() since its returning an sc_process_b instance. +// +// Revision 1.5 2006/01/31 21:42:07 acg +// Andy Goodrich: Added checks for SC_DEPRECATED_WARNINGS being defined as +// DISABLED. If so, we turn off the /IEEE_Std_1666/deprecated message group. +// +// Revision 1.4 2006/01/26 21:08:17 acg +// Andy Goodrich: conversion to use sc_is_running instead of deprecated +// sc_simcontext::is_running() +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_report_handler.h b/ext/systemc/src/sysc/utils/sc_report_handler.h new file mode 100644 index 000000000..799985a1f --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_report_handler.h @@ -0,0 +1,197 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_report_handler.h - + + Original Author: Alex Riesen, Synopsys, Inc. + see also sc_report.h + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_REPORT_HANDLER_H +#define SC_REPORT_HANDLER_H + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// STRUCT : sc_msg_def +// +// Exception message definition structure +// ---------------------------------------------------------------------------- + +struct sc_msg_def +{ + const char* msg_type; + sc_actions actions; + sc_actions sev_actions[SC_MAX_SEVERITY]; + unsigned limit; + unsigned sev_limit[SC_MAX_SEVERITY]; + unsigned limit_mask; // 0 - limit, 1..4 - sev_limit + unsigned call_count; + unsigned sev_call_count[SC_MAX_SEVERITY]; + char* msg_type_data; + + int id; // backward compatibility with 2.0+ +}; + +typedef void (* sc_report_handler_proc)(const sc_report&, const sc_actions &); +class sc_report; +extern bool sc_report_close_default_log(); +class sc_report_handler +{ +public: + static void report(sc_severity, + const char* msg_type, + const char* msg, + const char* file, + int line); + + static void report( sc_severity, + const char* msg_type, + const char* msg, + int verbosity, + const char* file, + int line ); + + static sc_actions set_actions(sc_severity, + sc_actions = SC_UNSPECIFIED); + + static sc_actions set_actions(const char * msg_type, + sc_actions = SC_UNSPECIFIED); + + static sc_actions set_actions(const char * msg_type, + sc_severity, + sc_actions = SC_UNSPECIFIED); + + static int stop_after(sc_severity, int limit = -1); + static int stop_after(const char* msg_type, int limit = -1); + static int stop_after(const char* msg_type, sc_severity, int limit = -1); + + static sc_actions suppress(sc_actions); + static sc_actions suppress(); + static sc_actions force(sc_actions); + static sc_actions force(); + + static int get_count(sc_severity severity_); + static int get_count(const char* msg_type_); + static int get_count(const char* msg_type_, sc_severity severity_); + + static int get_verbosity_level(); + static int set_verbosity_level( int level ); + + + static void initialize(); // just reset counters + static void release(); // initialize() needed for reports after it + + static sc_report_handler_proc set_handler(sc_report_handler_proc); + static sc_report_handler_proc get_handler(); + // use set_handler(NULL); to restore default handler + static void default_handler(const sc_report&, const sc_actions&); + + static sc_actions get_new_action_id(); + + static sc_report* get_cached_report(); + static void clear_cached_report(); + + // if filename is NULL, the previous log file name will be removed. + // The provider of a report_handler supposed to handle this. + // Return false if filename is not NULL and filename is already set. + static bool set_log_file_name(const char* filename); + static const char* get_log_file_name(); + +public: // private, actually + + struct msg_def_items + { + sc_msg_def* md; // have to point to sc_msg_def-s + int count; // set to number of items in md[] + bool allocated; // used internally, previous value ignored + msg_def_items* next; // used internally, previous value ignored + }; + + static void add_static_msg_types(msg_def_items *); + static sc_msg_def* add_msg_type(const char * msg_type); + +protected: + + static void cache_report(const sc_report&); + static sc_actions execute(sc_msg_def*, sc_severity); + + static sc_actions suppress_mask; + static sc_actions force_mask; + static sc_actions sev_actions[SC_MAX_SEVERITY]; + static unsigned sev_limit[SC_MAX_SEVERITY]; + static unsigned sev_call_count[SC_MAX_SEVERITY]; + static sc_report* last_global_report; + static sc_actions available_actions; + static char* log_file_name; + static int verbosity_level; + + static msg_def_items* messages; + static msg_def_items msg_terminator; + + static sc_report_handler_proc handler; + + static sc_msg_def* mdlookup(const char* msg_type); + +private: // backward compatibility with 2.0+ + + friend class sc_report; + static sc_msg_def* mdlookup(int id); + +public: + + static void report(sc_severity, + int id, + const char* add_msg, + const char* file, + int line); + +}; + +} // namespace sc_core + +// $Log: sc_report_handler.h,v $ +// Revision 1.5 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.4 2011/03/23 16:16:49 acg +// Andy Goodrich: finish message verbosity support. +// +// Revision 1.3 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.2 2011/02/01 23:02:05 acg +// Andy Goodrich: IEEE 1666 2011 changes. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_stop_here.cpp b/ext/systemc/src/sysc/utils/sc_stop_here.cpp new file mode 100644 index 000000000..614b03dd0 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_stop_here.cpp @@ -0,0 +1,124 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_stop_here.cpp -- Function provided for debugging purposes. + This file is always compiled in debug mode, such that + setting a breakpoint at this function can help locate + the cause of a SystemC error or warning. + + Original Author: Martin Janssen, Synopsys, Inc., 2001-11-14 + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#include "sysc/utils/sc_stop_here.h" + + +namespace sc_core { + +static const char* info_id = 0; +static const char* warning_id = 0; +static const char* error_id = 0; +static const char* fatal_id = 0; + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_interrupt_here +// +// Debugging aid for warning, error, and fatal reports. +// This function *cannot* be inlined. +// ---------------------------------------------------------------------------- + +void +sc_interrupt_here( const char* id, sc_severity severity ) +{ + // you can set a breakpoint at some of the lines below, either to + // interrupt with any severity, or to interrupt with a specific severity + + switch( severity ) { + case SC_INFO: + info_id = id; + break; + case SC_WARNING: + warning_id = id; + break; + case SC_ERROR: + error_id = id; + break; + default: + case SC_FATAL: + fatal_id = id; + break; + } +} + + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_stop_here +// +// Debugging aid for warning, error, and fatal reports. +// This function *cannot* be inlined. +// ---------------------------------------------------------------------------- + +void +sc_stop_here( const char* id, sc_severity severity ) +{ + // you can set a breakpoint at some of the lines below, either to + // stop with any severity, or to stop with a specific severity + + switch( severity ) { + case SC_INFO: + info_id = id; + break; + case SC_WARNING: + warning_id = id; + break; + case SC_ERROR: + error_id = id; + break; + default: + case SC_FATAL: + fatal_id = id; + break; + } +} + +} // namespace sc_core + +// $Log: sc_stop_here.cpp,v $ +// Revision 1.4 2011/08/26 21:49:08 acg +// Philipp A. Hartmann: eliminate compiler warning by moving static variables +// out of functions. +// +// Revision 1.3 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_stop_here.h b/ext/systemc/src/sysc/utils/sc_stop_here.h new file mode 100644 index 000000000..8d8dca412 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_stop_here.h @@ -0,0 +1,82 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_stop_here.h -- Function provided for debugging purposes. + This file is always compiled in debug mode, such that + setting a breakpoint at this function can help locate + the cause of a SystemC error or warning. + + Original Author: Martin Janssen, Synopsys, Inc., 2001-11-14 + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +// $Log: sc_stop_here.h,v $ +// Revision 1.3 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +#ifndef SC_STOP_HERE_H +#define SC_STOP_HERE_H + + +#include "sysc/utils/sc_report.h" + + +namespace sc_core { + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_interrupt_here +// +// Debugging aid for interrupt warning, error, and fatal reports. +// ---------------------------------------------------------------------------- + +extern +void +sc_interrupt_here( const char* id, sc_severity severity ); + + +// ---------------------------------------------------------------------------- +// FUNCTION : sc_stop_here +// +// Debugging aid for warning, error, and fatal reports. +// ---------------------------------------------------------------------------- + +extern +void +sc_stop_here( const char* id, sc_severity severity ); + +} // namespace sc_core + +#endif + +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_string.cpp b/ext/systemc/src/sysc/utils/sc_string.cpp new file mode 100644 index 000000000..25c788a59 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_string.cpp @@ -0,0 +1,612 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_string.cpp -- Implementation of a simple string class. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#include <assert.h> +#include <ctype.h> +#include <cstdio> +#include <stdarg.h> +#include <string.h> + +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_string.h" +#include "sysc/utils/sc_utils_ids.h" + +namespace sc_dt { + +inline static int +sc_roundup( int n, int m ) +{ + return ((n - 1) / m + 1) * m; +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_string_rep +// +// Reference counting string implementation class. +// ---------------------------------------------------------------------------- + +class sc_string_rep +{ + friend class sc_string_old; + friend ::std::ostream& operator<<( ::std::ostream&, const sc_string_old& ); + friend ::std::istream& operator>>( ::std::istream&, sc_string_old& ); + friend sc_string_old operator+( const char*, const sc_string_old& ); + + sc_string_rep( int size = 16 ) : + ref_count(1), alloc( sc_roundup( size, 16 ) ), str( new char[alloc] ) + { + *str = '\0'; + } + + sc_string_rep( const char* s ) : ref_count(1), alloc(0), str(0) + { + if (s) { + alloc = 1 + strlen(s); + str = strcpy( new char[alloc], s ); + } + else { + alloc = 16; + str = strcpy( new char[alloc], "" ); + } + } + + sc_string_rep( const char* s, int n); // get first n chars from the string + + ~sc_string_rep() + { + assert( ref_count == 0 ); + delete[] str; + } + + void resize( int new_size ); + void set_string( const char* s ); + + int ref_count; + int alloc; + char* str; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +sc_string_rep::sc_string_rep( const char* s, int n) : + ref_count(1), alloc(0), str(0) +{ + if (s && n>0) { + alloc = 1 + n; + str = strncpy( new char[alloc], s,n ); + str[n] = 00; + } + else { + alloc = 16; + str = strcpy( new char[alloc], "" ); + } +} + +void +sc_string_rep::resize( int new_size ) +{ + if (new_size <= alloc) return; + alloc = sc_roundup( new_size, 16 ); + char* new_str = strcpy( new char[alloc], str ); + delete[] str; + str = new_str; +} + +void +sc_string_rep::set_string( const char* s ) +{ + int len = strlen(s); + resize( len + 1 ); + strcpy( str, s ); +} + + +// ---------------------------------------------------------------------------- +// CLASS : sc_string_old +// +// String class (yet another). +// ---------------------------------------------------------------------------- + +// constructors + +sc_string_old::sc_string_old( int size ) : rep( new sc_string_rep(size) ) +{ +} + +sc_string_old::sc_string_old( const char* s ) : rep( new sc_string_rep(s) ) +{ +} + +sc_string_old::sc_string_old( const char* s, int n ) : + rep( new sc_string_rep( s, n ) ) +{ +} + +sc_string_old::sc_string_old( const sc_string_old& s ) : rep( s.rep ) +{ + rep->ref_count ++; +} + +sc_string_old::sc_string_old( sc_string_rep* r ) : rep(r) +{ +} + + +// destructor + +sc_string_old::~sc_string_old() +{ + if( -- (rep->ref_count) == 0 ) { + delete rep; + } +} + + +int +sc_string_old::length() const +{ + return strlen(rep->str); +} + +sc_string_old +sc_string_old::operator+( const char* s ) const +{ + int len = length(); + sc_string_rep* r = new sc_string_rep( len + strlen(s) + 1 ); + strcpy( r->str, rep->str ); + strcpy( r->str + len, s ); + return sc_string_old(r); +} + +sc_string_old sc_string_old::operator+(char c) const +{ + int len = length(); + sc_string_rep* r = new sc_string_rep( len + 2 ); + strcpy( r->str, rep->str ); + r->str[len] = c; + r->str[len+1] = 00; + return sc_string_old(r); +} + +sc_string_old +operator+( const char* s, const sc_string_old& t ) +{ + int len = strlen(s); + sc_string_rep* r = new sc_string_rep( len + t.length() + 1 ); + strcpy( r->str, s ); + strcpy( r->str + len, t ); + return sc_string_old(r); +} + +sc_string_old +sc_string_old::operator+( const sc_string_old& s ) const +{ + int len = length(); + sc_string_rep* r = new sc_string_rep( len + s.length() + 1 ); + strcpy( r->str, rep->str ); + strcpy( r->str + len, s.rep->str ); + return sc_string_old(r); +} + +sc_string_old& +sc_string_old::operator=( const char* s ) +{ + if (rep->ref_count > 1) { + --rep->ref_count; + rep = new sc_string_rep(s); + } + else { + rep->set_string(s); + } + return *this; +} + +sc_string_old& +sc_string_old::operator=( const sc_string_old& s ) +{ + if (&s == this) + return *this; + if (--(rep->ref_count) == 0) + delete rep; + rep = s.rep; + rep->ref_count++; + return *this; +} + +sc_string_old& +sc_string_old::operator+=( const char* s ) +{ + int oldlen = length(); + int slen = strlen(s); + if (rep->ref_count > 1) { + sc_string_rep* oldrep = rep; + --rep->ref_count; + rep = new sc_string_rep( oldlen + slen + 1 ); + strcpy( rep->str, oldrep->str ); + strcpy( rep->str + oldlen, s ); + } + else { + rep->resize( oldlen + slen + 1 ); + strcpy( rep->str + oldlen, s ); + } + return *this; +} + +sc_string_old& sc_string_old::operator+=(char c) +{ + int oldlen = length(); + if (rep->ref_count > 1) { + sc_string_rep* oldrep = rep; + --rep->ref_count; + rep = new sc_string_rep( oldlen + 2 ); + strcpy( rep->str, oldrep->str ); + rep->str[oldlen]=c; + rep->str[oldlen+1]=00; + } + else { + rep->resize( oldlen + 2 ); + rep->str[oldlen]=c; + rep->str[oldlen+1]=00; + } + return *this; +} + +sc_string_old& +sc_string_old::operator+=( const sc_string_old& s ) +{ + return this->operator+=( s.rep->str ); +} + +int +sc_string_old::cmp( const char* s ) const +{ + return strcmp( rep->str, s ); +} + +int +sc_string_old::cmp( const sc_string_old& s ) const +{ + return strcmp( rep->str, s.rep->str ); +} + +const char* sc_string_old::c_str() const +{ + return rep->str; +} + +// get substring +sc_string_old sc_string_old::substr(int first,int last) const +{ + if(first<0 || last<0 || first>last || first>=length() || last>=length()) + return ""; + return sc_string_old(rep->str+first, last-first+1); +} + + +sc_string_old sc_string_old::make_str(long n) // convert integer to string +{ + char buf[32]; + ::std::sprintf(buf,"%ld",n); + return sc_string_old(buf); +} + + +#define DEFINE_RELOP(op) \ +bool sc_string_old::operator op( const char* s ) const \ +{ \ + return strcmp( rep->str, s ) op 0; \ +} \ +bool sc_string_old::operator op( const sc_string_old& s ) const \ +{ \ + return strcmp( rep->str, s.rep->str ) op 0; \ +} + +DEFINE_RELOP(==) +DEFINE_RELOP(!=) +DEFINE_RELOP(<) +DEFINE_RELOP(<=) +DEFINE_RELOP(>) +DEFINE_RELOP(>=) + +sc_string_old::operator const char*() const +{ + return rep->str; +} + +char +sc_string_old::operator[]( int i ) const +{ + return rep->str[i]; +} + +char& sc_string_old::operator[]( int i ) +{ + if (rep->ref_count > 1) { + rep->ref_count--; + rep = new sc_string_rep(rep->str); + } + return rep->str[i]; +} + +void +sc_string_old::set( int i, char c ) +{ + if (rep->ref_count > 1) { + rep->ref_count--; + rep = new sc_string_rep(rep->str); + } + rep->str[i] = c; +} + +#if defined(_MSC_VER) + // Windows provides safer implementation +# define sc_vsnprintf _vsnprintf +#else +# define sc_vsnprintf vsnprintf +#endif + +sc_string_old sc_string_old::to_string(const char* format, ...) +{ + va_list argptr; + sc_string_old result; + char buffer[1024]; // static string buffer + buffer[1023]=000; + + va_start(argptr, format); + int cnt = sc_vsnprintf(buffer, 1024, format, argptr); + if(cnt>1023) // string too long + { + int buf_size = 1024; + const int max_size = 65000; + char* buf = 0; // dynamic string buffer + do + { + delete[] buf; + buf_size*=2; + buf = new char[buf_size]; + cnt = sc_vsnprintf(buf, buf_size, format, argptr); + } + while( buf_size<max_size && cnt>=buf_size); + if(cnt>=buf_size) + { + // string is longer the the maximum buffer size (max_size) + SC_REPORT_WARNING( sc_core::SC_ID_STRING_TOO_LONG_, "truncated" ); + buf[buf_size-1] = 000; + } + result = buf; + delete[] buf; + } + else + result = buffer; + + va_end(argptr); + + return result; +} + +void +sc_string_old::print( ::std::ostream& os ) const +{ + os << rep->str; +} + +void sc_string_old::test(int position)const +{ + if(position<0 || position>=length()) + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::test" ); +} + +// TODO: conveniece formatting functions for common types +// e.g. sc_string_old("a=%d, s is %s").fmt(1).fmt("string") +// should produce a=1, s is string +// it should be safe: if less arguments specified +// it should print %specifier; extra arguments should be ignored +// if the type of the argument is incompatible with format +// specifier it should be ignored +// + +unsigned +sc_string_old::fmt_length()const +{ + unsigned result=0; + if((*this)[0]!='%') + return 0; + else + result++; + if(is_delimiter("-+0 #",result)) // flags + result++; + while(is_delimiter("0123456789*",result)) // width + result++; + if(rep->str[result]=='.') // precision + { + result++; + unsigned old_result = result; + while(is_delimiter("0123456789*",result)) result++; + if(old_result == result) //error in format + return 0; + } + if(is_delimiter("hlL",result)) result++; // I64 is not supported + if(is_delimiter("cCdiouxXeEfgGnpsS",result)) + result++; + else // error in format + return 0; + return result; +} + +sc_string_old& +sc_string_old::fmt(const sc_string_old& s) +{ + return fmt(s.c_str()); +} + +int +sc_string_old::pos( const sc_string_old& sub_string ) const +{ + int sub_len = sub_string.length(); + if( sub_len == 0 ) { + return 0; // empty string always matches + } + int ind = 0; + int len = length(); + bool found = false; + while( ind < len && ! found ) + { + found = ( sub_string == substr( ind, ind + sub_len - 1 ) ); + ++ ind; + } + if( found ) { + return -- ind; + } else { + return -1; + } +} + +sc_string_old& +sc_string_old::remove(unsigned index, unsigned length) +{ + test((int)index); + if(length!=0) + (*this) = substr(0,index-1) + substr(index+length,this->length()-1); + return *this; +} + +sc_string_old& +sc_string_old::insert(const sc_string_old& sub_string, unsigned index) +{ + if(index>(unsigned)length()) + SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, "sc_string_old::insert" ); + return (*this) = substr(0,index-1)+sub_string+substr(index,length()-1); +} + +bool +sc_string_old::is_delimiter(const sc_string_old& str, unsigned index)const +{ + test((int)index); + return str.contains(rep->str[index]); +} + +bool +sc_string_old::contains(char c)const +{ + int len = length(); + int i=0; + bool found = false; + while(!found && i<len) + found = rep->str[i++]==c; + return found; +} + +sc_string_old +sc_string_old::uppercase()const +{ + int len = length(); + sc_string_old temp(*this); + for(int i=0; i<len; i++) + { + char c = temp.rep->str[i]; + if(c>='a' && c<='z') + temp.rep->str[i] = static_cast<char>( c-32 ); + } + return temp; +} + +sc_string_old +sc_string_old::lowercase()const +{ + int len = length(); + sc_string_old temp(*this); + for(int i=0; i<len; i++) + { + char c = temp.rep->str[i]; + if(c>='A' && c<='Z') + temp.rep->str[i] = static_cast<char>( c+32 ); + } + return temp; +} + + +// ---------------------------------------------------------------------------- + +::std::istream& +operator >> ( ::std::istream& is, sc_string_old& s ) +{ + if( s.rep->ref_count > 1 ) { + -- s.rep->ref_count; + s.rep = new sc_string_rep; + } + + int i = 0; + char* p = s.rep->str; + char c; + + // skip white spaces + while( is.get( c ) && isspace( c ) ) + ; + + for( ; is.good() && ! isspace( c ); is.get( c ) ) { + if( i > s.rep->alloc - 2 ) { + s.rep->str[i] = '\0'; + s.rep->resize( (int) (s.rep->alloc * 1.5) ); + p = s.rep->str + i; + } + *p ++ = c; + i ++; + } + *p = '\0'; + + return is; +} + } // namespace sc_dt + +// $Log: sc_string.cpp,v $ +// Revision 1.6 2011/08/29 18:04:32 acg +// Philipp A. Hartmann: miscellaneous clean ups. +// +// Revision 1.5 2011/08/26 22:49:42 acg +// Torsten Maehne: remove redudant assignment. +// +// Revision 1.4 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// taf diff --git a/ext/systemc/src/sysc/utils/sc_string.h b/ext/systemc/src/sysc/utils/sc_string.h new file mode 100644 index 000000000..cf225ef1e --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_string.h @@ -0,0 +1,254 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_string.h -- Implementation of a simple string class. + + Original Author: Stan Y. Liao, Synopsys, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +// $Log: sc_string.h,v $ +// Revision 1.3 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +#ifndef SC_STRING_H +#define SC_STRING_H + + +#include "sysc/utils/sc_iostream.h" +#include "sysc/utils/sc_report.h" + +namespace sc_dt { + class sc_string_old; +} + +#ifdef SC_USE_SC_STRING_OLD + typedef sc_dt::sc_string_old sc_string; +#endif +#ifdef SC_USE_STD_STRING + typedef ::std::string sc_string; +#endif + +namespace sc_dt { + +// forward class declarations +class sc_string_rep; + +// friend operator declarations +sc_string_old operator + ( const char* s, const sc_string_old& t ); + + +// ---------------------------------------------------------------------------- +// CLASS : sc_string +// +// String class (yet another). +// ---------------------------------------------------------------------------- + +class sc_string_old +{ + friend systemc_ostream& operator << (systemc_ostream& os, const sc_string_old& a); + friend systemc_istream& operator >> ( systemc_istream& is, sc_string_old& a ); + +public: + + // constructors + + explicit sc_string_old( int size = 16 ); + sc_string_old( const char* s ); + sc_string_old( const char* s, int n ); // get first n chars from the string + sc_string_old( const sc_string_old& s ); + + + // destructor + + ~sc_string_old(); + + + // concatenation and assignment + + sc_string_old& operator = ( const char* s ); + sc_string_old& operator = ( const sc_string_old& s ); + + sc_string_old& operator += ( const char* s ); + sc_string_old& operator += ( char c ); + sc_string_old& operator += ( const sc_string_old& s ); + + sc_string_old operator + ( const char* s ) const; + sc_string_old operator + ( char c ) const; + sc_string_old operator + ( const sc_string_old& s ) const; + + friend sc_string_old operator + ( const char* s, const sc_string_old& t ); + + + // returns substring [first,last] + + sc_string_old substr( int first, int last ) const; + + + // string comparison operators + + bool operator == ( const char* s ) const; + bool operator != ( const char* s ) const; + bool operator < ( const char* s ) const; + bool operator <= ( const char* s ) const; + bool operator > ( const char* s ) const; + bool operator >= ( const char* s ) const; + bool operator == ( const sc_string_old& s ) const; + bool operator != ( const sc_string_old& s ) const; + bool operator < ( const sc_string_old& s ) const; + bool operator <= ( const sc_string_old& s ) const; + bool operator > ( const sc_string_old& s ) const; + bool operator >= ( const sc_string_old& s ) const; + + // + // returns length of the string (excluding trailing \0) + // + int length() const; + + // + // returns c-style string + // + const char* c_str() const; + // + // returns c-style string + // + operator const char*() const; + // + // returns character at "index" position + // + char operator[](int index) const; + // + // l-value subscript + // + char& operator[](int index); + + // formatted string (see printf description) + static sc_string_old to_string(const char* format, ...); + // + // conveniece formatting functions for common types + // e.g. sc_string_old("a=%d, s is %s").fmt(1).fmt("string") + // should produce: a=1, s is string + // it should be safe: if less arguments specified + // it should print %specifier; extra arguments should be ignored + // TODO: if the type of the argument is incompatible with format + // specifier it should be ignored + // + // must have it inlined because of some compilers + template<class T> sc_string_old& fmt(const T& t) + { + // search % + int index; + int last_char = length()-1; + sc_string_old temp(*this); + do + { + index = temp.pos("%"); + if(index == last_char) + return *this; + temp = substr(index,last_char); + } while(temp[0] != '%'); + int f_len = (int)temp.fmt_length(); // length of format field + temp = to_string(substr(0,index+f_len-1).c_str(),t); + return (*this) = temp + substr(index+f_len,last_char); + } + sc_string_old& fmt(const sc_string_old& s); + // + // find position of substring in this string + // returns -1 if not found + // + int pos(const sc_string_old& sub_string)const; + // + // remove "count" characters from "index" + // + sc_string_old& remove(unsigned index, unsigned length); + // + // insert "substring" before "index" + // + sc_string_old& insert(const sc_string_old& sub_string, unsigned index); + // + // returns true if the character at byte index in this string matches + // any character in the delimiters string + // + bool is_delimiter(const sc_string_old& str, unsigned index)const; + // + // returns true if string contains the character + // + bool contains(char c)const; + // + // produce upper case string from this one + // + sc_string_old uppercase()const; + // + // produce lower case string from this one + // + sc_string_old lowercase()const; + // + // legacy methods + // + static sc_string_old make_str(long n); + void set( int index, char c ); + int cmp( const char* s ) const; + int cmp( const sc_string_old& s ) const; + + + void print( systemc_ostream& os = ::std::cout ) const; + +private: + + sc_string_old( sc_string_rep* r ); + + sc_string_rep* rep; + + void test(int position)const; + unsigned fmt_length()const; +}; + + +// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII + +inline +systemc_ostream& +operator << ( systemc_ostream& os, const sc_string_old& a ) +{ + a.print( os ); + return os; +} + +} // namespace sc_dt + +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.4 2006/05/08 17:50:51 acg +// Andy Goodrich: added David Long's forward declarations for friend +// functions, methods, and operators to keep the Microsoft compiler happy. +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif diff --git a/ext/systemc/src/sysc/utils/sc_temporary.h b/ext/systemc/src/sysc/utils/sc_temporary.h new file mode 100644 index 000000000..321994aad --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_temporary.h @@ -0,0 +1,228 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_temporary.h -- Temporary value pool classes. + + Original Author: Andy Goodrich, Forte Design Systems, Inc. + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_TEMPORARY_H +#define SC_TEMPORARY_H + +#include <cstddef> // std::size_t + +namespace sc_core { + +//------------------------------------------------------------------------------ +// sc_byte_heap - CLASS MANAGING A TEMPORARY HEAP OF BYTES +// +// This facility implements a heap of temporary byte allocations. Once an +// request has been allocated it is not freed. However the entire heap +// wraps and the storage is reused. This means that no allocations should +// be assumed as permanent. Allocations are double-word aligned. This is +// raw storage, so objects which contain virtual methods cannot be allocated +// with this object. See the sc_vpool object for that type of storage +// allocation. +// +// char* allocate( int size ) +// This method returns a pointer to block of size bytes. The block +// returned is the next available one in the heap. If the current heap +// cannot fullfil the request it will be rewound and storage allocated from +// its start. All allocations start on an 8-byte boundary. +// size = number of bytes to be allocated. +// +// void initialize( int heap_size=0x100000 ) +// This method allocates the storage to be managed. If there is already +// a block of storage under management it is freed. If no argument is +// provided for the heap size, a megabyte will be allocated. +// heap_size = number of bytes to allocate for the heap. +// +// unsigned int length() +// This method returns the size of this object's heap in bytes. +// +// sc_byte_heap() +// This is the non-initialized object instance constructor. It does not +// allocate the heap storage, that is done by the initialize() method. +// +// sc_byte_heap(int) +// This is the initializing object instance constructor. It does allocates +// a heap of the specified number of bytes. +// heap_size = number of bytes to allocate for the heap. +//------------------------------------------------------------------------------ +class sc_byte_heap { + public: + char* m_bgn_p; // Beginning of heap storage. + char* m_end_p; // End of heap storage. + char* m_next_p; // Next heap location to be allocated. + + inline char* allocate( std::size_t bytes_n ) + { + char* result_p; + bytes_n = (bytes_n + 7) & ((std::size_t)(-8)); + result_p = m_next_p; + m_next_p += bytes_n; + if ( m_next_p >= m_end_p ) + { + result_p = m_bgn_p; + m_next_p = m_bgn_p + bytes_n; + } + return result_p; + } + + inline void initialize( std::size_t heap_size=0x100000 ) + { + delete [] m_bgn_p; + m_bgn_p = new char[heap_size]; + m_end_p = &m_bgn_p[heap_size]; + m_next_p = m_bgn_p; + } + + inline std::size_t length() + { + return (std::size_t)(m_end_p - m_bgn_p); + } + + inline sc_byte_heap() : + m_bgn_p(0), m_end_p(0), m_next_p(0) + { + } + + inline sc_byte_heap( std::size_t heap_size ) : + m_bgn_p(0), m_end_p(0), m_next_p(0) + { + initialize( heap_size ); + } + + inline ~sc_byte_heap() + { + delete [] m_bgn_p; + } + +}; + + +//------------------------------------------------------------------------------ +// sc_vpool<T> - CLASS MANAGING A TEMPORARY VECTOR OF CLASS T INSTANCES +// +// This class implements a fixed pool of objects contained in a vector. These +// objects are allocated via the allocate() method. An index, m_pool_i, +// indicates the next object to be allocated. The vector is a power of 2 in +// size, and this fact is used to wrap the list when m_pool_i reaches the +// end of the vector. +// +// sc_vpool( int log2, T* pool_p=0 ) +// This is the object instance constructor for this class. It configures +// the object to manage a vector of 2**log2 entries. If a vector is +// not supplied one will be allocated. +// log2 = the log base two of the size of the vector. +// pool_p -> vector of 2**log2 entries to be managed or 0. +// +// ~sc_vpool() +// This is the object instance destructor for this class. It frees the +// block of storage which was being managed. +// +// T* allocate() +// This method returns the address of the next entry in the vector, m_pool_p, +// pointed to by the index, m_pool_i, and updates that index. The index +// update consists of adding 1 to m_pool_i and masking it by m_wrap. +// +// void reset() +// This method resets the allocation index, m_pool_i, to point to the start +// of the vector of objects under management. This call is not usually made +// since there are a fixed number of entries and the index wraps. However, +// for diagnostics tests it is convenient to be able to reset to the start +// of the vector. +// +// int size() +// This method returns the number of object instances contained in the +// vector being managed by this object instance. +//------------------------------------------------------------------------------ +template<class T> +class sc_vpool { + protected: + std::size_t m_pool_i; // Index of next entry to m_pool_m to provide. + T* m_pool_p; // Vector of temporaries. + std::size_t m_wrap; // Mask to wrap vector index. + + public: + inline sc_vpool( int log2, T* pool_p=0 ); + inline ~sc_vpool(); + inline T* allocate(); + inline void reset(); + inline std::size_t size(); +}; + +template<class T> sc_vpool<T>::sc_vpool( int log2, T* pool_p ) + : m_pool_i( 0 ) + , m_pool_p( pool_p ? pool_p : new T[static_cast<std::size_t>(1) << log2] ) + , m_wrap( ~(static_cast<std::size_t>(-1) << log2) ) +{ + // if ( log2 > 32 ) SC_REPORT_ERROR(SC_ID_POOL_SIZE_, ""); +} + +template<class T> sc_vpool<T>::~sc_vpool() +{ + // delete [] m_pool_p; +} + +template<class T> T* sc_vpool<T>::allocate() +{ + T* result_p; // Entry to return. + + result_p = &m_pool_p[m_pool_i]; + m_pool_i = (m_pool_i + 1) & m_wrap; + return result_p; +} + +template<class T> void sc_vpool<T>::reset() +{ + m_pool_i = 0; +} + +template<class T> std::size_t sc_vpool<T>::size() +{ + return m_wrap + 1; +} + +} // namespace sc_core + +// $Log: sc_temporary.h,v $ +// Revision 1.4 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.3 2011/08/24 22:05:56 acg +// Torsten Maehne: initialization changes to remove warnings. +// +// Revision 1.2 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif // SC_TEMPORARY_H diff --git a/ext/systemc/src/sysc/utils/sc_utils_ids.cpp b/ext/systemc/src/sysc/utils/sc_utils_ids.cpp new file mode 100644 index 000000000..3492692b3 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_utils_ids.cpp @@ -0,0 +1,147 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_utils_ids.cpp -- Report ids for the utils code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#include <cstdlib> +#include <cstring> + +#include "sysc/utils/sc_report.h" + + +namespace sc_core { +#define SC_DEFINE_MESSAGE(id,unused,text) extern const char id[] = text; +#include "sysc/utils/sc_utils_ids.h" +#include "sysc/kernel/sc_kernel_ids.h" +#include "sysc/communication/sc_communication_ids.h" +#include "sysc/datatypes/bit/sc_bit_ids.h" +#include "sysc/datatypes/fx/sc_fx_ids.h" +#include "sysc/datatypes/int/sc_int_ids.h" +#include "sysc/tracing/sc_tracing_ids.h" +#undef SC_DEFINE_MESSAGE + + +static sc_msg_def texts[] = { +#define SC_DEFINE_MESSAGE(id,n,unused) \ + { (id), 0u, {0u}, 0u, {0u}, 0u, 0u, {0u}, 0, n }, + +#undef SC_UTILS_IDS_H +#include "sysc/utils/sc_utils_ids.h" + +#undef SC_KERNEL_IDS_H +#include "sysc/kernel/sc_kernel_ids.h" + +#undef SC_COMMUNICATION_IDS_H +#include "sysc/communication/sc_communication_ids.h" + +#undef SC_BIT_IDS_H +#include "sysc/datatypes/bit/sc_bit_ids.h" + +#undef SC_FX_IDS_H +#include "sysc/datatypes/fx/sc_fx_ids.h" + +#undef SC_INT_IDS_H +#include "sysc/datatypes/int/sc_int_ids.h" + +#undef SC_TRACING_IDS_H +#include "sysc/tracing/sc_tracing_ids.h" + +#undef SC_DEFINE_MESSAGE +}; +static sc_report_handler::msg_def_items items = { + texts, sizeof(texts)/sizeof(*texts), false, 0 +}; + +static +int initialize() +{ + sc_report_handler::add_static_msg_types(&items); + + // PROCESS ANY ENVIRONMENTAL OVERRIDES: + + const char* deprecation_warn = std::getenv("SC_DEPRECATION_WARNINGS"); + if ( (deprecation_warn!=0) && !std::strcmp(deprecation_warn,"DISABLE") ) + { + sc_report_handler::set_actions( SC_ID_IEEE_1666_DEPRECATION_ + , SC_DO_NOTHING); + } + return 42; +} + +static int forty_two = initialize(); + +} // namespace sc_core + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + Alex Riesen, Synopsys, Inc., 2003-02-02 + ported to SystemC 2.1 exception reporting. + + *****************************************************************************/ + + +// $Log: sc_utils_ids.cpp,v $ +// Revision 1.5 2011/08/26 20:46:19 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.4 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.3 2009/02/28 00:27:57 acg +// Andy Goodrich: includes for C++ library types to keep compiler happy. +// +// Revision 1.2 2008/05/20 20:43:21 acg +// Andy Goodrich: Added includes <cstdlib> and <cstring> to pick up their +// declarations. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.6 2006/01/31 21:42:07 acg +// Andy Goodrich: Added checks for SC_DEPRECATED_WARNINGS being defined as +// DISABLED. If so, we turn off the /IEEE_Std_1666/deprecated message group. +// +// Revision 1.5 2006/01/24 21:59:59 acg +// Andy Goodrich: removed sc_trace_ids.h since its only message has been +// replaced by SC_ID_IEEE_1666_DEPRECATION_ message. +// +// Revision 1.4 2006/01/24 20:53:41 acg +// Andy Goodrich: added warnings indicating that use of integer ids in reports +// is deprecated. Added tracing/sc_trace_ids.h to message list. +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_utils_ids.h b/ext/systemc/src/sysc/utils/sc_utils_ids.h new file mode 100644 index 000000000..811878280 --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_utils_ids.h @@ -0,0 +1,113 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_utils_ids.h -- Report ids for the utils code. + + Original Author: Martin Janssen, Synopsys, Inc., 2002-01-17 + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_UTILS_IDS_H +#define SC_UTILS_IDS_H + +// ---------------------------------------------------------------------------- +// Report ids (utils) +// +// Report ids in the range of 800-899. +// ---------------------------------------------------------------------------- + +#ifndef SC_DEFINE_MESSAGE +#define SC_DEFINE_MESSAGE(id,unused1,unused2) \ + namespace sc_core { extern const char id[]; } +namespace sc_core { + extern const char SC_ID_REGISTER_ID_FAILED_[]; // in sc_report_handler.cpp +} +#endif + +SC_DEFINE_MESSAGE(SC_ID_STRING_TOO_LONG_, + 801, "string is too long") +SC_DEFINE_MESSAGE(SC_ID_FRONT_ON_EMPTY_LIST_, + 802, "attempt to take front() on an empty list") +SC_DEFINE_MESSAGE(SC_ID_BACK_ON_EMPTY_LIST_, + 803, "attempt to take back() on an empty list") +SC_DEFINE_MESSAGE(SC_ID_IEEE_1666_DEPRECATION_, + 804, "/IEEE_Std_1666/deprecated" ) +SC_DEFINE_MESSAGE(SC_ID_VECTOR_INIT_CALLED_TWICE_, + 805, "sc_vector::init has already been called" ) +SC_DEFINE_MESSAGE(SC_ID_VECTOR_INIT_INVALID_CONTEXT_, + 806, "sc_vector::init called from invalid object context" ) +SC_DEFINE_MESSAGE(SC_ID_VECTOR_BIND_EMPTY_, + 807, "sc_vector::bind called with empty range" ) +SC_DEFINE_MESSAGE(SC_ID_VECTOR_NONOBJECT_ELEMENTS_, + 808, "sc_vector::get_elements called for element type " + "not derived from sc_object" ) + +/***************************************************************************** + + MODIFICATION LOG - modifiers, enter your name, affiliation, date and + changes you are making here. + + Name, Affiliation, Date: + Description of Modification: + + Alex Riesen, Synopsys, Inc., 2003-02-02 + ported to SystemC 2.1 exception reporting. + + *****************************************************************************/ + +// $Log: sc_utils_ids.h,v $ +// Revision 1.5 2011/08/26 20:46:20 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.4 2011/02/18 20:38:44 acg +// Andy Goodrich: Updated Copyright notice. +// +// Revision 1.3 2011/02/14 17:54:25 acg +// Andy Goodrich: Philipp's addition of early bind checks. +// +// Revision 1.2 2010/12/07 20:10:19 acg +// Andy Goodrich: messages for new sc_vector class. +// +// Revision 1.1.1.1 2006/12/15 20:20:06 acg +// SystemC 2.3 +// +// Revision 1.6 2006/01/25 00:31:27 acg +// Andy Goodrich: Changed over to use a standard message id of +// SC_ID_IEEE_1666_DEPRECATION for all deprecation messages. +// +// Revision 1.5 2006/01/24 22:01:35 acg +// Andy Goodrich: consolidated all IEEE 1666 compliance messages to use the +// SC_ID_IEEE_1666_DEPRECATION_ message type. +// +// Revision 1.4 2006/01/24 20:53:41 acg +// Andy Goodrich: added warnings indicating that use of integer ids in reports +// is deprecated. Added tracing/sc_trace_ids.h to message list. +// +// Revision 1.3 2006/01/13 18:53:11 acg +// Andy Goodrich: Added $Log command so that CVS comments are reproduced in +// the source. +// + +#endif + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_vector.cpp b/ext/systemc/src/sysc/utils/sc_vector.cpp new file mode 100644 index 000000000..e42fba02e --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_vector.cpp @@ -0,0 +1,178 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_vector.cpp - A vector of named (SystemC) objects (modules, ports, channels) + + Original Author: Philipp A. Hartmann, OFFIS + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + + +#include "sc_vector.h" + +#include "sysc/utils/sc_hash.h" +#include "sysc/utils/sc_list.h" +#include "sysc/utils/sc_utils_ids.h" + +#include "sysc/kernel/sc_simcontext.h" +#include "sysc/kernel/sc_object_manager.h" + +#include <sstream> + +namespace sc_core { + +sc_vector_base::sc_vector_base() + : sc_object( sc_gen_unique_name("vector") ) + , vec_() + , objs_vec_() +{} + +std::vector< sc_object* > const & +sc_vector_base::get_elements() const +{ + if( !objs_vec_ ) + objs_vec_ = new std::vector< sc_object* >; + + if( objs_vec_->size() || !size() ) + return *objs_vec_; + + objs_vec_->reserve( size() ); + for( const_iterator it=begin(); it != end(); ++it ) + if( sc_object* obj = object_cast(*it) ) + objs_vec_->push_back( obj ); + + return *objs_vec_; +} + +sc_object* +sc_vector_base::implicit_cast( ... ) const +{ + SC_REPORT_ERROR( SC_ID_VECTOR_NONOBJECT_ELEMENTS_, name() ); + return NULL; +} + +void +sc_vector_base::check_index( size_type i ) const +{ + if( i>=size() ) + { + std::stringstream str; + str << name() + << "[" << i << "] >= size() = " << size(); + SC_REPORT_ERROR( SC_ID_OUT_OF_BOUNDS_, str.str().c_str() ); + } +} + +bool +sc_vector_base::check_init( size_type n ) const +{ + if ( !n ) + return false; + + if( size() ) // already filled + { + std::stringstream str; + str << name() + << ", size=" << size() + << ", requested size=" << n; + SC_REPORT_ERROR( SC_ID_VECTOR_INIT_CALLED_TWICE_ + , str.str().c_str() ); + return false; + } + + sc_simcontext* simc = simcontext(); + sc_assert( simc == sc_get_curr_simcontext() ); + + sc_object* parent_p = simc->active_object(); + if( parent_p != get_parent_object() ) + { + std::stringstream str; + str << name() << ": expected " + << ( get_parent_object() + ? get_parent_object()->name() : "<top-level>" ) + << ", got " + << ( parent_p ? parent_p->name() : "<top-level>" ); + + SC_REPORT_ERROR( SC_ID_VECTOR_INIT_INVALID_CONTEXT_ + , str.str().c_str() ); + return false; + } + + return true; +} + +void +sc_vector_base::report_empty_bind( const char* kind_, bool dst_empty_ ) const +{ + std::stringstream str; + + str << "target `" << name() << "' " + << "(" << kind_ << ") "; + + if( !size() ) { + str << "not initialised yet"; + } else if ( dst_empty_ ) { + str << "empty range given"; + } else { + str << "empty destination range given"; + } + + SC_REPORT_WARNING( SC_ID_VECTOR_BIND_EMPTY_, str.str().c_str() ); +} + +std::string +sc_vector_base::make_name( const char* prefix, size_type /* idx */ ) +{ + // TODO: How to handle name clashes due to interleaved vector + // creation and init()? + // sc_vector< foo > v1, v2; + // v1.name() == "vector", v2.name() == "vector_0" + // v1.init( 1 ); -> v1[0].name() == "vector_0" -> clash + return sc_gen_unique_name( prefix ); +} + +} // namespace sc_core + +// $Log: sc_vector.cpp,v $ +// Revision 1.6 2011/08/26 20:46:20 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.5 2011/04/01 22:35:19 acg +// Andy Goodrich: spelling fix. +// +// Revision 1.4 2011/03/28 13:03:09 acg +// Andy Goodrich: Philipp's latest update. +// +// Revision 1.3 2011/03/23 16:16:28 acg +// Philipp A. Hartmann: rebase implementation on void* +// - supports virtual inheritance from sc_object again +// - build up get_elements result on demand +// - still requires element type to be derived from sc_object +// +// Revision 1.2 2011/02/14 17:54:25 acg +// Andy Goodrich: Philipp's addition of early bind checks. +// +// Revision 1.1 2011/02/13 21:54:14 acg +// Andy Goodrich: turn on embedding of cvs log records. + +// Taf! diff --git a/ext/systemc/src/sysc/utils/sc_vector.h b/ext/systemc/src/sysc/utils/sc_vector.h new file mode 100644 index 000000000..2afbaf45e --- /dev/null +++ b/ext/systemc/src/sysc/utils/sc_vector.h @@ -0,0 +1,724 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +/***************************************************************************** + + sc_vector.h - A vector of named (SystemC) objects (modules, ports, channels) + + Original Author: Philipp A. Hartmann, OFFIS + + CHANGE LOG AT END OF FILE + *****************************************************************************/ + +#ifndef SC_VECTOR_H_INCLUDED_ +#define SC_VECTOR_H_INCLUDED_ + +#include <vector> +#include <iterator> +#include <string> +#include <algorithm> // std::swap + +#include "sysc/kernel/sc_object.h" +#include <type_traits> + +//#define SC_VECTOR_HEADER_ONLY_ + +namespace sc_core { +namespace sc_meta { + + using ::std::enable_if; + using ::std::remove_const; + using ::std::is_same; + using ::std::is_const; + + template< typename CT, typename T > + struct is_more_const { + static constexpr bool value + = ( is_same< typename remove_const<CT>::type + , typename remove_const<T>::type + >::value + && ( is_const<CT>::value >= is_const<T>::value ) ); + }; + +} // namespace sc_meta + +// forward declarations +template< typename T > class sc_vector; +template< typename T, typename MT > class sc_vector_assembly; +template< typename T, typename MT > class sc_vector_iter; + +// implementation-defined +template< typename Container, typename ArgumentIterator > +typename Container::iterator +sc_vector_do_bind( Container & cont + , ArgumentIterator first + , ArgumentIterator last + , typename Container::iterator from ); + +// implementation-defined +template< typename Container, typename ArgumentIterator > +typename Container::iterator +sc_vector_do_operator_paren( Container & cont + , ArgumentIterator first + , ArgumentIterator last + , typename Container::iterator from ); + +class sc_vector_base + : public sc_object +{ + + template<typename,typename> friend class sc_vector_assembly; + template<typename,typename> friend class sc_vector_iter; + +public: + + typedef std::vector< void* > storage_type; + typedef storage_type::size_type size_type; + typedef storage_type::difference_type difference_type; + + const char * kind() const { return "sc_vector"; } + + std::vector<sc_object*> const & get_elements() const; + + size_type size() const + { return vec_.size(); } + +protected: + + // begin implementation defined + + typedef storage_type::iterator iterator; + typedef storage_type::const_iterator const_iterator; + + sc_vector_base(); + + sc_vector_base( const char* prefix ) + : sc_object( prefix ) + , vec_() + , objs_vec_(0) + {} + + ~sc_vector_base() + { delete objs_vec_; } + + void * & at( size_type i ) + { return vec_[i]; } + + void const * at( size_type i ) const + { return vec_[i]; } + + void reserve( size_type n ) + { vec_.reserve(n); } + + void clear() + { vec_.clear(); } + + void push_back( void* item ) + { vec_.push_back(item); } + + void check_index( size_type i ) const; + bool check_init( size_type n ) const; + + static std::string make_name( const char* prefix, size_type index ); + + iterator begin() { return vec_.begin(); } + iterator end() { return vec_.end(); } + + const_iterator begin() const { return vec_.begin(); } + const_iterator end() const { return vec_.end(); } + + virtual sc_object* object_cast( void* ) const = 0; + + sc_object* implicit_cast( sc_object* p ) const { return p; } + sc_object* implicit_cast( ... /* incompatible */ ) const; + +public: + + void report_empty_bind( const char* kind_, bool dst_range_ ) const; + +private: + storage_type vec_; + mutable std::vector< sc_object* >* objs_vec_; + + // disabled + sc_vector_base( const sc_vector_base& ); + sc_vector_base& operator=( const sc_vector_base& ); + +}; // sc_vector_base + +// iterator access adapters +template< typename ElementType > +struct sc_direct_access +{ + typedef ElementType element_type; + typedef element_type type; + typedef typename sc_meta::remove_const<type>::type plain_type; + + typedef sc_direct_access< type > policy; + typedef sc_direct_access< plain_type > non_const_policy; + typedef sc_direct_access< const plain_type > const_policy; + + sc_direct_access(){} + sc_direct_access( const non_const_policy& ) {} + // convert from any policy to (const) direct policy + template <typename U> + sc_direct_access(const U&, + typename sc_meta::enable_if<sc_meta::is_more_const< + type, + typename U::policy::element_type>::value>::type* = NULL) + {} + + type* get( type* this_ ) const + { return this_; } +}; + +// iterator access adapters +template< typename ElementType + , typename AccessType > +class sc_member_access +{ + public: + template< typename, typename > friend class sc_member_access; + + typedef ElementType element_type; + typedef AccessType access_type; + typedef access_type (ElementType::*member_type); + typedef access_type type; + typedef typename sc_meta::remove_const<type>::type plain_type; + typedef typename sc_meta::remove_const<ElementType>::type plain_elem_type; + + typedef sc_member_access< element_type, access_type > policy; + typedef sc_member_access< plain_elem_type, plain_type > + non_const_policy; + typedef sc_member_access< const plain_elem_type, const plain_type > + const_policy; + + sc_member_access( member_type ptr ) + : ptr_(ptr) {} + + sc_member_access( const non_const_policy& other ) + : ptr_(other.ptr_) + {} + + access_type * get( element_type* this_ ) const + { return &(this_->*ptr_); } + + private: + member_type ptr_; +}; // sc_member_access + + +template< typename ElementType + , typename AccessPolicy = sc_direct_access<ElementType> > +class sc_vector_iter + : public std::iterator< std::random_access_iterator_tag + , typename AccessPolicy::type > + , private AccessPolicy +{ + typedef ElementType element_type; + typedef typename AccessPolicy::policy access_policy; + typedef typename AccessPolicy::non_const_policy non_const_policy; + typedef typename AccessPolicy::const_policy const_policy; + typedef typename access_policy::type access_type; + + typedef typename sc_meta::remove_const<ElementType>::type plain_type; + typedef const plain_type const_plain_type; + + friend class sc_vector< plain_type >; + template< typename, typename > friend class sc_vector_assembly; + template< typename, typename > friend class sc_vector_iter; + + typedef std::iterator< std::random_access_iterator_tag, access_type > base_type; + typedef sc_vector_iter this_type; + typedef sc_vector<plain_type> vector_type; + typedef sc_vector_base::storage_type storage_type; + + // select correct base-type iterator + template< typename U > struct select_iter + { typedef typename storage_type::iterator type; }; + template< typename U > struct select_iter< const U > + { typedef typename storage_type::const_iterator type; }; + + typedef typename select_iter<ElementType>::type raw_iterator; + typedef sc_vector_iter< const_plain_type, const_policy > const_iterator; + + // underlying vector iterator + + raw_iterator it_; + + sc_vector_iter( raw_iterator it, access_policy acc = access_policy() ) + : access_policy(acc), it_(it) {} + + access_policy const & get_policy() const { return *this; } + +public: + // interface for Random Access Iterator category, + // see ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements] + + typedef typename base_type::difference_type difference_type; + typedef typename base_type::reference reference; + typedef typename base_type::pointer pointer; + + sc_vector_iter() : access_policy(), it_() {} + + // iterator conversions to more const, and/or direct iterators + template< typename OtherElement, typename OtherPolicy > + sc_vector_iter( const sc_vector_iter<OtherElement, OtherPolicy>& it + , typename sc_meta::enable_if<sc_meta::is_more_const< + element_type, + typename OtherPolicy::element_type>::value>::type* = NULL) + : access_policy( it.get_policy() ), it_( it.it_ ) + {} + + // step + this_type& operator++(){ ++it_; return *this; } + this_type& operator--(){ --it_; return *this; } + this_type operator++(int){ this_type old(*this); ++it_; return old; } + this_type operator--(int){ this_type old(*this); --it_; return old; } + + // advance + this_type operator+( difference_type n ) const + { return this_type( it_ + n, get_policy()); } + this_type operator-( difference_type n ) const + { return this_type( it_ - n, get_policy()); } + + this_type& operator+=( difference_type n ) { it_+=n; return *this; } + this_type& operator-=( difference_type n ) { it_-=n; return *this; } + + // relations + bool operator== ( const this_type& that ) const { return it_ == that.it_; } + bool operator!= ( const this_type& that ) const { return it_ != that.it_; } + bool operator<= ( const this_type& that ) const { return it_ <= that.it_; } + bool operator>= ( const this_type& that ) const { return it_ >= that.it_; } + bool operator< ( const this_type& that ) const { return it_ < that.it_; } + bool operator> ( const this_type& that ) const { return it_ > that.it_; } + + // dereference + reference operator*() const + { return *access_policy::get( static_cast<element_type*>(*it_) ); } + pointer operator->() const + { return access_policy::get( static_cast<element_type*>(*it_) ); } + reference operator[]( difference_type n ) const + { return *access_policy::get( static_cast<element_type*>(it_[n]) ); } + + // distance + difference_type operator-( this_type const& that ) const + { return it_-that.it_; } + +}; // sc_vector_iter + +template< typename T > +class sc_vector + : public sc_vector_base +{ + typedef sc_vector_base base_type; + typedef sc_vector<T> this_type; + +public: + typedef T element_type; + typedef sc_vector_iter< element_type > iterator; + typedef sc_vector_iter< const element_type > const_iterator; + + sc_vector(){} + + explicit sc_vector( const char* prefix ) + : base_type( prefix ) + {} + + explicit sc_vector( const char* prefix, size_type n ) + : base_type( prefix ) + { init(n); } + + template< typename Creator > + sc_vector( const char* prefix, size_type n, Creator creator ) + : base_type( prefix ) + { + init( n, creator ); + } + + virtual ~sc_vector(); + + element_type& operator[]( size_type i ) + { return *static_cast<element_type*>( base_type::at(i) ); } + + element_type& at( size_type i ) + { check_index(i); return (*this)[i]; } + + const element_type& operator[]( size_type i ) const + { return *static_cast<element_type const *>( base_type::at(i) ); } + + const element_type& at( size_type i ) const + { check_index(i); return (*this)[i]; } + + void init( size_type n ) + { init( n, &this_type::create_element ); } + + template< typename Creator > + void init( size_type n, Creator c ); + + static element_type * create_element( const char* prefix, size_type index ); + + iterator begin() { return base_type::begin(); } + iterator end() { return base_type::end(); } + + const_iterator begin() const { return base_type::begin(); } + const_iterator end() const { return base_type::end(); } + + const_iterator cbegin() const { return base_type::begin(); } + const_iterator cend() const { return base_type::end(); } + + template< typename ContainerType, typename ArgumentType > + iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c ) + { return bind( c.begin(), c.end() ); } + + template< typename BindableContainer > + iterator bind( BindableContainer & c ) + { return bind( c.begin(), c.end() ); } + + template< typename BindableIterator > + iterator bind( BindableIterator first, BindableIterator last ) + { return bind( first, last, this->begin() ); } + + template< typename BindableIterator > + iterator bind( BindableIterator first, BindableIterator last + , iterator from ) + { return sc_vector_do_bind( *this, first, last, from ); } + + template< typename ContainerType, typename ArgumentType > + iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c ) + { return operator()( c.begin(), c.end() ); } + + template< typename ArgumentContainer > + iterator operator()( ArgumentContainer & c ) + { return operator()( c.begin(), c.end() ); } + + template< typename ArgumentIterator > + iterator operator()( ArgumentIterator first, ArgumentIterator last ) + { return operator()( first, last, this->begin() ); } + + template< typename ArgumentIterator > + iterator operator()( ArgumentIterator first, ArgumentIterator last + , iterator from ) + { return sc_vector_do_operator_paren( *this, first, last, from ); } + + // member-wise access + + template< typename MT > + sc_vector_assembly<T,MT> assemble( MT (T::*member_ptr) ) + { return sc_vector_assembly<T,MT>( *this, member_ptr ); } + +protected: + + void clear(); + + virtual sc_object* object_cast( void* p ) const + { return implicit_cast( static_cast<element_type*>(p) ); } + +}; + +template< typename T, typename MT > +class sc_vector_assembly +{ + template< typename U > friend class sc_vector; + +public: + + typedef sc_vector<T> base_type; + + typedef sc_vector_iter< T, sc_member_access<T, MT> > iterator; + typedef sc_vector_iter< const T + , sc_member_access<const T, const MT> > const_iterator; + + typedef T element_type; + typedef MT access_type; + + typedef typename base_type::size_type size_type; + typedef typename base_type::difference_type difference_type; + typedef typename iterator::reference reference; + typedef typename iterator::pointer pointer; + typedef typename const_iterator::reference const_reference; + typedef typename const_iterator::pointer const_pointer; + + + typedef access_type (T::*member_type); + + const char* name() const { return vec_->name(); } + const char* kind() const { return "sc_vector_assembly"; } + + iterator begin() + { return iterator( (*vec_).begin().it_, ptr_ ); } + iterator end() + { return iterator( (*vec_).end().it_, ptr_ ); } + + const_iterator cbegin() const + { return const_iterator( (*vec_).cbegin().it_, ptr_ ); } + const_iterator cend() const + { return const_iterator( (*vec_).cend().it_, ptr_ ); } + + const_iterator begin() const + { return const_iterator( (*vec_).begin().it_, ptr_ ); } + const_iterator end() const + { return const_iterator( (*vec_).end().it_, ptr_ ); } + + size_type size() const { return vec_->size(); } + const std::vector< sc_object* > & get_elements() const; + + reference operator[]( size_type idx ) + { return (*vec_)[idx].*ptr_; } + reference at( size_type idx ) + { return vec_->at(idx).*ptr_; } + const_reference operator[]( size_type idx ) const + { return (*vec_)[idx].*ptr_; } + const_reference at( size_type idx ) const + { return vec_->at(idx).*ptr_; } + + template< typename ContainerType, typename ArgumentType > + iterator bind( sc_vector_assembly<ContainerType,ArgumentType> c ) + { return bind( c.begin(), c.end() ); } + + template< typename BindableContainer > + iterator bind( BindableContainer & c ) + { return bind( c.begin(), c.end() ); } + + template< typename BindableIterator > + iterator bind( BindableIterator first, BindableIterator last ) + { return bind( first, last, this->begin() ); } + + template< typename BindableIterator > + iterator bind( BindableIterator first, BindableIterator last + , iterator from ) + { return sc_vector_do_bind( *this, first, last, from ); } + + template< typename BindableIterator > + iterator bind( BindableIterator first, BindableIterator last + , typename base_type::iterator from ) + { return bind( first, last, iterator(from.it_, ptr_) ); } + + template< typename ContainerType, typename ArgumentType > + iterator operator()( sc_vector_assembly<ContainerType,ArgumentType> c ) + { return operator()( c.begin(), c.end() ); } + + template< typename ArgumentContainer > + iterator operator()( ArgumentContainer & c ) + { return operator()( c.begin(), c.end() ); } + + template< typename ArgumentIterator > + iterator operator()( ArgumentIterator first, ArgumentIterator last ) + { return operator()( first, last, this->begin() ); } + + template< typename ArgumentIterator > + iterator operator()( ArgumentIterator first, ArgumentIterator last + , iterator from ) + { return sc_vector_do_operator_paren( *this, first, last, from ); } + + template< typename ArgumentIterator > + iterator operator()( ArgumentIterator first, ArgumentIterator last + , typename base_type::iterator from ) + { return operator()( first, last, iterator(from.it_, ptr_) ); } + + sc_vector_assembly( const sc_vector_assembly & other ) + : vec_( other.vec_ ) + , ptr_( other.ptr_ ) + , child_vec_(0) + {} + + sc_vector_assembly& operator=( sc_vector_assembly other_copy ) + { + swap( other_copy ); + return *this; + } + + void swap( sc_vector_assembly & that ) + { + using std::swap; + swap( vec_, that.vec_ ); + swap( ptr_, that.ptr_ ); + swap( child_vec_, that.child_vec_ ); + } + + void report_empty_bind( const char* kind_, bool dst_empty_ ) const + { vec_->report_empty_bind( kind_, dst_empty_ ); } + + ~sc_vector_assembly() + { delete child_vec_; } + +private: + + sc_vector_assembly( base_type & v, member_type ptr ) + : vec_(&v) + , ptr_(ptr) + , child_vec_(0) + {} + + sc_object* object_cast( pointer p ) const + { return vec_->implicit_cast( p ); } + + base_type * vec_; + member_type ptr_; + + mutable std::vector< sc_object* >* child_vec_; +}; + +template< typename T, typename MT > +sc_vector_assembly<T,MT> +sc_assemble_vector( sc_vector<T> & vec, MT (T::*ptr) ) +{ + return vec.assemble( ptr ); +} + +template< typename T > +typename sc_vector<T>::element_type * +sc_vector<T>::create_element( const char* name, size_type /* idx */ ) +{ + return new T( name ); +} + +template< typename T > +template< typename Creator > +void +sc_vector<T>::init( size_type n, Creator c ) +{ + if ( base_type::check_init(n) ) + { + base_type::reserve( n ); + try + { + for ( size_type i = 0; i<n; ++i ) + { + // this workaround is needed for SystemC 2.2/2.3 sc_bind + std::string name = make_name( basename(), i ); + const char* cname = name.c_str(); + + void* p = c( cname, i ) ; // call Creator + base_type::push_back(p); + } + } + catch ( ... ) + { + clear(); + throw; + } + } +} + +template< typename T > +void +sc_vector<T>::clear() +{ + size_type i = size(); + while ( i --> 0 ) + { + delete &( (*this)[i] ); + base_type::at(i) = 0; + } + base_type::clear(); +} + +template< typename Container, typename ArgumentIterator > +typename Container::iterator +sc_vector_do_bind( Container & cont + , ArgumentIterator first + , ArgumentIterator last + , typename Container::iterator from ) +{ + typename Container::iterator end = cont.end(); + + if( !cont.size() || from == end || first == last ) + cont.report_empty_bind( cont.kind(), from == end ); + + while( from!=end && first != last ) + (*from++).bind( *first++ ); + return from; +} + +template< typename Container, typename ArgumentIterator > +typename Container::iterator +sc_vector_do_operator_paren( Container& cont + , ArgumentIterator first + , ArgumentIterator last + , typename Container::iterator from ) +{ + typename Container::iterator end = cont.end(); + + if( !cont.size() || from == end || first == last ) + cont.report_empty_bind( cont.kind(), from == end ); + + while( from!=end && first != last ) + (*from++)( *first++ ); + return from; +} + +template< typename T > +sc_vector<T>::~sc_vector() +{ + clear(); +} + +template< typename T, typename MT > +std::vector< sc_object* > const & +sc_vector_assembly<T,MT>::get_elements() const +{ + if( !child_vec_ ) + child_vec_ = new std::vector< sc_object* >; + + if( child_vec_->size() || !size() ) + return *child_vec_; + + child_vec_->reserve( size() ); + for( const_iterator it=begin(); it != end(); ++it ) + if( sc_object * obj = object_cast( const_cast<MT*>(&*it) ) ) + child_vec_->push_back( obj ); + + return *child_vec_; +} + +} // namespace sc_core +#undef SC_RPTYPE_ +#undef SC_ENABLE_IF_ + +// $Log: sc_vector.h,v $ +// Revision 1.17 2011/08/26 20:46:20 acg +// Andy Goodrich: moved the modification log to the end of the file to +// eliminate source line number skew when check-ins are done. +// +// Revision 1.16 2011/07/25 10:21:17 acg +// Andy Goodrich: check in aftermath of call to automake. +// +// Revision 1.15 2011/04/02 00:04:32 acg +// Philipp A. Hartmann: fix distance from member iterators, and +// add iterator conversions. +// +// Revision 1.14 2011/04/01 22:35:19 acg +// Andy Goodrich: spelling fix. +// +// Revision 1.13 2011/03/28 13:03:09 acg +// Andy Goodrich: Philipp's latest update. +// +// Revision 1.12 2011/03/23 16:16:28 acg +// Philipp A. Hartmann: rebase implementation on void* +// - supports virtual inheritance from sc_object again +// - build up get_elements result on demand +// - still requires element type to be derived from sc_object +// +// Revision 1.11 2011/02/19 16:46:36 acg +// Andy Goodrich: finally get the update from Philipp correct! +// + +#endif // SC_VECTOR_H_INCLUDED_ +// Taf! |