113516Sgabeblack@google.com/*****************************************************************************
213516Sgabeblack@google.com
313516Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413516Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513516Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613516Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713516Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813516Sgabeblack@google.com  License.  You may obtain a copy of the License at
913516Sgabeblack@google.com
1013516Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113516Sgabeblack@google.com
1213516Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313516Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413516Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513516Sgabeblack@google.com  implied.  See the License for the specific language governing
1613516Sgabeblack@google.com  permissions and limitations under the License.
1713516Sgabeblack@google.com
1813516Sgabeblack@google.com *****************************************************************************/
1913516Sgabeblack@google.com
2013516Sgabeblack@google.com#include <cstring>
2113516Sgabeblack@google.com#include <map>
2213524Sgabeblack@google.com#include <string>
2313523Sgabeblack@google.com#include <typeindex>
2413516Sgabeblack@google.com
2513586Sgabeblack@google.com#include "systemc/ext/tlm_core/2/generic_payload/phase.hh"
2613586Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh"
2713586Sgabeblack@google.com
2813516Sgabeblack@google.comnamespace tlm
2913516Sgabeblack@google.com{
3013516Sgabeblack@google.com
3113516Sgabeblack@google.comnamespace
3213516Sgabeblack@google.com{
3313516Sgabeblack@google.com
3413516Sgabeblack@google.comstruct tlm_phase_registry
3513516Sgabeblack@google.com{
3613516Sgabeblack@google.com    typedef unsigned int key_type;
3713516Sgabeblack@google.com
3813516Sgabeblack@google.com    static tlm_phase_registry &
3913516Sgabeblack@google.com    instance()
4013516Sgabeblack@google.com    {
4113516Sgabeblack@google.com        static tlm_phase_registry inst;
4213516Sgabeblack@google.com        return inst;
4313516Sgabeblack@google.com    }
4413516Sgabeblack@google.com
4513516Sgabeblack@google.com    unsigned int
4613524Sgabeblack@google.com    register_phase(std::type_index type, std::string name)
4713516Sgabeblack@google.com    {
4813516Sgabeblack@google.com        type_map::const_iterator it = ids_.find(type);
4913516Sgabeblack@google.com
5013516Sgabeblack@google.com        if (name.empty()) {
5113516Sgabeblack@google.com            SC_REPORT_FATAL( sc_core::SC_ID_INTERNAL_ERROR_,
5213516Sgabeblack@google.com                    "unexpected empty tlm_phase name" );
5313516Sgabeblack@google.com            return UNINITIALIZED_PHASE;
5413516Sgabeblack@google.com        }
5513516Sgabeblack@google.com
5613516Sgabeblack@google.com        if (it == ids_.end()) {
5713516Sgabeblack@google.com            // new phase - generate/store ID and name
5813516Sgabeblack@google.com            type_map::value_type v(type, static_cast<key_type>(names_.size()));
5913516Sgabeblack@google.com            names_.push_back(name_table::value_type(name.data(), name.size()));
6013516Sgabeblack@google.com            ids_.insert(v);
6113516Sgabeblack@google.com            return v.second;
6213516Sgabeblack@google.com        }
6313516Sgabeblack@google.com
6413516Sgabeblack@google.com        if (names_[it->second] != name) {
6513516Sgabeblack@google.com            SC_REPORT_FATAL(sc_core::SC_ID_INTERNAL_ERROR_,
6613516Sgabeblack@google.com                    "tlm_phase registration failed: duplicate type info" );
6713516Sgabeblack@google.com            sc_core::sc_abort();
6813516Sgabeblack@google.com        }
6913516Sgabeblack@google.com        return it->second;
7013516Sgabeblack@google.com    }
7113516Sgabeblack@google.com
7213516Sgabeblack@google.com    const char *
7313516Sgabeblack@google.com    get_name(key_type id) const
7413516Sgabeblack@google.com    {
7513516Sgabeblack@google.com        sc_assert(id < names_.size());
7613516Sgabeblack@google.com        return names_[id].c_str();
7713516Sgabeblack@google.com    }
7813516Sgabeblack@google.com
7913516Sgabeblack@google.com  private:
8013523Sgabeblack@google.com    typedef std::map<std::type_index, key_type> type_map;
8113516Sgabeblack@google.com    typedef std::vector<std::string> name_table;
8213516Sgabeblack@google.com
8313516Sgabeblack@google.com    type_map ids_;
8413516Sgabeblack@google.com    name_table names_;
8513516Sgabeblack@google.com
8613516Sgabeblack@google.com    tlm_phase_registry() : names_(END_RESP + 1)
8713516Sgabeblack@google.com    {
8813516Sgabeblack@google.com        names_[UNINITIALIZED_PHASE] = "UNINITIALIZED_PHASE";
8913516Sgabeblack@google.com        names_[BEGIN_REQ] = "BEGIN_REQ";
9013516Sgabeblack@google.com        names_[END_REQ] = "END_REQ";
9113516Sgabeblack@google.com        names_[BEGIN_RESP] = "BEGIN_RESP";
9213516Sgabeblack@google.com        names_[END_RESP] = "END_RESP";
9313516Sgabeblack@google.com    }
9413516Sgabeblack@google.com};
9513516Sgabeblack@google.com
9613516Sgabeblack@google.com} // anonymous namespace
9713516Sgabeblack@google.com
9813516Sgabeblack@google.comtlm_phase::tlm_phase(unsigned int id) : m_id(id)
9913516Sgabeblack@google.com{}
10013516Sgabeblack@google.com
10113516Sgabeblack@google.comtlm_phase::tlm_phase(const std::type_info &type, const char *name) :
10213516Sgabeblack@google.com    m_id(tlm_phase_registry::instance().register_phase(type, name))
10313516Sgabeblack@google.com{}
10413516Sgabeblack@google.com
10513516Sgabeblack@google.comconst char *
10613516Sgabeblack@google.comtlm_phase::get_name() const
10713516Sgabeblack@google.com{
10813516Sgabeblack@google.com    return tlm_phase_registry::instance().get_name(m_id);
10913516Sgabeblack@google.com}
11013516Sgabeblack@google.com
11113516Sgabeblack@google.com} // namespace tlm
112