simple_target_socket.h revision 13743
113511Sgabeblack@google.com/***************************************************************************** 213511Sgabeblack@google.com 313511Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 413511Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 513511Sgabeblack@google.com with this work for additional information regarding copyright ownership. 613511Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 713511Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 813511Sgabeblack@google.com License. You may obtain a copy of the License at 913511Sgabeblack@google.com 1013511Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1113511Sgabeblack@google.com 1213511Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1313511Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1413511Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1513511Sgabeblack@google.com implied. See the License for the specific language governing 1613511Sgabeblack@google.com permissions and limitations under the License. 1713511Sgabeblack@google.com 1813511Sgabeblack@google.com *****************************************************************************/ 1913511Sgabeblack@google.com 2013513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__ 2113513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__ 2213511Sgabeblack@google.com 2313586Sgabeblack@google.com#include "../core/sc_event.hh" 2413586Sgabeblack@google.com#include "../core/sc_module.hh" 2513586Sgabeblack@google.com#include "../core/sc_port.hh" 2613743Sgabeblack@google.com#include "../core/sc_spawn.hh" 2713586Sgabeblack@google.com#include "../tlm_core/2/generic_payload/gp.hh" 2813586Sgabeblack@google.com#include "../tlm_core/2/interfaces/fw_bw_ifs.hh" 2913743Sgabeblack@google.com#include "../tlm_core/2/sockets/initiator_socket.hh" 3013586Sgabeblack@google.com#include "../tlm_core/2/sockets/target_socket.hh" 3113586Sgabeblack@google.com#include "../utils/sc_report_handler.hh" 3213586Sgabeblack@google.com#include "convenience_socket_bases.h" 3313586Sgabeblack@google.com#include "peq_with_get.h" 3413511Sgabeblack@google.com 3513513Sgabeblack@google.comnamespace tlm_utils 3613513Sgabeblack@google.com{ 3713511Sgabeblack@google.com 3813513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 3913513Sgabeblack@google.com sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 4013513Sgabeblack@google.comclass simple_target_socket_b : 4113513Sgabeblack@google.com public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>, 4213513Sgabeblack@google.com protected simple_socket_base 4313511Sgabeblack@google.com{ 4413513Sgabeblack@google.com friend class fw_process; 4513513Sgabeblack@google.com friend class bw_process; 4613513Sgabeblack@google.com public: 4713513Sgabeblack@google.com typedef typename TYPES::tlm_payload_type transaction_type; 4813513Sgabeblack@google.com typedef typename TYPES::tlm_phase_type phase_type; 4913513Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 5013513Sgabeblack@google.com typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 5113513Sgabeblack@google.com typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 5213513Sgabeblack@google.com typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type; 5313511Sgabeblack@google.com 5413511Sgabeblack@google.com public: 5513513Sgabeblack@google.com static const char * 5613513Sgabeblack@google.com default_name() 5713511Sgabeblack@google.com { 5813513Sgabeblack@google.com return sc_core::sc_gen_unique_name("simple_target_socket"); 5913511Sgabeblack@google.com } 6013511Sgabeblack@google.com 6113513Sgabeblack@google.com explicit simple_target_socket_b(const char *n=default_name()) : 6213513Sgabeblack@google.com base_type(n), m_fw_process(this), m_bw_process(this) 6313511Sgabeblack@google.com { 6413513Sgabeblack@google.com bind(m_fw_process); 6513511Sgabeblack@google.com } 6613511Sgabeblack@google.com 6713513Sgabeblack@google.com using base_type::bind; 6813513Sgabeblack@google.com 6913513Sgabeblack@google.com // bw transport must come through us. 7013513Sgabeblack@google.com tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; } 7113513Sgabeblack@google.com 7213513Sgabeblack@google.com // REGISTER_XXX 7313513Sgabeblack@google.com void 7413513Sgabeblack@google.com register_nb_transport_fw(MODULE *mod, 7513513Sgabeblack@google.com sync_enum_type (MODULE::*cb)( 7613513Sgabeblack@google.com transaction_type &, phase_type &, sc_core::sc_time &)) 7713511Sgabeblack@google.com { 7813513Sgabeblack@google.com elaboration_check("register_nb_transport_fw"); 7913513Sgabeblack@google.com m_fw_process.set_nb_transport_ptr(mod, cb); 8013513Sgabeblack@google.com } 8113513Sgabeblack@google.com 8213513Sgabeblack@google.com void 8313513Sgabeblack@google.com register_b_transport(MODULE *mod, 8413513Sgabeblack@google.com void (MODULE::*cb)(transaction_type &, sc_core::sc_time &)) 8513513Sgabeblack@google.com { 8613513Sgabeblack@google.com elaboration_check("register_b_transport"); 8713513Sgabeblack@google.com m_fw_process.set_b_transport_ptr(mod, cb); 8813513Sgabeblack@google.com } 8913513Sgabeblack@google.com 9013513Sgabeblack@google.com void 9113513Sgabeblack@google.com register_transport_dbg(MODULE *mod, 9213513Sgabeblack@google.com unsigned int (MODULE::*cb)(transaction_type &)) 9313513Sgabeblack@google.com { 9413513Sgabeblack@google.com elaboration_check("register_transport_dbg"); 9513513Sgabeblack@google.com m_fw_process.set_transport_dbg_ptr(mod, cb); 9613513Sgabeblack@google.com } 9713513Sgabeblack@google.com 9813513Sgabeblack@google.com void 9913513Sgabeblack@google.com register_get_direct_mem_ptr(MODULE *mod, 10013513Sgabeblack@google.com bool (MODULE::*cb)(transaction_type &, tlm::tlm_dmi &)) 10113513Sgabeblack@google.com { 10213513Sgabeblack@google.com elaboration_check("register_get_direct_mem_ptr"); 10313513Sgabeblack@google.com m_fw_process.set_get_direct_mem_ptr(mod, cb); 10413513Sgabeblack@google.com } 10513513Sgabeblack@google.com 10613513Sgabeblack@google.com protected: 10713513Sgabeblack@google.com void 10813513Sgabeblack@google.com start_of_simulation() 10913513Sgabeblack@google.com { 11013513Sgabeblack@google.com base_type::start_of_simulation(); 11113513Sgabeblack@google.com m_fw_process.start_of_simulation(); 11213511Sgabeblack@google.com } 11313511Sgabeblack@google.com 11413511Sgabeblack@google.com private: 11513513Sgabeblack@google.com // Make call on bw path. 11613513Sgabeblack@google.com sync_enum_type 11713513Sgabeblack@google.com bw_nb_transport(transaction_type &trans, phase_type &phase, 11813513Sgabeblack@google.com sc_core::sc_time &t) 11913511Sgabeblack@google.com { 12013513Sgabeblack@google.com return base_type::operator -> ()->nb_transport_bw(trans, phase, t); 12113511Sgabeblack@google.com } 12213511Sgabeblack@google.com 12313513Sgabeblack@google.com void 12413513Sgabeblack@google.com bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 12513511Sgabeblack@google.com { 12613513Sgabeblack@google.com base_type::operator -> ()->invalidate_direct_mem_ptr(s, e); 12713511Sgabeblack@google.com } 12813511Sgabeblack@google.com 12913513Sgabeblack@google.com // Helper class to handle bw path calls Needed to detect transaction end 13013513Sgabeblack@google.com // when called from b_transport. 13113513Sgabeblack@google.com class bw_process : public tlm::tlm_bw_transport_if<TYPES> 13213511Sgabeblack@google.com { 13313513Sgabeblack@google.com public: 13413513Sgabeblack@google.com bw_process(simple_target_socket_b *p_own) : m_owner(p_own) {} 13513513Sgabeblack@google.com 13613513Sgabeblack@google.com sync_enum_type 13713513Sgabeblack@google.com nb_transport_bw(transaction_type &trans, phase_type &phase, 13813513Sgabeblack@google.com sc_core::sc_time &t) 13913513Sgabeblack@google.com { 14013513Sgabeblack@google.com typename std::map<transaction_type *, 14113513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 14213513Sgabeblack@google.com m_owner->m_pending_trans.find(&trans); 14313513Sgabeblack@google.com 14413513Sgabeblack@google.com if (it == m_owner->m_pending_trans.end()) { 14513513Sgabeblack@google.com // Not a blocking call, forward. 14613513Sgabeblack@google.com return m_owner->bw_nb_transport(trans, phase, t); 14713513Sgabeblack@google.com 14813513Sgabeblack@google.com } 14913513Sgabeblack@google.com 15013513Sgabeblack@google.com if (phase == tlm::END_REQ) { 15113513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15213513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 15313513Sgabeblack@google.com } 15413513Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 15513513Sgabeblack@google.com if (m_owner->m_current_transaction == &trans) { 15613513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15713513Sgabeblack@google.com } 15813513Sgabeblack@google.com it->second->notify(t); 15913513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 16013513Sgabeblack@google.com return tlm::TLM_COMPLETED; 16113513Sgabeblack@google.com } 16213513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 16313513Sgabeblack@google.com return tlm::TLM_COMPLETED; 16413513Sgabeblack@google.com } 16513513Sgabeblack@google.com 16613513Sgabeblack@google.com void 16713513Sgabeblack@google.com invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 16813513Sgabeblack@google.com { 16913513Sgabeblack@google.com return m_owner->bw_invalidate_direct_mem_ptr(s, e); 17013513Sgabeblack@google.com } 17113513Sgabeblack@google.com 17213513Sgabeblack@google.com private: 17313513Sgabeblack@google.com simple_target_socket_b *m_owner; 17413513Sgabeblack@google.com }; 17513513Sgabeblack@google.com 17613513Sgabeblack@google.com class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 17713513Sgabeblack@google.com public tlm::tlm_mm_interface 17813513Sgabeblack@google.com { 17913513Sgabeblack@google.com public: 18013513Sgabeblack@google.com typedef sync_enum_type (MODULE::*NBTransportPtr)( 18113513Sgabeblack@google.com transaction_type &, phase_type &, sc_core::sc_time &); 18213513Sgabeblack@google.com typedef void (MODULE::*BTransportPtr)( 18313513Sgabeblack@google.com transaction_type &, sc_core::sc_time &); 18413513Sgabeblack@google.com typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type &); 18513513Sgabeblack@google.com typedef bool (MODULE::*GetDirectMemPtr)( 18613513Sgabeblack@google.com transaction_type &, tlm::tlm_dmi &); 18713513Sgabeblack@google.com 18813513Sgabeblack@google.com fw_process(simple_target_socket_b *p_own) : 18913513Sgabeblack@google.com m_owner(p_own), m_mod(0), m_nb_transport_ptr(0), 19013513Sgabeblack@google.com m_b_transport_ptr(0), m_transport_dbg_ptr(0), 19113513Sgabeblack@google.com m_get_direct_mem_ptr(0), 19213513Sgabeblack@google.com m_peq(sc_core::sc_gen_unique_name("m_peq")), 19313513Sgabeblack@google.com m_response_in_progress(false) 19413513Sgabeblack@google.com {} 19513513Sgabeblack@google.com 19613513Sgabeblack@google.com void 19713513Sgabeblack@google.com start_of_simulation() 19813513Sgabeblack@google.com { 19913513Sgabeblack@google.com // Only spawn b2nb_thread, if needed. 20013513Sgabeblack@google.com if (!m_b_transport_ptr && m_nb_transport_ptr) { 20113513Sgabeblack@google.com sc_core::sc_spawn_options opts; 20213513Sgabeblack@google.com opts.set_sensitivity(&m_peq.get_event()); 20313513Sgabeblack@google.com opts.dont_initialize(); 20413513Sgabeblack@google.com sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 20513513Sgabeblack@google.com sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 20613513Sgabeblack@google.com } 20713513Sgabeblack@google.com } 20813513Sgabeblack@google.com 20913513Sgabeblack@google.com void 21013513Sgabeblack@google.com set_nb_transport_ptr(MODULE *mod, NBTransportPtr p) 21113513Sgabeblack@google.com { 21213513Sgabeblack@google.com if (m_nb_transport_ptr) { 21313513Sgabeblack@google.com m_owner->display_warning( 21413513Sgabeblack@google.com "non-blocking callback already registered"); 21513513Sgabeblack@google.com return; 21613513Sgabeblack@google.com } 21713513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 21813513Sgabeblack@google.com m_mod = mod; 21913513Sgabeblack@google.com m_nb_transport_ptr = p; 22013513Sgabeblack@google.com } 22113513Sgabeblack@google.com 22213513Sgabeblack@google.com void 22313513Sgabeblack@google.com set_b_transport_ptr(MODULE *mod, BTransportPtr p) 22413513Sgabeblack@google.com { 22513513Sgabeblack@google.com if (m_b_transport_ptr) { 22613513Sgabeblack@google.com m_owner->display_warning( 22713513Sgabeblack@google.com "blocking callback already registered"); 22813513Sgabeblack@google.com return; 22913513Sgabeblack@google.com } 23013513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 23113513Sgabeblack@google.com m_mod = mod; 23213513Sgabeblack@google.com m_b_transport_ptr = p; 23313513Sgabeblack@google.com } 23413513Sgabeblack@google.com 23513513Sgabeblack@google.com void 23613513Sgabeblack@google.com set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p) 23713513Sgabeblack@google.com { 23813513Sgabeblack@google.com if (m_transport_dbg_ptr) { 23913513Sgabeblack@google.com m_owner->display_warning("debug callback already registered"); 24013513Sgabeblack@google.com return; 24113513Sgabeblack@google.com } 24213513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 24313513Sgabeblack@google.com m_mod = mod; 24413513Sgabeblack@google.com m_transport_dbg_ptr = p; 24513513Sgabeblack@google.com } 24613513Sgabeblack@google.com 24713513Sgabeblack@google.com void 24813513Sgabeblack@google.com set_get_direct_mem_ptr(MODULE *mod, GetDirectMemPtr p) 24913513Sgabeblack@google.com { 25013513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 25113513Sgabeblack@google.com m_owner->display_warning( 25213513Sgabeblack@google.com "get DMI pointer callback already registered"); 25313513Sgabeblack@google.com return; 25413513Sgabeblack@google.com } 25513513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 25613513Sgabeblack@google.com m_mod = mod; 25713513Sgabeblack@google.com m_get_direct_mem_ptr = p; 25813513Sgabeblack@google.com } 25913513Sgabeblack@google.com 26013513Sgabeblack@google.com // Interface implementation. 26113513Sgabeblack@google.com sync_enum_type 26213513Sgabeblack@google.com nb_transport_fw(transaction_type &trans, phase_type &phase, 26313513Sgabeblack@google.com sc_core::sc_time & t) 26413513Sgabeblack@google.com { 26513513Sgabeblack@google.com if (m_nb_transport_ptr) { 26613513Sgabeblack@google.com // Forward call. 26713513Sgabeblack@google.com sc_assert(m_mod); 26813513Sgabeblack@google.com return (m_mod->*m_nb_transport_ptr)(trans, phase, t); 26913513Sgabeblack@google.com } 27013513Sgabeblack@google.com 27113513Sgabeblack@google.com // nb->b conversion 27213513Sgabeblack@google.com if (m_b_transport_ptr) { 27313513Sgabeblack@google.com if (phase == tlm::BEGIN_REQ) { 27413513Sgabeblack@google.com // Prepare thread to do blocking call. 27513513Sgabeblack@google.com process_handle_class *ph = 27613513Sgabeblack@google.com m_process_handle.get_handle(&trans); 27713513Sgabeblack@google.com 27813513Sgabeblack@google.com if (!ph) { // Create new dynamic process. 27913513Sgabeblack@google.com ph = new process_handle_class(&trans); 28013513Sgabeblack@google.com m_process_handle.put_handle(ph); 28113513Sgabeblack@google.com 28213513Sgabeblack@google.com sc_core::sc_spawn_options opts; 28313513Sgabeblack@google.com opts.dont_initialize(); 28413513Sgabeblack@google.com opts.set_sensitivity(&ph->m_e); 28513513Sgabeblack@google.com 28613513Sgabeblack@google.com sc_core::sc_spawn( 28713513Sgabeblack@google.com sc_bind(&fw_process::nb2b_thread, this, ph), 28813513Sgabeblack@google.com sc_core::sc_gen_unique_name("nb2b_thread"), 28913513Sgabeblack@google.com &opts); 29013513Sgabeblack@google.com } 29113513Sgabeblack@google.com 29213513Sgabeblack@google.com ph->m_e.notify(t); 29313513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 29413513Sgabeblack@google.com } 29513513Sgabeblack@google.com if (phase == tlm::END_RESP) { 29613513Sgabeblack@google.com m_response_in_progress = false; 29713513Sgabeblack@google.com m_end_response.notify(t); 29813513Sgabeblack@google.com return tlm::TLM_COMPLETED; 29913513Sgabeblack@google.com } 30013513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 30113513Sgabeblack@google.com return tlm::TLM_COMPLETED; 30213513Sgabeblack@google.com } 30313513Sgabeblack@google.com m_owner->display_error( 30413513Sgabeblack@google.com "no non-blocking transport callback registered"); 30513513Sgabeblack@google.com return tlm::TLM_COMPLETED; 30613513Sgabeblack@google.com } 30713513Sgabeblack@google.com 30813513Sgabeblack@google.com void 30913513Sgabeblack@google.com b_transport(transaction_type &trans, sc_core::sc_time &t) 31013513Sgabeblack@google.com { 31113513Sgabeblack@google.com if (m_b_transport_ptr) { 31213513Sgabeblack@google.com // Forward call. 31313513Sgabeblack@google.com sc_assert(m_mod); 31413513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(trans, t); 31513513Sgabeblack@google.com return; 31613513Sgabeblack@google.com } 31713513Sgabeblack@google.com 31813513Sgabeblack@google.com // b->nb conversion 31913513Sgabeblack@google.com if (m_nb_transport_ptr) { 32013513Sgabeblack@google.com m_peq.notify(trans, t); 32113513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 32213513Sgabeblack@google.com 32313513Sgabeblack@google.com mm_end_event_ext mm_ext; 32413513Sgabeblack@google.com const bool mm_added = !trans.has_mm(); 32513513Sgabeblack@google.com 32613513Sgabeblack@google.com if (mm_added) { 32713513Sgabeblack@google.com trans.set_mm(this); 32813513Sgabeblack@google.com trans.set_auto_extension(&mm_ext); 32913513Sgabeblack@google.com trans.acquire(); 33013513Sgabeblack@google.com } 33113513Sgabeblack@google.com 33213513Sgabeblack@google.com // Wait until transaction is finished. 33313513Sgabeblack@google.com sc_core::sc_event end_event; 33413513Sgabeblack@google.com m_owner->m_pending_trans[&trans] = &end_event; 33513513Sgabeblack@google.com sc_core::wait(end_event); 33613513Sgabeblack@google.com 33713513Sgabeblack@google.com if (mm_added) { 33813513Sgabeblack@google.com // Release will not delete the transaction, it will 33913513Sgabeblack@google.com // notify mm_ext.done. 34013513Sgabeblack@google.com trans.release(); 34113513Sgabeblack@google.com if (trans.get_ref_count()) { 34213513Sgabeblack@google.com sc_core::wait(mm_ext.done); 34313513Sgabeblack@google.com } 34413513Sgabeblack@google.com trans.set_mm(0); 34513513Sgabeblack@google.com } 34613513Sgabeblack@google.com return; 34713513Sgabeblack@google.com } 34813513Sgabeblack@google.com 34913513Sgabeblack@google.com // Should not be reached. 35013513Sgabeblack@google.com m_owner->display_error( 35113513Sgabeblack@google.com "no blocking transport callback registered"); 35213513Sgabeblack@google.com } 35313513Sgabeblack@google.com 35413513Sgabeblack@google.com unsigned int 35513513Sgabeblack@google.com transport_dbg(transaction_type &trans) 35613513Sgabeblack@google.com { 35713513Sgabeblack@google.com if (m_transport_dbg_ptr) { 35813513Sgabeblack@google.com // Forward call. 35913513Sgabeblack@google.com sc_assert(m_mod); 36013513Sgabeblack@google.com return (m_mod->*m_transport_dbg_ptr)(trans); 36113513Sgabeblack@google.com } 36213513Sgabeblack@google.com // No debug support. 36313513Sgabeblack@google.com return 0; 36413513Sgabeblack@google.com } 36513513Sgabeblack@google.com 36613513Sgabeblack@google.com bool 36713513Sgabeblack@google.com get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data) 36813513Sgabeblack@google.com { 36913513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 37013513Sgabeblack@google.com // Forward call. 37113513Sgabeblack@google.com sc_assert(m_mod); 37213513Sgabeblack@google.com return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data); 37313513Sgabeblack@google.com } 37413513Sgabeblack@google.com // No DMI support. 37513513Sgabeblack@google.com dmi_data.allow_read_write(); 37613513Sgabeblack@google.com dmi_data.set_start_address(0x0); 37713513Sgabeblack@google.com dmi_data.set_end_address((sc_dt::uint64)-1); 37813513Sgabeblack@google.com return false; 37913513Sgabeblack@google.com } 38013513Sgabeblack@google.com 38113513Sgabeblack@google.com private: 38213513Sgabeblack@google.com 38313513Sgabeblack@google.com // Dynamic process handler for nb2b conversion. 38413513Sgabeblack@google.com 38513513Sgabeblack@google.com class process_handle_class 38613513Sgabeblack@google.com { 38713513Sgabeblack@google.com public: 38813513Sgabeblack@google.com explicit process_handle_class(transaction_type *trans) : 38913513Sgabeblack@google.com m_trans(trans), m_suspend(false) 39013513Sgabeblack@google.com {} 39113513Sgabeblack@google.com 39213513Sgabeblack@google.com transaction_type *m_trans; 39313513Sgabeblack@google.com sc_core::sc_event m_e; 39413513Sgabeblack@google.com bool m_suspend; 39513513Sgabeblack@google.com }; 39613513Sgabeblack@google.com 39713513Sgabeblack@google.com class process_handle_list 39813513Sgabeblack@google.com { 39913513Sgabeblack@google.com public: 40013513Sgabeblack@google.com process_handle_list() {} 40113513Sgabeblack@google.com 40213513Sgabeblack@google.com ~process_handle_list() 40313513Sgabeblack@google.com { 40413513Sgabeblack@google.com for (typename std::vector< 40513513Sgabeblack@google.com process_handle_class *>::iterator it = v.begin(), 40613513Sgabeblack@google.com end = v.end(); it != end; ++it) { 40713513Sgabeblack@google.com delete *it; 40813513Sgabeblack@google.com } 40913513Sgabeblack@google.com } 41013513Sgabeblack@google.com 41113513Sgabeblack@google.com process_handle_class * 41213513Sgabeblack@google.com get_handle(transaction_type *trans) 41313513Sgabeblack@google.com { 41413513Sgabeblack@google.com typename std::vector<process_handle_class *>::iterator it; 41513513Sgabeblack@google.com 41613513Sgabeblack@google.com for (it = v.begin(); it != v.end(); it++) { 41713513Sgabeblack@google.com if ((*it)->m_suspend) { 41813513Sgabeblack@google.com // Found suspended dynamic process, re-use it. 41913513Sgabeblack@google.com (*it)->m_trans = trans; // Replace to new one. 42013513Sgabeblack@google.com (*it)->m_suspend = false; 42113513Sgabeblack@google.com return *it; 42213513Sgabeblack@google.com } 42313513Sgabeblack@google.com } 42413513Sgabeblack@google.com return NULL; // No suspended process. 42513513Sgabeblack@google.com } 42613513Sgabeblack@google.com 42713513Sgabeblack@google.com void 42813513Sgabeblack@google.com put_handle(process_handle_class *ph) 42913513Sgabeblack@google.com { 43013513Sgabeblack@google.com v.push_back(ph); 43113513Sgabeblack@google.com } 43213513Sgabeblack@google.com 43313513Sgabeblack@google.com private: 43413513Sgabeblack@google.com std::vector<process_handle_class*> v; 43513513Sgabeblack@google.com }; 43613513Sgabeblack@google.com 43713513Sgabeblack@google.com process_handle_list m_process_handle; 43813513Sgabeblack@google.com 43913513Sgabeblack@google.com void 44013513Sgabeblack@google.com nb2b_thread(process_handle_class *h) 44113513Sgabeblack@google.com { 44213513Sgabeblack@google.com while (1) { 44313513Sgabeblack@google.com transaction_type *trans = h->m_trans; 44413513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 44513513Sgabeblack@google.com 44613513Sgabeblack@google.com // Forward call. 44713513Sgabeblack@google.com sc_assert(m_mod); 44813513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(*trans, t); 44913513Sgabeblack@google.com 45013513Sgabeblack@google.com sc_core::wait(t); 45113513Sgabeblack@google.com 45213513Sgabeblack@google.com // Return path. 45313513Sgabeblack@google.com while (m_response_in_progress) { 45413513Sgabeblack@google.com sc_core::wait(m_end_response); 45513513Sgabeblack@google.com } 45613513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 45713513Sgabeblack@google.com phase_type phase = tlm::BEGIN_RESP; 45813513Sgabeblack@google.com sync_enum_type sync = 45913513Sgabeblack@google.com m_owner->bw_nb_transport(*trans, phase, t); 46013513Sgabeblack@google.com if (!(sync == tlm::TLM_COMPLETED || 46113513Sgabeblack@google.com (sync == tlm::TLM_UPDATED && 46213513Sgabeblack@google.com phase == tlm::END_RESP))) { 46313513Sgabeblack@google.com m_response_in_progress = true; 46413513Sgabeblack@google.com } 46513513Sgabeblack@google.com 46613513Sgabeblack@google.com // Suspend until next transaction. 46713513Sgabeblack@google.com h->m_suspend = true; 46813513Sgabeblack@google.com sc_core::wait(); 46913513Sgabeblack@google.com } 47013513Sgabeblack@google.com } 47113513Sgabeblack@google.com 47213513Sgabeblack@google.com void 47313513Sgabeblack@google.com b2nb_thread() 47413513Sgabeblack@google.com { 47513513Sgabeblack@google.com while (true) { 47613513Sgabeblack@google.com transaction_type *trans; 47713513Sgabeblack@google.com while ((trans = m_peq.get_next_transaction()) != 0) { 47813513Sgabeblack@google.com sc_assert(m_mod); 47913513Sgabeblack@google.com sc_assert(m_nb_transport_ptr); 48013513Sgabeblack@google.com phase_type phase = tlm::BEGIN_REQ; 48113513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 48213513Sgabeblack@google.com 48313513Sgabeblack@google.com switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) { 48413513Sgabeblack@google.com case tlm::TLM_COMPLETED: 48513513Sgabeblack@google.com { 48613513Sgabeblack@google.com // Notify transaction is finished. 48713513Sgabeblack@google.com typename std::map<transaction_type *, 48813513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 48913513Sgabeblack@google.com m_owner->m_pending_trans.find(trans); 49013513Sgabeblack@google.com sc_assert(it != m_owner->m_pending_trans.end()); 49113513Sgabeblack@google.com it->second->notify(t); 49213513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 49313513Sgabeblack@google.com break; 49413513Sgabeblack@google.com } 49513513Sgabeblack@google.com 49613513Sgabeblack@google.com case tlm::TLM_ACCEPTED: 49713513Sgabeblack@google.com case tlm::TLM_UPDATED: 49813513Sgabeblack@google.com switch (phase) { 49913513Sgabeblack@google.com case tlm::BEGIN_REQ: 50013513Sgabeblack@google.com m_owner->m_current_transaction = trans; 50113513Sgabeblack@google.com sc_core::wait(m_owner->m_end_request); 50213513Sgabeblack@google.com m_owner->m_current_transaction = 0; 50313513Sgabeblack@google.com break; 50413513Sgabeblack@google.com 50513513Sgabeblack@google.com case tlm::END_REQ: 50613513Sgabeblack@google.com sc_core::wait(t); 50713513Sgabeblack@google.com break; 50813513Sgabeblack@google.com 50913513Sgabeblack@google.com case tlm::BEGIN_RESP: 51013513Sgabeblack@google.com { 51113513Sgabeblack@google.com phase = tlm::END_RESP; 51213513Sgabeblack@google.com // This line is a bug fix added in TLM-2.0.2 51313513Sgabeblack@google.com sc_core::wait(t); 51413513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 51513513Sgabeblack@google.com (m_mod->*m_nb_transport_ptr)( 51613513Sgabeblack@google.com *trans, phase, t); 51713513Sgabeblack@google.com 51813513Sgabeblack@google.com // Notify transaction is finished. 51913513Sgabeblack@google.com typename std::map<transaction_type *, 52013513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 52113513Sgabeblack@google.com m_owner->m_pending_trans.find( 52213513Sgabeblack@google.com trans); 52313513Sgabeblack@google.com sc_assert(it != 52413513Sgabeblack@google.com m_owner->m_pending_trans.end()); 52513513Sgabeblack@google.com it->second->notify(t); 52613513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 52713513Sgabeblack@google.com break; 52813513Sgabeblack@google.com } 52913513Sgabeblack@google.com 53013513Sgabeblack@google.com default: 53113513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 53213513Sgabeblack@google.com } 53313513Sgabeblack@google.com break; 53413513Sgabeblack@google.com 53513513Sgabeblack@google.com default: 53613513Sgabeblack@google.com m_owner->display_error("invalid sync value received"); 53713513Sgabeblack@google.com } 53813513Sgabeblack@google.com } 53913513Sgabeblack@google.com sc_core::wait(); 54013513Sgabeblack@google.com } 54113513Sgabeblack@google.com } 54213513Sgabeblack@google.com 54313513Sgabeblack@google.com void 54413513Sgabeblack@google.com free(tlm::tlm_generic_payload *trans) 54513513Sgabeblack@google.com { 54613513Sgabeblack@google.com mm_end_event_ext *ext = 54713513Sgabeblack@google.com trans->template get_extension<mm_end_event_ext>(); 54813513Sgabeblack@google.com sc_assert(ext); 54913513Sgabeblack@google.com // Notify event first before freeing extensions (reset). 55013513Sgabeblack@google.com ext->done.notify(); 55113513Sgabeblack@google.com trans->reset(); 55213513Sgabeblack@google.com } 55313513Sgabeblack@google.com 55413513Sgabeblack@google.com private: 55513513Sgabeblack@google.com struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 55613513Sgabeblack@google.com { 55713513Sgabeblack@google.com tlm::tlm_extension_base *clone() const { return NULL; } 55813513Sgabeblack@google.com void free() {} 55913513Sgabeblack@google.com void copy_from(tlm::tlm_extension_base const &) {} 56013513Sgabeblack@google.com sc_core::sc_event done; 56113513Sgabeblack@google.com }; 56213513Sgabeblack@google.com 56313513Sgabeblack@google.com private: 56413513Sgabeblack@google.com simple_target_socket_b *m_owner; 56513513Sgabeblack@google.com MODULE *m_mod; 56613513Sgabeblack@google.com NBTransportPtr m_nb_transport_ptr; 56713513Sgabeblack@google.com BTransportPtr m_b_transport_ptr; 56813513Sgabeblack@google.com TransportDbgPtr m_transport_dbg_ptr; 56913513Sgabeblack@google.com GetDirectMemPtr m_get_direct_mem_ptr; 57013513Sgabeblack@google.com peq_with_get<transaction_type> m_peq; 57113513Sgabeblack@google.com bool m_response_in_progress; 57213513Sgabeblack@google.com sc_core::sc_event m_end_response; 57313513Sgabeblack@google.com }; 57413513Sgabeblack@google.com 57513513Sgabeblack@google.com private: 57613513Sgabeblack@google.com const sc_core::sc_object *get_socket() const { return this; } 57713513Sgabeblack@google.com 57813513Sgabeblack@google.com private: 57913513Sgabeblack@google.com fw_process m_fw_process; 58013513Sgabeblack@google.com bw_process m_bw_process; 58113513Sgabeblack@google.com std::map<transaction_type *, sc_core::sc_event *> m_pending_trans; 58213513Sgabeblack@google.com sc_core::sc_event m_end_request; 58313513Sgabeblack@google.com transaction_type* m_current_transaction; 58413513Sgabeblack@google.com}; 58513513Sgabeblack@google.com 58613513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 58713513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 58813513Sgabeblack@google.comclass simple_target_socket : 58913513Sgabeblack@google.com public simple_target_socket_b<MODULE, BUSWIDTH, TYPES> 59013513Sgabeblack@google.com{ 59113513Sgabeblack@google.com typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES> socket_b; 59213513Sgabeblack@google.com public: 59313513Sgabeblack@google.com simple_target_socket() : socket_b() {} 59413513Sgabeblack@google.com explicit simple_target_socket(const char *name) : socket_b(name) {} 59513513Sgabeblack@google.com}; 59613513Sgabeblack@google.com 59713513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 59813513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 59913513Sgabeblack@google.comclass simple_target_socket_optional : 60013513Sgabeblack@google.com public simple_target_socket_b<MODULE, BUSWIDTH, TYPES, 60113513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> 60213513Sgabeblack@google.com{ 60313513Sgabeblack@google.com typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES, 60413513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 60513513Sgabeblack@google.com public: 60613513Sgabeblack@google.com simple_target_socket_optional() : socket_b() {} 60713513Sgabeblack@google.com explicit simple_target_socket_optional(const char *name) : 60813513Sgabeblack@google.com socket_b(name) 60913513Sgabeblack@google.com {} 61013513Sgabeblack@google.com}; 61113513Sgabeblack@google.com 61213513Sgabeblack@google.com// ID Tagged version. 61313513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 61413513Sgabeblack@google.com sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 61513513Sgabeblack@google.comclass simple_target_socket_tagged_b : 61613513Sgabeblack@google.com public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>, 61713513Sgabeblack@google.com protected simple_socket_base 61813513Sgabeblack@google.com{ 61913513Sgabeblack@google.com friend class fw_process; 62013513Sgabeblack@google.com friend class bw_process; 62113513Sgabeblack@google.com public: 62213513Sgabeblack@google.com typedef typename TYPES::tlm_payload_type transaction_type; 62313513Sgabeblack@google.com typedef typename TYPES::tlm_phase_type phase_type; 62413513Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 62513513Sgabeblack@google.com typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 62613513Sgabeblack@google.com typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 62713513Sgabeblack@google.com typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type; 62813513Sgabeblack@google.com 62913513Sgabeblack@google.com public: 63013513Sgabeblack@google.com static const char * 63113513Sgabeblack@google.com default_name() 63213513Sgabeblack@google.com { 63313513Sgabeblack@google.com return sc_core::sc_gen_unique_name("simple_target_socket_tagged"); 63413511Sgabeblack@google.com } 63513511Sgabeblack@google.com 63613513Sgabeblack@google.com explicit simple_target_socket_tagged_b(const char *n=default_name()) : 63713513Sgabeblack@google.com base_type(n), m_fw_process(this), m_bw_process(this) 63813511Sgabeblack@google.com { 63913513Sgabeblack@google.com bind(m_fw_process); 64013511Sgabeblack@google.com } 64113511Sgabeblack@google.com 64213513Sgabeblack@google.com using base_type::bind; 64313513Sgabeblack@google.com 64413513Sgabeblack@google.com // bw transport must come through us. 64513513Sgabeblack@google.com tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; } 64613513Sgabeblack@google.com 64713513Sgabeblack@google.com // REGISTER_XXX 64813513Sgabeblack@google.com void 64913513Sgabeblack@google.com register_nb_transport_fw(MODULE *mod, 65013513Sgabeblack@google.com sync_enum_type (MODULE::*cb)(int id, transaction_type &, 65113513Sgabeblack@google.com phase_type &, sc_core::sc_time &), 65213513Sgabeblack@google.com int id) 65313511Sgabeblack@google.com { 65413513Sgabeblack@google.com elaboration_check("register_nb_transport_fw"); 65513513Sgabeblack@google.com m_fw_process.set_nb_transport_ptr(mod, cb); 65613513Sgabeblack@google.com m_fw_process.set_nb_transport_user_id(id); 65713511Sgabeblack@google.com } 65813511Sgabeblack@google.com 65913513Sgabeblack@google.com void 66013513Sgabeblack@google.com register_b_transport(MODULE *mod, 66113513Sgabeblack@google.com void (MODULE::*cb)(int id, transaction_type &, 66213513Sgabeblack@google.com sc_core::sc_time &), 66313513Sgabeblack@google.com int id) 66413511Sgabeblack@google.com { 66513513Sgabeblack@google.com elaboration_check("register_b_transport"); 66613513Sgabeblack@google.com m_fw_process.set_b_transport_ptr(mod, cb); 66713513Sgabeblack@google.com m_fw_process.set_b_transport_user_id(id); 66813511Sgabeblack@google.com } 66913511Sgabeblack@google.com 67013513Sgabeblack@google.com void 67113513Sgabeblack@google.com register_transport_dbg(MODULE *mod, 67213513Sgabeblack@google.com unsigned int (MODULE::*cb)(int id, transaction_type &), int id) 67313511Sgabeblack@google.com { 67413513Sgabeblack@google.com elaboration_check("register_transport_dbg"); 67513513Sgabeblack@google.com m_fw_process.set_transport_dbg_ptr(mod, cb); 67613513Sgabeblack@google.com m_fw_process.set_transport_dbg_user_id(id); 67713511Sgabeblack@google.com } 67813511Sgabeblack@google.com 67913513Sgabeblack@google.com void 68013513Sgabeblack@google.com register_get_direct_mem_ptr(MODULE *mod, 68113513Sgabeblack@google.com bool (MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), 68213513Sgabeblack@google.com int id) 68313511Sgabeblack@google.com { 68413513Sgabeblack@google.com elaboration_check("register_get_direct_mem_ptr"); 68513513Sgabeblack@google.com m_fw_process.set_get_direct_mem_ptr(mod, cb); 68613513Sgabeblack@google.com m_fw_process.set_get_dmi_user_id(id); 68713513Sgabeblack@google.com } 68813513Sgabeblack@google.com 68913513Sgabeblack@google.com protected: 69013513Sgabeblack@google.com void 69113513Sgabeblack@google.com start_of_simulation() 69213513Sgabeblack@google.com { 69313513Sgabeblack@google.com base_type::start_of_simulation(); 69413513Sgabeblack@google.com m_fw_process.start_of_simulation(); 69513511Sgabeblack@google.com } 69613511Sgabeblack@google.com 69713511Sgabeblack@google.com private: 69813513Sgabeblack@google.com // Make call on bw path. 69913513Sgabeblack@google.com sync_enum_type 70013513Sgabeblack@google.com bw_nb_transport(transaction_type &trans, phase_type &phase, 70113513Sgabeblack@google.com sc_core::sc_time &t) 70213513Sgabeblack@google.com { 70313513Sgabeblack@google.com return base_type::operator -> ()->nb_transport_bw(trans, phase, t); 70413513Sgabeblack@google.com } 70513511Sgabeblack@google.com 70613513Sgabeblack@google.com void 70713513Sgabeblack@google.com bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 70813513Sgabeblack@google.com { 70913513Sgabeblack@google.com base_type::operator -> ()->invalidate_direct_mem_ptr(s, e); 71013513Sgabeblack@google.com } 71113511Sgabeblack@google.com 71213513Sgabeblack@google.com // Helper class to handle bw path calls Needed to detect transaction 71313513Sgabeblack@google.com // end when called from b_transport. 71413513Sgabeblack@google.com class bw_process : public tlm::tlm_bw_transport_if<TYPES> 71513513Sgabeblack@google.com { 71613513Sgabeblack@google.com public: 71713513Sgabeblack@google.com bw_process(simple_target_socket_tagged_b *p_own) : m_owner(p_own) {} 71813511Sgabeblack@google.com 71913513Sgabeblack@google.com sync_enum_type 72013513Sgabeblack@google.com nb_transport_bw(transaction_type &trans, phase_type &phase, 72113513Sgabeblack@google.com sc_core::sc_time &t) 72213513Sgabeblack@google.com { 72313513Sgabeblack@google.com typename std::map<transaction_type *, 72413513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 72513513Sgabeblack@google.com m_owner->m_pending_trans.find(&trans); 72613513Sgabeblack@google.com 72713513Sgabeblack@google.com if (it == m_owner->m_pending_trans.end()) { 72813513Sgabeblack@google.com // Not a blocking call, forward. 72913513Sgabeblack@google.com return m_owner->bw_nb_transport(trans, phase, t); 73013513Sgabeblack@google.com } 73113513Sgabeblack@google.com if (phase == tlm::END_REQ) { 73213513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 73313513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 73413513Sgabeblack@google.com } 73513513Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 73613513Sgabeblack@google.com if (m_owner->m_current_transaction == &trans) { 73713513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 73813513Sgabeblack@google.com } 73913513Sgabeblack@google.com it->second->notify(t); 74013513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 74113513Sgabeblack@google.com return tlm::TLM_COMPLETED; 74213513Sgabeblack@google.com } 74313513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 74413513Sgabeblack@google.com return tlm::TLM_COMPLETED; 74513513Sgabeblack@google.com } 74613513Sgabeblack@google.com 74713513Sgabeblack@google.com void 74813513Sgabeblack@google.com invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 74913513Sgabeblack@google.com { 75013513Sgabeblack@google.com return m_owner->bw_invalidate_direct_mem_ptr(s, e); 75113513Sgabeblack@google.com } 75213513Sgabeblack@google.com 75313513Sgabeblack@google.com private: 75413513Sgabeblack@google.com simple_target_socket_tagged_b *m_owner; 75513511Sgabeblack@google.com }; 75613511Sgabeblack@google.com 75713513Sgabeblack@google.com class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 75813513Sgabeblack@google.com public tlm::tlm_mm_interface 75913513Sgabeblack@google.com { 76013513Sgabeblack@google.com public: 76113513Sgabeblack@google.com typedef sync_enum_type (MODULE::*NBTransportPtr)( 76213513Sgabeblack@google.com int id, transaction_type &, phase_type &, 76313513Sgabeblack@google.com sc_core::sc_time &); 76413513Sgabeblack@google.com typedef void (MODULE::*BTransportPtr)( 76513513Sgabeblack@google.com int id, transaction_type &, sc_core::sc_time &); 76613513Sgabeblack@google.com typedef unsigned int (MODULE::*TransportDbgPtr)( 76713513Sgabeblack@google.com int id, transaction_type &); 76813513Sgabeblack@google.com typedef bool (MODULE::*GetDirectMemPtr)( 76913513Sgabeblack@google.com int id, transaction_type &, tlm::tlm_dmi &); 77013511Sgabeblack@google.com 77113513Sgabeblack@google.com fw_process(simple_target_socket_tagged_b *p_own) : 77213513Sgabeblack@google.com m_owner(p_own), m_mod(0), m_nb_transport_ptr(0), 77313513Sgabeblack@google.com m_b_transport_ptr(0), m_transport_dbg_ptr(0), 77413513Sgabeblack@google.com m_get_direct_mem_ptr(0), m_nb_transport_user_id(0), 77513513Sgabeblack@google.com m_b_transport_user_id(0), m_transport_dbg_user_id(0), 77613513Sgabeblack@google.com m_get_dmi_user_id(0), 77713513Sgabeblack@google.com m_peq(sc_core::sc_gen_unique_name("m_peq")), 77813513Sgabeblack@google.com m_response_in_progress(false) 77913513Sgabeblack@google.com {} 78013511Sgabeblack@google.com 78113513Sgabeblack@google.com void 78213513Sgabeblack@google.com start_of_simulation() 78313513Sgabeblack@google.com { 78413513Sgabeblack@google.com if (!m_b_transport_ptr && m_nb_transport_ptr) { 78513513Sgabeblack@google.com // Only spawn b2nb_thread if needed. 78613513Sgabeblack@google.com sc_core::sc_spawn_options opts; 78713513Sgabeblack@google.com opts.set_sensitivity(&m_peq.get_event()); 78813513Sgabeblack@google.com opts.dont_initialize(); 78913513Sgabeblack@google.com sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 79013513Sgabeblack@google.com sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 79113513Sgabeblack@google.com } 79213511Sgabeblack@google.com } 79313511Sgabeblack@google.com 79413513Sgabeblack@google.com void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; } 79513513Sgabeblack@google.com void set_b_transport_user_id(int id) { m_b_transport_user_id = id; } 79613513Sgabeblack@google.com void 79713513Sgabeblack@google.com set_transport_dbg_user_id(int id) 79813513Sgabeblack@google.com { 79913513Sgabeblack@google.com m_transport_dbg_user_id = id; 80013513Sgabeblack@google.com } 80113513Sgabeblack@google.com void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; } 80213511Sgabeblack@google.com 80313513Sgabeblack@google.com void 80413513Sgabeblack@google.com set_nb_transport_ptr(MODULE *mod, NBTransportPtr p) 80513513Sgabeblack@google.com { 80613513Sgabeblack@google.com if (m_nb_transport_ptr) { 80713513Sgabeblack@google.com m_owner->display_warning( 80813513Sgabeblack@google.com "non-blocking callback already registered"); 80913513Sgabeblack@google.com return; 81013513Sgabeblack@google.com } 81113513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 81213513Sgabeblack@google.com m_mod = mod; 81313513Sgabeblack@google.com m_nb_transport_ptr = p; 81413513Sgabeblack@google.com } 81513511Sgabeblack@google.com 81613513Sgabeblack@google.com void 81713513Sgabeblack@google.com set_b_transport_ptr(MODULE* mod, BTransportPtr p) 81813513Sgabeblack@google.com { 81913513Sgabeblack@google.com if (m_b_transport_ptr) { 82013513Sgabeblack@google.com m_owner->display_warning( 82113513Sgabeblack@google.com "blocking callback already registered"); 82213513Sgabeblack@google.com return; 82313513Sgabeblack@google.com } 82413513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 82513513Sgabeblack@google.com m_mod = mod; 82613513Sgabeblack@google.com m_b_transport_ptr = p; 82713513Sgabeblack@google.com } 82813511Sgabeblack@google.com 82913513Sgabeblack@google.com void 83013513Sgabeblack@google.com set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p) 83113513Sgabeblack@google.com { 83213513Sgabeblack@google.com if (m_transport_dbg_ptr) { 83313513Sgabeblack@google.com m_owner->display_warning( 83413513Sgabeblack@google.com "debug callback already registered"); 83513513Sgabeblack@google.com return; 83613513Sgabeblack@google.com } 83713513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 83813513Sgabeblack@google.com m_mod = mod; 83913513Sgabeblack@google.com m_transport_dbg_ptr = p; 84013513Sgabeblack@google.com } 84113511Sgabeblack@google.com 84213513Sgabeblack@google.com void 84313513Sgabeblack@google.com set_get_direct_mem_ptr(MODULE *mod, GetDirectMemPtr p) 84413513Sgabeblack@google.com { 84513513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 84613513Sgabeblack@google.com m_owner->display_warning( 84713513Sgabeblack@google.com "get DMI pointer callback already registered"); 84813513Sgabeblack@google.com } 84913513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 85013513Sgabeblack@google.com m_mod = mod; 85113513Sgabeblack@google.com m_get_direct_mem_ptr = p; 85213513Sgabeblack@google.com } 85313511Sgabeblack@google.com 85413513Sgabeblack@google.com // Interface implementation. 85513513Sgabeblack@google.com sync_enum_type 85613513Sgabeblack@google.com nb_transport_fw(transaction_type &trans, phase_type &phase, 85713513Sgabeblack@google.com sc_core::sc_time &t) 85813513Sgabeblack@google.com { 85913513Sgabeblack@google.com if (m_nb_transport_ptr) { 86013513Sgabeblack@google.com // Forward call. 86113513Sgabeblack@google.com sc_assert(m_mod); 86213513Sgabeblack@google.com return (m_mod->*m_nb_transport_ptr)( 86313513Sgabeblack@google.com m_nb_transport_user_id, trans, phase, t); 86413511Sgabeblack@google.com } 86513511Sgabeblack@google.com 86613513Sgabeblack@google.com // nb->b conversion 86713513Sgabeblack@google.com if (m_b_transport_ptr) { 86813513Sgabeblack@google.com if (phase == tlm::BEGIN_REQ) { 86913513Sgabeblack@google.com 87013513Sgabeblack@google.com // Prepare thread to do blocking call. 87113513Sgabeblack@google.com process_handle_class *ph = 87213513Sgabeblack@google.com m_process_handle.get_handle(&trans); 87313513Sgabeblack@google.com 87413513Sgabeblack@google.com if (!ph) { // Create new dynamic process. 87513513Sgabeblack@google.com ph = new process_handle_class(&trans); 87613513Sgabeblack@google.com m_process_handle.put_handle(ph); 87713513Sgabeblack@google.com 87813513Sgabeblack@google.com sc_core::sc_spawn_options opts; 87913513Sgabeblack@google.com opts.dont_initialize(); 88013513Sgabeblack@google.com opts.set_sensitivity(&ph->m_e); 88113513Sgabeblack@google.com 88213513Sgabeblack@google.com sc_core::sc_spawn( 88313513Sgabeblack@google.com sc_bind(&fw_process::nb2b_thread, this, ph), 88413513Sgabeblack@google.com sc_core::sc_gen_unique_name("nb2b_thread"), 88513513Sgabeblack@google.com &opts); 88613513Sgabeblack@google.com } 88713513Sgabeblack@google.com 88813513Sgabeblack@google.com ph->m_e.notify(t); 88913513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 89013513Sgabeblack@google.com } 89113513Sgabeblack@google.com if (phase == tlm::END_RESP) { 89213513Sgabeblack@google.com m_response_in_progress = false; 89313513Sgabeblack@google.com m_end_response.notify(t); 89413513Sgabeblack@google.com return tlm::TLM_COMPLETED; 89513513Sgabeblack@google.com } 89613513Sgabeblack@google.com m_owner->display_error("invalid phase"); 89713513Sgabeblack@google.com return tlm::TLM_COMPLETED; 89813511Sgabeblack@google.com } 89913511Sgabeblack@google.com 90013513Sgabeblack@google.com m_owner->display_error( 90113513Sgabeblack@google.com "no non-blocking transport callback registered"); 90213513Sgabeblack@google.com return tlm::TLM_COMPLETED; 90313511Sgabeblack@google.com } 90413511Sgabeblack@google.com 90513513Sgabeblack@google.com void 90613513Sgabeblack@google.com b_transport(transaction_type &trans, sc_core::sc_time &t) 90713513Sgabeblack@google.com { 90813513Sgabeblack@google.com if (m_b_transport_ptr) { 90913513Sgabeblack@google.com // Forward call. 91013513Sgabeblack@google.com sc_assert(m_mod); 91113513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t); 91213513Sgabeblack@google.com return; 91313513Sgabeblack@google.com } 91413511Sgabeblack@google.com 91513513Sgabeblack@google.com // b->nb conversion 91613513Sgabeblack@google.com if (m_nb_transport_ptr) { 91713513Sgabeblack@google.com m_peq.notify(trans, t); 91813513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 91913513Sgabeblack@google.com 92013513Sgabeblack@google.com mm_end_event_ext mm_ext; 92113513Sgabeblack@google.com const bool mm_added = !trans.has_mm(); 92213513Sgabeblack@google.com 92313513Sgabeblack@google.com if (mm_added) { 92413513Sgabeblack@google.com trans.set_mm(this); 92513513Sgabeblack@google.com trans.set_auto_extension(&mm_ext); 92613513Sgabeblack@google.com trans.acquire(); 92713513Sgabeblack@google.com } 92813513Sgabeblack@google.com 92913513Sgabeblack@google.com // Wait until transaction is finished. 93013513Sgabeblack@google.com sc_core::sc_event end_event; 93113513Sgabeblack@google.com m_owner->m_pending_trans[&trans] = &end_event; 93213513Sgabeblack@google.com sc_core::wait(end_event); 93313513Sgabeblack@google.com 93413513Sgabeblack@google.com if (mm_added) { 93513513Sgabeblack@google.com // Release will not delete the transaction, it will 93613513Sgabeblack@google.com // notify mm_ext.done. 93713513Sgabeblack@google.com trans.release(); 93813513Sgabeblack@google.com if (trans.get_ref_count()) { 93913513Sgabeblack@google.com sc_core::wait(mm_ext.done); 94013513Sgabeblack@google.com } 94113513Sgabeblack@google.com trans.set_mm(0); 94213513Sgabeblack@google.com } 94313513Sgabeblack@google.com return; 94413513Sgabeblack@google.com } 94513513Sgabeblack@google.com 94613513Sgabeblack@google.com m_owner->display_error("no transport callback registered"); 94713513Sgabeblack@google.com } 94813513Sgabeblack@google.com 94913513Sgabeblack@google.com unsigned int 95013513Sgabeblack@google.com transport_dbg(transaction_type &trans) 95113513Sgabeblack@google.com { 95213513Sgabeblack@google.com if (m_transport_dbg_ptr) { 95313513Sgabeblack@google.com // Forward call. 95413513Sgabeblack@google.com sc_assert(m_mod); 95513513Sgabeblack@google.com return (m_mod->*m_transport_dbg_ptr)( 95613513Sgabeblack@google.com m_transport_dbg_user_id, trans); 95713513Sgabeblack@google.com } 95813513Sgabeblack@google.com // No debug support. 95913513Sgabeblack@google.com return 0; 96013513Sgabeblack@google.com } 96113513Sgabeblack@google.com 96213513Sgabeblack@google.com bool 96313513Sgabeblack@google.com get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data) 96413513Sgabeblack@google.com { 96513513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 96613513Sgabeblack@google.com // Forward call. 96713513Sgabeblack@google.com sc_assert(m_mod); 96813513Sgabeblack@google.com return (m_mod->*m_get_direct_mem_ptr)( 96913513Sgabeblack@google.com m_get_dmi_user_id, trans, dmi_data); 97013513Sgabeblack@google.com } 97113513Sgabeblack@google.com // No DMI support. 97213513Sgabeblack@google.com dmi_data.allow_read_write(); 97313513Sgabeblack@google.com dmi_data.set_start_address(0x0); 97413513Sgabeblack@google.com dmi_data.set_end_address((sc_dt::uint64)-1); 97513513Sgabeblack@google.com return false; 97613513Sgabeblack@google.com } 97713513Sgabeblack@google.com 97813513Sgabeblack@google.com private: 97913513Sgabeblack@google.com 98013513Sgabeblack@google.com // Dynamic process handler for nb2b conversion. 98113513Sgabeblack@google.com class process_handle_class 98213513Sgabeblack@google.com { 98313513Sgabeblack@google.com public: 98413513Sgabeblack@google.com explicit process_handle_class(transaction_type *trans) : 98513513Sgabeblack@google.com m_trans(trans), m_suspend(false) 98613513Sgabeblack@google.com {} 98713513Sgabeblack@google.com 98813513Sgabeblack@google.com transaction_type *m_trans; 98913513Sgabeblack@google.com sc_core::sc_event m_e; 99013513Sgabeblack@google.com bool m_suspend; 99113513Sgabeblack@google.com }; 99213513Sgabeblack@google.com 99313513Sgabeblack@google.com class process_handle_list 99413513Sgabeblack@google.com { 99513513Sgabeblack@google.com public: 99613513Sgabeblack@google.com process_handle_list() {} 99713513Sgabeblack@google.com 99813513Sgabeblack@google.com ~process_handle_list() 99913513Sgabeblack@google.com { 100013513Sgabeblack@google.com for (typename std::vector< 100113513Sgabeblack@google.com process_handle_class *>::iterator it = v.begin(), 100213513Sgabeblack@google.com end = v.end(); it != end; ++it) { 100313513Sgabeblack@google.com delete *it; 100413513Sgabeblack@google.com } 100513513Sgabeblack@google.com } 100613513Sgabeblack@google.com 100713513Sgabeblack@google.com process_handle_class * 100813513Sgabeblack@google.com get_handle(transaction_type *trans) 100913513Sgabeblack@google.com { 101013513Sgabeblack@google.com typename std::vector<process_handle_class *>::iterator it; 101113513Sgabeblack@google.com 101213513Sgabeblack@google.com for (it = v.begin(); it != v.end(); it++) { 101313513Sgabeblack@google.com if ((*it)->m_suspend) { 101413513Sgabeblack@google.com // Found suspended dynamic process, re-use it. 101513513Sgabeblack@google.com (*it)->m_trans = trans; // Replace to new one. 101613513Sgabeblack@google.com (*it)->m_suspend = false; 101713513Sgabeblack@google.com return *it; 101813513Sgabeblack@google.com } 101913513Sgabeblack@google.com } 102013513Sgabeblack@google.com return NULL; // No suspended process. 102113513Sgabeblack@google.com } 102213513Sgabeblack@google.com 102313513Sgabeblack@google.com void put_handle(process_handle_class *ph) { v.push_back(ph); } 102413513Sgabeblack@google.com 102513513Sgabeblack@google.com private: 102613513Sgabeblack@google.com std::vector<process_handle_class *> v; 102713513Sgabeblack@google.com }; 102813513Sgabeblack@google.com 102913513Sgabeblack@google.com process_handle_list m_process_handle; 103013513Sgabeblack@google.com 103113513Sgabeblack@google.com void 103213513Sgabeblack@google.com nb2b_thread(process_handle_class *h) 103313513Sgabeblack@google.com { 103413513Sgabeblack@google.com 103513513Sgabeblack@google.com while (1) { 103613513Sgabeblack@google.com transaction_type *trans = h->m_trans; 103713513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 103813513Sgabeblack@google.com 103913513Sgabeblack@google.com // Forward call. 104013513Sgabeblack@google.com sc_assert(m_mod); 104113513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)( 104213513Sgabeblack@google.com m_b_transport_user_id, *trans, t); 104313513Sgabeblack@google.com 104413513Sgabeblack@google.com sc_core::wait(t); 104513513Sgabeblack@google.com 104613513Sgabeblack@google.com // Return path. 104713513Sgabeblack@google.com while (m_response_in_progress) { 104813513Sgabeblack@google.com sc_core::wait(m_end_response); 104913513Sgabeblack@google.com } 105013513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 105113513Sgabeblack@google.com phase_type phase = tlm::BEGIN_RESP; 105213513Sgabeblack@google.com sync_enum_type sync = 105313513Sgabeblack@google.com m_owner->bw_nb_transport(*trans, phase, t); 105413513Sgabeblack@google.com if (!(sync == tlm::TLM_COMPLETED || 105513513Sgabeblack@google.com (sync == tlm::TLM_UPDATED && 105613513Sgabeblack@google.com phase == tlm::END_RESP))) { 105713513Sgabeblack@google.com m_response_in_progress = true; 105813513Sgabeblack@google.com } 105913513Sgabeblack@google.com 106013513Sgabeblack@google.com // Suspend until next transaction. 106113513Sgabeblack@google.com h->m_suspend = true; 106213513Sgabeblack@google.com sc_core::wait(); 106313513Sgabeblack@google.com } 106413513Sgabeblack@google.com } 106513513Sgabeblack@google.com 106613513Sgabeblack@google.com void 106713513Sgabeblack@google.com b2nb_thread() 106813513Sgabeblack@google.com { 106913513Sgabeblack@google.com while (true) { 107013513Sgabeblack@google.com transaction_type *trans; 107113513Sgabeblack@google.com while ((trans = m_peq.get_next_transaction()) != 0) { 107213513Sgabeblack@google.com sc_assert(m_mod); 107313513Sgabeblack@google.com sc_assert(m_nb_transport_ptr); 107413513Sgabeblack@google.com phase_type phase = tlm::BEGIN_REQ; 107513513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 107613513Sgabeblack@google.com 107713513Sgabeblack@google.com switch ((m_mod->*m_nb_transport_ptr)( 107813513Sgabeblack@google.com m_nb_transport_user_id, *trans, phase, t)) { 107913513Sgabeblack@google.com case tlm::TLM_COMPLETED: 108013513Sgabeblack@google.com { 108113513Sgabeblack@google.com // Notify transaction is finished. 108213513Sgabeblack@google.com typename std::map<transaction_type *, 108313513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 108413513Sgabeblack@google.com m_owner->m_pending_trans.find(trans); 108513513Sgabeblack@google.com sc_assert(it != m_owner->m_pending_trans.end()); 108613513Sgabeblack@google.com it->second->notify(t); 108713513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 108813513Sgabeblack@google.com break; 108913513Sgabeblack@google.com } 109013513Sgabeblack@google.com 109113513Sgabeblack@google.com case tlm::TLM_ACCEPTED: 109213513Sgabeblack@google.com case tlm::TLM_UPDATED: 109313513Sgabeblack@google.com switch (phase) { 109413513Sgabeblack@google.com case tlm::BEGIN_REQ: 109513513Sgabeblack@google.com m_owner->m_current_transaction = trans; 109613513Sgabeblack@google.com sc_core::wait(m_owner->m_end_request); 109713513Sgabeblack@google.com m_owner->m_current_transaction = 0; 109813513Sgabeblack@google.com break; 109913513Sgabeblack@google.com 110013513Sgabeblack@google.com case tlm::END_REQ: 110113513Sgabeblack@google.com sc_core::wait(t); 110213513Sgabeblack@google.com break; 110313513Sgabeblack@google.com 110413513Sgabeblack@google.com case tlm::BEGIN_RESP: 110513513Sgabeblack@google.com { 110613513Sgabeblack@google.com phase = tlm::END_RESP; 110713513Sgabeblack@google.com // This line is a bug fix added in TLM-2.0.2. 110813513Sgabeblack@google.com sc_core::wait(t); 110913513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 111013513Sgabeblack@google.com (m_mod->*m_nb_transport_ptr)( 111113513Sgabeblack@google.com m_nb_transport_user_id, 111213513Sgabeblack@google.com *trans, phase, t); 111313513Sgabeblack@google.com 111413513Sgabeblack@google.com // Notify transaction is finished. 111513513Sgabeblack@google.com typename std::map<transaction_type *, 111613513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 111713513Sgabeblack@google.com m_owner->m_pending_trans.find( 111813513Sgabeblack@google.com trans); 111913513Sgabeblack@google.com sc_assert(it != 112013513Sgabeblack@google.com m_owner->m_pending_trans.end()); 112113513Sgabeblack@google.com it->second->notify(t); 112213513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 112313513Sgabeblack@google.com break; 112413513Sgabeblack@google.com } 112513513Sgabeblack@google.com 112613513Sgabeblack@google.com default: 112713513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 112813513Sgabeblack@google.com }; 112913513Sgabeblack@google.com break; 113013513Sgabeblack@google.com 113113513Sgabeblack@google.com default: 113213513Sgabeblack@google.com m_owner->display_error("invalid sync value received"); 113313513Sgabeblack@google.com } 113413513Sgabeblack@google.com } 113513513Sgabeblack@google.com sc_core::wait(); 113613513Sgabeblack@google.com } 113713513Sgabeblack@google.com } 113813513Sgabeblack@google.com 113913513Sgabeblack@google.com void 114013513Sgabeblack@google.com free(tlm::tlm_generic_payload *trans) 114113513Sgabeblack@google.com { 114213513Sgabeblack@google.com mm_end_event_ext *ext = 114313513Sgabeblack@google.com trans->template get_extension<mm_end_event_ext>(); 114413513Sgabeblack@google.com sc_assert(ext); 114513513Sgabeblack@google.com // Notify event first before freeing extensions (reset). 114613513Sgabeblack@google.com ext->done.notify(); 114713513Sgabeblack@google.com trans->reset(); 114813513Sgabeblack@google.com } 114913513Sgabeblack@google.com 115013513Sgabeblack@google.com private: 115113513Sgabeblack@google.com struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 115213513Sgabeblack@google.com { 115313513Sgabeblack@google.com tlm::tlm_extension_base *clone() const { return NULL; } 115413513Sgabeblack@google.com void free() {} 115513513Sgabeblack@google.com void copy_from(tlm::tlm_extension_base const &) {} 115613513Sgabeblack@google.com sc_core::sc_event done; 115713513Sgabeblack@google.com }; 115813513Sgabeblack@google.com 115913513Sgabeblack@google.com private: 116013513Sgabeblack@google.com simple_target_socket_tagged_b *m_owner; 116113513Sgabeblack@google.com MODULE *m_mod; 116213513Sgabeblack@google.com NBTransportPtr m_nb_transport_ptr; 116313513Sgabeblack@google.com BTransportPtr m_b_transport_ptr; 116413513Sgabeblack@google.com TransportDbgPtr m_transport_dbg_ptr; 116513513Sgabeblack@google.com GetDirectMemPtr m_get_direct_mem_ptr; 116613513Sgabeblack@google.com int m_nb_transport_user_id; 116713513Sgabeblack@google.com int m_b_transport_user_id; 116813513Sgabeblack@google.com int m_transport_dbg_user_id; 116913513Sgabeblack@google.com int m_get_dmi_user_id; 117013513Sgabeblack@google.com peq_with_get<transaction_type> m_peq; 117113513Sgabeblack@google.com bool m_response_in_progress; 117213513Sgabeblack@google.com sc_core::sc_event m_end_response; 117313511Sgabeblack@google.com }; 117413511Sgabeblack@google.com 117513511Sgabeblack@google.com private: 117613513Sgabeblack@google.com const sc_core::sc_object *get_socket() const { return this; } 117713511Sgabeblack@google.com 117813513Sgabeblack@google.com private: 117913513Sgabeblack@google.com fw_process m_fw_process; 118013513Sgabeblack@google.com bw_process m_bw_process; 118113513Sgabeblack@google.com std::map<transaction_type *, sc_core::sc_event *> m_pending_trans; 118213513Sgabeblack@google.com sc_core::sc_event m_end_request; 118313513Sgabeblack@google.com transaction_type* m_current_transaction; 118413511Sgabeblack@google.com}; 118513511Sgabeblack@google.com 118613513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 118713513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 118813513Sgabeblack@google.comclass simple_target_socket_tagged : 118913513Sgabeblack@google.com public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES> 119013511Sgabeblack@google.com{ 119113513Sgabeblack@google.com typedef simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES> socket_b; 119213513Sgabeblack@google.com public: 119313513Sgabeblack@google.com simple_target_socket_tagged() : socket_b() {} 119413513Sgabeblack@google.com explicit simple_target_socket_tagged(const char *name) : socket_b(name) {} 119513511Sgabeblack@google.com}; 119613511Sgabeblack@google.com 119713513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 119813513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 119913513Sgabeblack@google.comclass simple_target_socket_tagged_optional : 120013513Sgabeblack@google.com public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES, 120113513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> 120213511Sgabeblack@google.com{ 120313513Sgabeblack@google.com typedef simple_target_socket_tagged_b< 120413513Sgabeblack@google.com MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 120513511Sgabeblack@google.com public: 120613513Sgabeblack@google.com simple_target_socket_tagged_optional() : socket_b() {} 120713513Sgabeblack@google.com explicit simple_target_socket_tagged_optional(const char *name) : 120813513Sgabeblack@google.com socket_b(name) 120913511Sgabeblack@google.com {} 121013511Sgabeblack@google.com}; 121113511Sgabeblack@google.com 121213511Sgabeblack@google.com} // namespace tlm_utils 121313513Sgabeblack@google.com 121413513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__ */ 1215