summaryrefslogtreecommitdiff
path: root/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp')
-rw-r--r--src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp
new file mode 100644
index 000000000..5f3fb25e0
--- /dev/null
+++ b/src/systemc/tlm_core/tlm_2/tlm_generic_payload/tlm_phase.cpp
@@ -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.
+
+ *****************************************************************************/
+
+#include "tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h"
+#include "sysc/utils/sc_string_view.h"
+#include "sysc/utils/sc_typeindex.h"
+#include "sysc/utils/sc_report.h"
+#include <cstring>
+#include <map>
+
+using sc_core::sc_string_view;
+using sc_core::sc_type_index;
+
+namespace tlm {
+/* anonymous */ namespace {
+
+struct tlm_phase_registry
+{
+ typedef unsigned int key_type;
+
+ static tlm_phase_registry& instance()
+ { static tlm_phase_registry inst; return inst; }
+
+ unsigned int register_phase(sc_type_index type, sc_string_view name)
+ {
+ type_map::const_iterator it = ids_.find( type );
+
+ if( name.empty() ) {
+ SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
+ "unexpected empty tlm_phase name" );
+ return UNINITIALIZED_PHASE;
+ }
+
+ if( it == ids_.end() ) { // new phase - generate/store ID and name
+ type_map::value_type v( type, static_cast<key_type>(names_.size()) );
+ names_.push_back( name_table::value_type(name.data(), name.size()) );
+ ids_.insert( v );
+ return v.second;
+ }
+
+ if( names_[it->second] != name ) {
+ SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
+ "tlm_phase registration failed: duplicate type info" );
+ sc_core::sc_abort();
+ }
+ return it->second;
+ }
+
+ const char* get_name( key_type id ) const
+ {
+ sc_assert( id < names_.size() );
+ return names_[id].c_str();
+ }
+
+private:
+ typedef std::map<sc_type_index, key_type> type_map;
+ typedef std::vector<std::string> name_table;
+
+ type_map ids_;
+ name_table names_;
+
+ tlm_phase_registry()
+ : names_( END_RESP+1 )
+ {
+# define BUILTIN_PHASE(phase) \
+ names_[phase] = #phase
+
+ BUILTIN_PHASE( UNINITIALIZED_PHASE );
+ BUILTIN_PHASE( BEGIN_REQ );
+ BUILTIN_PHASE( END_REQ );
+ BUILTIN_PHASE( BEGIN_RESP );
+ BUILTIN_PHASE( END_RESP );
+ }
+
+}; // class tlm_phase_registry
+
+} // anonymous namespace
+
+tlm_phase::tlm_phase( unsigned int id )
+ : m_id(id)
+{
+ // TODO: validate id?
+ // TODO: add deprecation warning?
+}
+
+tlm_phase::tlm_phase( const std::type_info& type, const char* name )
+ : m_id( tlm_phase_registry::instance().register_phase(type, name) )
+{}
+
+const char*
+tlm_phase::get_name() const
+{
+ return tlm_phase_registry::instance().get_name( m_id );
+}
+
+} // namespace tlm
+// Taf!