simple_target_socket.h revision 13586
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" 2613586Sgabeblack@google.com#include "../tlm_core/2/generic_payload/gp.hh" 2713586Sgabeblack@google.com#include "../tlm_core/2/interfaces/fw_bw_ifs.hh" 2813586Sgabeblack@google.com#include "../tlm_core/2/sockets/target_socket.hh" 2913586Sgabeblack@google.com#include "../utils/sc_report_handler.hh" 3013586Sgabeblack@google.com#include "convenience_socket_bases.h" 3113586Sgabeblack@google.com#include "peq_with_get.h" 3213511Sgabeblack@google.com 3313513Sgabeblack@google.comnamespace tlm_utils 3413513Sgabeblack@google.com{ 3513511Sgabeblack@google.com 3613513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 3713513Sgabeblack@google.com sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 3813513Sgabeblack@google.comclass simple_target_socket_b : 3913513Sgabeblack@google.com public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>, 4013513Sgabeblack@google.com protected simple_socket_base 4113511Sgabeblack@google.com{ 4213513Sgabeblack@google.com friend class fw_process; 4313513Sgabeblack@google.com friend class bw_process; 4413513Sgabeblack@google.com public: 4513513Sgabeblack@google.com typedef typename TYPES::tlm_payload_type transaction_type; 4613513Sgabeblack@google.com typedef typename TYPES::tlm_phase_type phase_type; 4713513Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 4813513Sgabeblack@google.com typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 4913513Sgabeblack@google.com typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 5013513Sgabeblack@google.com typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type; 5113511Sgabeblack@google.com 5213511Sgabeblack@google.com public: 5313513Sgabeblack@google.com static const char * 5413513Sgabeblack@google.com default_name() 5513511Sgabeblack@google.com { 5613513Sgabeblack@google.com return sc_core::sc_gen_unique_name("simple_target_socket"); 5713511Sgabeblack@google.com } 5813511Sgabeblack@google.com 5913513Sgabeblack@google.com explicit simple_target_socket_b(const char *n=default_name()) : 6013513Sgabeblack@google.com base_type(n), m_fw_process(this), m_bw_process(this) 6113511Sgabeblack@google.com { 6213513Sgabeblack@google.com bind(m_fw_process); 6313511Sgabeblack@google.com } 6413511Sgabeblack@google.com 6513513Sgabeblack@google.com using base_type::bind; 6613513Sgabeblack@google.com 6713513Sgabeblack@google.com // bw transport must come through us. 6813513Sgabeblack@google.com tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; } 6913513Sgabeblack@google.com 7013513Sgabeblack@google.com // REGISTER_XXX 7113513Sgabeblack@google.com void 7213513Sgabeblack@google.com register_nb_transport_fw(MODULE *mod, 7313513Sgabeblack@google.com sync_enum_type (MODULE::*cb)( 7413513Sgabeblack@google.com transaction_type &, phase_type &, sc_core::sc_time &)) 7513511Sgabeblack@google.com { 7613513Sgabeblack@google.com elaboration_check("register_nb_transport_fw"); 7713513Sgabeblack@google.com m_fw_process.set_nb_transport_ptr(mod, cb); 7813513Sgabeblack@google.com } 7913513Sgabeblack@google.com 8013513Sgabeblack@google.com void 8113513Sgabeblack@google.com register_b_transport(MODULE *mod, 8213513Sgabeblack@google.com void (MODULE::*cb)(transaction_type &, sc_core::sc_time &)) 8313513Sgabeblack@google.com { 8413513Sgabeblack@google.com elaboration_check("register_b_transport"); 8513513Sgabeblack@google.com m_fw_process.set_b_transport_ptr(mod, cb); 8613513Sgabeblack@google.com } 8713513Sgabeblack@google.com 8813513Sgabeblack@google.com void 8913513Sgabeblack@google.com register_transport_dbg(MODULE *mod, 9013513Sgabeblack@google.com unsigned int (MODULE::*cb)(transaction_type &)) 9113513Sgabeblack@google.com { 9213513Sgabeblack@google.com elaboration_check("register_transport_dbg"); 9313513Sgabeblack@google.com m_fw_process.set_transport_dbg_ptr(mod, cb); 9413513Sgabeblack@google.com } 9513513Sgabeblack@google.com 9613513Sgabeblack@google.com void 9713513Sgabeblack@google.com register_get_direct_mem_ptr(MODULE *mod, 9813513Sgabeblack@google.com bool (MODULE::*cb)(transaction_type &, tlm::tlm_dmi &)) 9913513Sgabeblack@google.com { 10013513Sgabeblack@google.com elaboration_check("register_get_direct_mem_ptr"); 10113513Sgabeblack@google.com m_fw_process.set_get_direct_mem_ptr(mod, cb); 10213513Sgabeblack@google.com } 10313513Sgabeblack@google.com 10413513Sgabeblack@google.com protected: 10513513Sgabeblack@google.com void 10613513Sgabeblack@google.com start_of_simulation() 10713513Sgabeblack@google.com { 10813513Sgabeblack@google.com base_type::start_of_simulation(); 10913513Sgabeblack@google.com m_fw_process.start_of_simulation(); 11013511Sgabeblack@google.com } 11113511Sgabeblack@google.com 11213511Sgabeblack@google.com private: 11313513Sgabeblack@google.com // Make call on bw path. 11413513Sgabeblack@google.com sync_enum_type 11513513Sgabeblack@google.com bw_nb_transport(transaction_type &trans, phase_type &phase, 11613513Sgabeblack@google.com sc_core::sc_time &t) 11713511Sgabeblack@google.com { 11813513Sgabeblack@google.com return base_type::operator -> ()->nb_transport_bw(trans, phase, t); 11913511Sgabeblack@google.com } 12013511Sgabeblack@google.com 12113513Sgabeblack@google.com void 12213513Sgabeblack@google.com bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 12313511Sgabeblack@google.com { 12413513Sgabeblack@google.com base_type::operator -> ()->invalidate_direct_mem_ptr(s, e); 12513511Sgabeblack@google.com } 12613511Sgabeblack@google.com 12713513Sgabeblack@google.com // Helper class to handle bw path calls Needed to detect transaction end 12813513Sgabeblack@google.com // when called from b_transport. 12913513Sgabeblack@google.com class bw_process : public tlm::tlm_bw_transport_if<TYPES> 13013511Sgabeblack@google.com { 13113513Sgabeblack@google.com public: 13213513Sgabeblack@google.com bw_process(simple_target_socket_b *p_own) : m_owner(p_own) {} 13313513Sgabeblack@google.com 13413513Sgabeblack@google.com sync_enum_type 13513513Sgabeblack@google.com nb_transport_bw(transaction_type &trans, phase_type &phase, 13613513Sgabeblack@google.com sc_core::sc_time &t) 13713513Sgabeblack@google.com { 13813513Sgabeblack@google.com typename std::map<transaction_type *, 13913513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 14013513Sgabeblack@google.com m_owner->m_pending_trans.find(&trans); 14113513Sgabeblack@google.com 14213513Sgabeblack@google.com if (it == m_owner->m_pending_trans.end()) { 14313513Sgabeblack@google.com // Not a blocking call, forward. 14413513Sgabeblack@google.com return m_owner->bw_nb_transport(trans, phase, t); 14513513Sgabeblack@google.com 14613513Sgabeblack@google.com } 14713513Sgabeblack@google.com 14813513Sgabeblack@google.com if (phase == tlm::END_REQ) { 14913513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15013513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 15113513Sgabeblack@google.com } 15213513Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 15313513Sgabeblack@google.com if (m_owner->m_current_transaction == &trans) { 15413513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15513513Sgabeblack@google.com } 15613513Sgabeblack@google.com it->second->notify(t); 15713513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 15813513Sgabeblack@google.com return tlm::TLM_COMPLETED; 15913513Sgabeblack@google.com } 16013513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 16113513Sgabeblack@google.com return tlm::TLM_COMPLETED; 16213513Sgabeblack@google.com } 16313513Sgabeblack@google.com 16413513Sgabeblack@google.com void 16513513Sgabeblack@google.com invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 16613513Sgabeblack@google.com { 16713513Sgabeblack@google.com return m_owner->bw_invalidate_direct_mem_ptr(s, e); 16813513Sgabeblack@google.com } 16913513Sgabeblack@google.com 17013513Sgabeblack@google.com private: 17113513Sgabeblack@google.com simple_target_socket_b *m_owner; 17213513Sgabeblack@google.com }; 17313513Sgabeblack@google.com 17413513Sgabeblack@google.com class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 17513513Sgabeblack@google.com public tlm::tlm_mm_interface 17613513Sgabeblack@google.com { 17713513Sgabeblack@google.com public: 17813513Sgabeblack@google.com typedef sync_enum_type (MODULE::*NBTransportPtr)( 17913513Sgabeblack@google.com transaction_type &, phase_type &, sc_core::sc_time &); 18013513Sgabeblack@google.com typedef void (MODULE::*BTransportPtr)( 18113513Sgabeblack@google.com transaction_type &, sc_core::sc_time &); 18213513Sgabeblack@google.com typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type &); 18313513Sgabeblack@google.com typedef bool (MODULE::*GetDirectMemPtr)( 18413513Sgabeblack@google.com transaction_type &, tlm::tlm_dmi &); 18513513Sgabeblack@google.com 18613513Sgabeblack@google.com fw_process(simple_target_socket_b *p_own) : 18713513Sgabeblack@google.com m_owner(p_own), m_mod(0), m_nb_transport_ptr(0), 18813513Sgabeblack@google.com m_b_transport_ptr(0), m_transport_dbg_ptr(0), 18913513Sgabeblack@google.com m_get_direct_mem_ptr(0), 19013513Sgabeblack@google.com m_peq(sc_core::sc_gen_unique_name("m_peq")), 19113513Sgabeblack@google.com m_response_in_progress(false) 19213513Sgabeblack@google.com {} 19313513Sgabeblack@google.com 19413513Sgabeblack@google.com void 19513513Sgabeblack@google.com start_of_simulation() 19613513Sgabeblack@google.com { 19713513Sgabeblack@google.com // Only spawn b2nb_thread, if needed. 19813513Sgabeblack@google.com if (!m_b_transport_ptr && m_nb_transport_ptr) { 19913513Sgabeblack@google.com sc_core::sc_spawn_options opts; 20013513Sgabeblack@google.com opts.set_sensitivity(&m_peq.get_event()); 20113513Sgabeblack@google.com opts.dont_initialize(); 20213513Sgabeblack@google.com sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 20313513Sgabeblack@google.com sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 20413513Sgabeblack@google.com } 20513513Sgabeblack@google.com } 20613513Sgabeblack@google.com 20713513Sgabeblack@google.com void 20813513Sgabeblack@google.com set_nb_transport_ptr(MODULE *mod, NBTransportPtr p) 20913513Sgabeblack@google.com { 21013513Sgabeblack@google.com if (m_nb_transport_ptr) { 21113513Sgabeblack@google.com m_owner->display_warning( 21213513Sgabeblack@google.com "non-blocking callback already registered"); 21313513Sgabeblack@google.com return; 21413513Sgabeblack@google.com } 21513513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 21613513Sgabeblack@google.com m_mod = mod; 21713513Sgabeblack@google.com m_nb_transport_ptr = p; 21813513Sgabeblack@google.com } 21913513Sgabeblack@google.com 22013513Sgabeblack@google.com void 22113513Sgabeblack@google.com set_b_transport_ptr(MODULE *mod, BTransportPtr p) 22213513Sgabeblack@google.com { 22313513Sgabeblack@google.com if (m_b_transport_ptr) { 22413513Sgabeblack@google.com m_owner->display_warning( 22513513Sgabeblack@google.com "blocking callback already registered"); 22613513Sgabeblack@google.com return; 22713513Sgabeblack@google.com } 22813513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 22913513Sgabeblack@google.com m_mod = mod; 23013513Sgabeblack@google.com m_b_transport_ptr = p; 23113513Sgabeblack@google.com } 23213513Sgabeblack@google.com 23313513Sgabeblack@google.com void 23413513Sgabeblack@google.com set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p) 23513513Sgabeblack@google.com { 23613513Sgabeblack@google.com if (m_transport_dbg_ptr) { 23713513Sgabeblack@google.com m_owner->display_warning("debug callback already registered"); 23813513Sgabeblack@google.com return; 23913513Sgabeblack@google.com } 24013513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 24113513Sgabeblack@google.com m_mod = mod; 24213513Sgabeblack@google.com m_transport_dbg_ptr = p; 24313513Sgabeblack@google.com } 24413513Sgabeblack@google.com 24513513Sgabeblack@google.com void 24613513Sgabeblack@google.com set_get_direct_mem_ptr(MODULE *mod, GetDirectMemPtr p) 24713513Sgabeblack@google.com { 24813513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 24913513Sgabeblack@google.com m_owner->display_warning( 25013513Sgabeblack@google.com "get DMI pointer callback already registered"); 25113513Sgabeblack@google.com return; 25213513Sgabeblack@google.com } 25313513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 25413513Sgabeblack@google.com m_mod = mod; 25513513Sgabeblack@google.com m_get_direct_mem_ptr = p; 25613513Sgabeblack@google.com } 25713513Sgabeblack@google.com 25813513Sgabeblack@google.com // Interface implementation. 25913513Sgabeblack@google.com sync_enum_type 26013513Sgabeblack@google.com nb_transport_fw(transaction_type &trans, phase_type &phase, 26113513Sgabeblack@google.com sc_core::sc_time & t) 26213513Sgabeblack@google.com { 26313513Sgabeblack@google.com if (m_nb_transport_ptr) { 26413513Sgabeblack@google.com // Forward call. 26513513Sgabeblack@google.com sc_assert(m_mod); 26613513Sgabeblack@google.com return (m_mod->*m_nb_transport_ptr)(trans, phase, t); 26713513Sgabeblack@google.com } 26813513Sgabeblack@google.com 26913513Sgabeblack@google.com // nb->b conversion 27013513Sgabeblack@google.com if (m_b_transport_ptr) { 27113513Sgabeblack@google.com if (phase == tlm::BEGIN_REQ) { 27213513Sgabeblack@google.com // Prepare thread to do blocking call. 27313513Sgabeblack@google.com process_handle_class *ph = 27413513Sgabeblack@google.com m_process_handle.get_handle(&trans); 27513513Sgabeblack@google.com 27613513Sgabeblack@google.com if (!ph) { // Create new dynamic process. 27713513Sgabeblack@google.com ph = new process_handle_class(&trans); 27813513Sgabeblack@google.com m_process_handle.put_handle(ph); 27913513Sgabeblack@google.com 28013513Sgabeblack@google.com sc_core::sc_spawn_options opts; 28113513Sgabeblack@google.com opts.dont_initialize(); 28213513Sgabeblack@google.com opts.set_sensitivity(&ph->m_e); 28313513Sgabeblack@google.com 28413513Sgabeblack@google.com sc_core::sc_spawn( 28513513Sgabeblack@google.com sc_bind(&fw_process::nb2b_thread, this, ph), 28613513Sgabeblack@google.com sc_core::sc_gen_unique_name("nb2b_thread"), 28713513Sgabeblack@google.com &opts); 28813513Sgabeblack@google.com } 28913513Sgabeblack@google.com 29013513Sgabeblack@google.com ph->m_e.notify(t); 29113513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 29213513Sgabeblack@google.com } 29313513Sgabeblack@google.com if (phase == tlm::END_RESP) { 29413513Sgabeblack@google.com m_response_in_progress = false; 29513513Sgabeblack@google.com m_end_response.notify(t); 29613513Sgabeblack@google.com return tlm::TLM_COMPLETED; 29713513Sgabeblack@google.com } 29813513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 29913513Sgabeblack@google.com return tlm::TLM_COMPLETED; 30013513Sgabeblack@google.com } 30113513Sgabeblack@google.com m_owner->display_error( 30213513Sgabeblack@google.com "no non-blocking transport callback registered"); 30313513Sgabeblack@google.com return tlm::TLM_COMPLETED; 30413513Sgabeblack@google.com } 30513513Sgabeblack@google.com 30613513Sgabeblack@google.com void 30713513Sgabeblack@google.com b_transport(transaction_type &trans, sc_core::sc_time &t) 30813513Sgabeblack@google.com { 30913513Sgabeblack@google.com if (m_b_transport_ptr) { 31013513Sgabeblack@google.com // Forward call. 31113513Sgabeblack@google.com sc_assert(m_mod); 31213513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(trans, t); 31313513Sgabeblack@google.com return; 31413513Sgabeblack@google.com } 31513513Sgabeblack@google.com 31613513Sgabeblack@google.com // b->nb conversion 31713513Sgabeblack@google.com if (m_nb_transport_ptr) { 31813513Sgabeblack@google.com m_peq.notify(trans, t); 31913513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 32013513Sgabeblack@google.com 32113513Sgabeblack@google.com mm_end_event_ext mm_ext; 32213513Sgabeblack@google.com const bool mm_added = !trans.has_mm(); 32313513Sgabeblack@google.com 32413513Sgabeblack@google.com if (mm_added) { 32513513Sgabeblack@google.com trans.set_mm(this); 32613513Sgabeblack@google.com trans.set_auto_extension(&mm_ext); 32713513Sgabeblack@google.com trans.acquire(); 32813513Sgabeblack@google.com } 32913513Sgabeblack@google.com 33013513Sgabeblack@google.com // Wait until transaction is finished. 33113513Sgabeblack@google.com sc_core::sc_event end_event; 33213513Sgabeblack@google.com m_owner->m_pending_trans[&trans] = &end_event; 33313513Sgabeblack@google.com sc_core::wait(end_event); 33413513Sgabeblack@google.com 33513513Sgabeblack@google.com if (mm_added) { 33613513Sgabeblack@google.com // Release will not delete the transaction, it will 33713513Sgabeblack@google.com // notify mm_ext.done. 33813513Sgabeblack@google.com trans.release(); 33913513Sgabeblack@google.com if (trans.get_ref_count()) { 34013513Sgabeblack@google.com sc_core::wait(mm_ext.done); 34113513Sgabeblack@google.com } 34213513Sgabeblack@google.com trans.set_mm(0); 34313513Sgabeblack@google.com } 34413513Sgabeblack@google.com return; 34513513Sgabeblack@google.com } 34613513Sgabeblack@google.com 34713513Sgabeblack@google.com // Should not be reached. 34813513Sgabeblack@google.com m_owner->display_error( 34913513Sgabeblack@google.com "no blocking transport callback registered"); 35013513Sgabeblack@google.com } 35113513Sgabeblack@google.com 35213513Sgabeblack@google.com unsigned int 35313513Sgabeblack@google.com transport_dbg(transaction_type &trans) 35413513Sgabeblack@google.com { 35513513Sgabeblack@google.com if (m_transport_dbg_ptr) { 35613513Sgabeblack@google.com // Forward call. 35713513Sgabeblack@google.com sc_assert(m_mod); 35813513Sgabeblack@google.com return (m_mod->*m_transport_dbg_ptr)(trans); 35913513Sgabeblack@google.com } 36013513Sgabeblack@google.com // No debug support. 36113513Sgabeblack@google.com return 0; 36213513Sgabeblack@google.com } 36313513Sgabeblack@google.com 36413513Sgabeblack@google.com bool 36513513Sgabeblack@google.com get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data) 36613513Sgabeblack@google.com { 36713513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 36813513Sgabeblack@google.com // Forward call. 36913513Sgabeblack@google.com sc_assert(m_mod); 37013513Sgabeblack@google.com return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data); 37113513Sgabeblack@google.com } 37213513Sgabeblack@google.com // No DMI support. 37313513Sgabeblack@google.com dmi_data.allow_read_write(); 37413513Sgabeblack@google.com dmi_data.set_start_address(0x0); 37513513Sgabeblack@google.com dmi_data.set_end_address((sc_dt::uint64)-1); 37613513Sgabeblack@google.com return false; 37713513Sgabeblack@google.com } 37813513Sgabeblack@google.com 37913513Sgabeblack@google.com private: 38013513Sgabeblack@google.com 38113513Sgabeblack@google.com // Dynamic process handler for nb2b conversion. 38213513Sgabeblack@google.com 38313513Sgabeblack@google.com class process_handle_class 38413513Sgabeblack@google.com { 38513513Sgabeblack@google.com public: 38613513Sgabeblack@google.com explicit process_handle_class(transaction_type *trans) : 38713513Sgabeblack@google.com m_trans(trans), m_suspend(false) 38813513Sgabeblack@google.com {} 38913513Sgabeblack@google.com 39013513Sgabeblack@google.com transaction_type *m_trans; 39113513Sgabeblack@google.com sc_core::sc_event m_e; 39213513Sgabeblack@google.com bool m_suspend; 39313513Sgabeblack@google.com }; 39413513Sgabeblack@google.com 39513513Sgabeblack@google.com class process_handle_list 39613513Sgabeblack@google.com { 39713513Sgabeblack@google.com public: 39813513Sgabeblack@google.com process_handle_list() {} 39913513Sgabeblack@google.com 40013513Sgabeblack@google.com ~process_handle_list() 40113513Sgabeblack@google.com { 40213513Sgabeblack@google.com for (typename std::vector< 40313513Sgabeblack@google.com process_handle_class *>::iterator it = v.begin(), 40413513Sgabeblack@google.com end = v.end(); it != end; ++it) { 40513513Sgabeblack@google.com delete *it; 40613513Sgabeblack@google.com } 40713513Sgabeblack@google.com } 40813513Sgabeblack@google.com 40913513Sgabeblack@google.com process_handle_class * 41013513Sgabeblack@google.com get_handle(transaction_type *trans) 41113513Sgabeblack@google.com { 41213513Sgabeblack@google.com typename std::vector<process_handle_class *>::iterator it; 41313513Sgabeblack@google.com 41413513Sgabeblack@google.com for (it = v.begin(); it != v.end(); it++) { 41513513Sgabeblack@google.com if ((*it)->m_suspend) { 41613513Sgabeblack@google.com // Found suspended dynamic process, re-use it. 41713513Sgabeblack@google.com (*it)->m_trans = trans; // Replace to new one. 41813513Sgabeblack@google.com (*it)->m_suspend = false; 41913513Sgabeblack@google.com return *it; 42013513Sgabeblack@google.com } 42113513Sgabeblack@google.com } 42213513Sgabeblack@google.com return NULL; // No suspended process. 42313513Sgabeblack@google.com } 42413513Sgabeblack@google.com 42513513Sgabeblack@google.com void 42613513Sgabeblack@google.com put_handle(process_handle_class *ph) 42713513Sgabeblack@google.com { 42813513Sgabeblack@google.com v.push_back(ph); 42913513Sgabeblack@google.com } 43013513Sgabeblack@google.com 43113513Sgabeblack@google.com private: 43213513Sgabeblack@google.com std::vector<process_handle_class*> v; 43313513Sgabeblack@google.com }; 43413513Sgabeblack@google.com 43513513Sgabeblack@google.com process_handle_list m_process_handle; 43613513Sgabeblack@google.com 43713513Sgabeblack@google.com void 43813513Sgabeblack@google.com nb2b_thread(process_handle_class *h) 43913513Sgabeblack@google.com { 44013513Sgabeblack@google.com while (1) { 44113513Sgabeblack@google.com transaction_type *trans = h->m_trans; 44213513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 44313513Sgabeblack@google.com 44413513Sgabeblack@google.com // Forward call. 44513513Sgabeblack@google.com sc_assert(m_mod); 44613513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(*trans, t); 44713513Sgabeblack@google.com 44813513Sgabeblack@google.com sc_core::wait(t); 44913513Sgabeblack@google.com 45013513Sgabeblack@google.com // Return path. 45113513Sgabeblack@google.com while (m_response_in_progress) { 45213513Sgabeblack@google.com sc_core::wait(m_end_response); 45313513Sgabeblack@google.com } 45413513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 45513513Sgabeblack@google.com phase_type phase = tlm::BEGIN_RESP; 45613513Sgabeblack@google.com sync_enum_type sync = 45713513Sgabeblack@google.com m_owner->bw_nb_transport(*trans, phase, t); 45813513Sgabeblack@google.com if (!(sync == tlm::TLM_COMPLETED || 45913513Sgabeblack@google.com (sync == tlm::TLM_UPDATED && 46013513Sgabeblack@google.com phase == tlm::END_RESP))) { 46113513Sgabeblack@google.com m_response_in_progress = true; 46213513Sgabeblack@google.com } 46313513Sgabeblack@google.com 46413513Sgabeblack@google.com // Suspend until next transaction. 46513513Sgabeblack@google.com h->m_suspend = true; 46613513Sgabeblack@google.com sc_core::wait(); 46713513Sgabeblack@google.com } 46813513Sgabeblack@google.com } 46913513Sgabeblack@google.com 47013513Sgabeblack@google.com void 47113513Sgabeblack@google.com b2nb_thread() 47213513Sgabeblack@google.com { 47313513Sgabeblack@google.com while (true) { 47413513Sgabeblack@google.com transaction_type *trans; 47513513Sgabeblack@google.com while ((trans = m_peq.get_next_transaction()) != 0) { 47613513Sgabeblack@google.com sc_assert(m_mod); 47713513Sgabeblack@google.com sc_assert(m_nb_transport_ptr); 47813513Sgabeblack@google.com phase_type phase = tlm::BEGIN_REQ; 47913513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 48013513Sgabeblack@google.com 48113513Sgabeblack@google.com switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) { 48213513Sgabeblack@google.com case tlm::TLM_COMPLETED: 48313513Sgabeblack@google.com { 48413513Sgabeblack@google.com // Notify transaction is finished. 48513513Sgabeblack@google.com typename std::map<transaction_type *, 48613513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 48713513Sgabeblack@google.com m_owner->m_pending_trans.find(trans); 48813513Sgabeblack@google.com sc_assert(it != m_owner->m_pending_trans.end()); 48913513Sgabeblack@google.com it->second->notify(t); 49013513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 49113513Sgabeblack@google.com break; 49213513Sgabeblack@google.com } 49313513Sgabeblack@google.com 49413513Sgabeblack@google.com case tlm::TLM_ACCEPTED: 49513513Sgabeblack@google.com case tlm::TLM_UPDATED: 49613513Sgabeblack@google.com switch (phase) { 49713513Sgabeblack@google.com case tlm::BEGIN_REQ: 49813513Sgabeblack@google.com m_owner->m_current_transaction = trans; 49913513Sgabeblack@google.com sc_core::wait(m_owner->m_end_request); 50013513Sgabeblack@google.com m_owner->m_current_transaction = 0; 50113513Sgabeblack@google.com break; 50213513Sgabeblack@google.com 50313513Sgabeblack@google.com case tlm::END_REQ: 50413513Sgabeblack@google.com sc_core::wait(t); 50513513Sgabeblack@google.com break; 50613513Sgabeblack@google.com 50713513Sgabeblack@google.com case tlm::BEGIN_RESP: 50813513Sgabeblack@google.com { 50913513Sgabeblack@google.com phase = tlm::END_RESP; 51013513Sgabeblack@google.com // This line is a bug fix added in TLM-2.0.2 51113513Sgabeblack@google.com sc_core::wait(t); 51213513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 51313513Sgabeblack@google.com (m_mod->*m_nb_transport_ptr)( 51413513Sgabeblack@google.com *trans, phase, t); 51513513Sgabeblack@google.com 51613513Sgabeblack@google.com // Notify transaction is finished. 51713513Sgabeblack@google.com typename std::map<transaction_type *, 51813513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 51913513Sgabeblack@google.com m_owner->m_pending_trans.find( 52013513Sgabeblack@google.com trans); 52113513Sgabeblack@google.com sc_assert(it != 52213513Sgabeblack@google.com m_owner->m_pending_trans.end()); 52313513Sgabeblack@google.com it->second->notify(t); 52413513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 52513513Sgabeblack@google.com break; 52613513Sgabeblack@google.com } 52713513Sgabeblack@google.com 52813513Sgabeblack@google.com default: 52913513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 53013513Sgabeblack@google.com } 53113513Sgabeblack@google.com break; 53213513Sgabeblack@google.com 53313513Sgabeblack@google.com default: 53413513Sgabeblack@google.com m_owner->display_error("invalid sync value received"); 53513513Sgabeblack@google.com } 53613513Sgabeblack@google.com } 53713513Sgabeblack@google.com sc_core::wait(); 53813513Sgabeblack@google.com } 53913513Sgabeblack@google.com } 54013513Sgabeblack@google.com 54113513Sgabeblack@google.com void 54213513Sgabeblack@google.com free(tlm::tlm_generic_payload *trans) 54313513Sgabeblack@google.com { 54413513Sgabeblack@google.com mm_end_event_ext *ext = 54513513Sgabeblack@google.com trans->template get_extension<mm_end_event_ext>(); 54613513Sgabeblack@google.com sc_assert(ext); 54713513Sgabeblack@google.com // Notify event first before freeing extensions (reset). 54813513Sgabeblack@google.com ext->done.notify(); 54913513Sgabeblack@google.com trans->reset(); 55013513Sgabeblack@google.com } 55113513Sgabeblack@google.com 55213513Sgabeblack@google.com private: 55313513Sgabeblack@google.com struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 55413513Sgabeblack@google.com { 55513513Sgabeblack@google.com tlm::tlm_extension_base *clone() const { return NULL; } 55613513Sgabeblack@google.com void free() {} 55713513Sgabeblack@google.com void copy_from(tlm::tlm_extension_base const &) {} 55813513Sgabeblack@google.com sc_core::sc_event done; 55913513Sgabeblack@google.com }; 56013513Sgabeblack@google.com 56113513Sgabeblack@google.com private: 56213513Sgabeblack@google.com simple_target_socket_b *m_owner; 56313513Sgabeblack@google.com MODULE *m_mod; 56413513Sgabeblack@google.com NBTransportPtr m_nb_transport_ptr; 56513513Sgabeblack@google.com BTransportPtr m_b_transport_ptr; 56613513Sgabeblack@google.com TransportDbgPtr m_transport_dbg_ptr; 56713513Sgabeblack@google.com GetDirectMemPtr m_get_direct_mem_ptr; 56813513Sgabeblack@google.com peq_with_get<transaction_type> m_peq; 56913513Sgabeblack@google.com bool m_response_in_progress; 57013513Sgabeblack@google.com sc_core::sc_event m_end_response; 57113513Sgabeblack@google.com }; 57213513Sgabeblack@google.com 57313513Sgabeblack@google.com private: 57413513Sgabeblack@google.com const sc_core::sc_object *get_socket() const { return this; } 57513513Sgabeblack@google.com 57613513Sgabeblack@google.com private: 57713513Sgabeblack@google.com fw_process m_fw_process; 57813513Sgabeblack@google.com bw_process m_bw_process; 57913513Sgabeblack@google.com std::map<transaction_type *, sc_core::sc_event *> m_pending_trans; 58013513Sgabeblack@google.com sc_core::sc_event m_end_request; 58113513Sgabeblack@google.com transaction_type* m_current_transaction; 58213513Sgabeblack@google.com}; 58313513Sgabeblack@google.com 58413513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 58513513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 58613513Sgabeblack@google.comclass simple_target_socket : 58713513Sgabeblack@google.com public simple_target_socket_b<MODULE, BUSWIDTH, TYPES> 58813513Sgabeblack@google.com{ 58913513Sgabeblack@google.com typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES> socket_b; 59013513Sgabeblack@google.com public: 59113513Sgabeblack@google.com simple_target_socket() : socket_b() {} 59213513Sgabeblack@google.com explicit simple_target_socket(const char *name) : socket_b(name) {} 59313513Sgabeblack@google.com}; 59413513Sgabeblack@google.com 59513513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 59613513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 59713513Sgabeblack@google.comclass simple_target_socket_optional : 59813513Sgabeblack@google.com public simple_target_socket_b<MODULE, BUSWIDTH, TYPES, 59913513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> 60013513Sgabeblack@google.com{ 60113513Sgabeblack@google.com typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES, 60213513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 60313513Sgabeblack@google.com public: 60413513Sgabeblack@google.com simple_target_socket_optional() : socket_b() {} 60513513Sgabeblack@google.com explicit simple_target_socket_optional(const char *name) : 60613513Sgabeblack@google.com socket_b(name) 60713513Sgabeblack@google.com {} 60813513Sgabeblack@google.com}; 60913513Sgabeblack@google.com 61013513Sgabeblack@google.com// ID Tagged version. 61113513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 61213513Sgabeblack@google.com sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 61313513Sgabeblack@google.comclass simple_target_socket_tagged_b : 61413513Sgabeblack@google.com public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>, 61513513Sgabeblack@google.com protected simple_socket_base 61613513Sgabeblack@google.com{ 61713513Sgabeblack@google.com friend class fw_process; 61813513Sgabeblack@google.com friend class bw_process; 61913513Sgabeblack@google.com public: 62013513Sgabeblack@google.com typedef typename TYPES::tlm_payload_type transaction_type; 62113513Sgabeblack@google.com typedef typename TYPES::tlm_phase_type phase_type; 62213513Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 62313513Sgabeblack@google.com typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 62413513Sgabeblack@google.com typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 62513513Sgabeblack@google.com typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type; 62613513Sgabeblack@google.com 62713513Sgabeblack@google.com public: 62813513Sgabeblack@google.com static const char * 62913513Sgabeblack@google.com default_name() 63013513Sgabeblack@google.com { 63113513Sgabeblack@google.com return sc_core::sc_gen_unique_name("simple_target_socket_tagged"); 63213511Sgabeblack@google.com } 63313511Sgabeblack@google.com 63413513Sgabeblack@google.com explicit simple_target_socket_tagged_b(const char *n=default_name()) : 63513513Sgabeblack@google.com base_type(n), m_fw_process(this), m_bw_process(this) 63613511Sgabeblack@google.com { 63713513Sgabeblack@google.com bind(m_fw_process); 63813511Sgabeblack@google.com } 63913511Sgabeblack@google.com 64013513Sgabeblack@google.com using base_type::bind; 64113513Sgabeblack@google.com 64213513Sgabeblack@google.com // bw transport must come through us. 64313513Sgabeblack@google.com tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; } 64413513Sgabeblack@google.com 64513513Sgabeblack@google.com // REGISTER_XXX 64613513Sgabeblack@google.com void 64713513Sgabeblack@google.com register_nb_transport_fw(MODULE *mod, 64813513Sgabeblack@google.com sync_enum_type (MODULE::*cb)(int id, transaction_type &, 64913513Sgabeblack@google.com phase_type &, sc_core::sc_time &), 65013513Sgabeblack@google.com int id) 65113511Sgabeblack@google.com { 65213513Sgabeblack@google.com elaboration_check("register_nb_transport_fw"); 65313513Sgabeblack@google.com m_fw_process.set_nb_transport_ptr(mod, cb); 65413513Sgabeblack@google.com m_fw_process.set_nb_transport_user_id(id); 65513511Sgabeblack@google.com } 65613511Sgabeblack@google.com 65713513Sgabeblack@google.com void 65813513Sgabeblack@google.com register_b_transport(MODULE *mod, 65913513Sgabeblack@google.com void (MODULE::*cb)(int id, transaction_type &, 66013513Sgabeblack@google.com sc_core::sc_time &), 66113513Sgabeblack@google.com int id) 66213511Sgabeblack@google.com { 66313513Sgabeblack@google.com elaboration_check("register_b_transport"); 66413513Sgabeblack@google.com m_fw_process.set_b_transport_ptr(mod, cb); 66513513Sgabeblack@google.com m_fw_process.set_b_transport_user_id(id); 66613511Sgabeblack@google.com } 66713511Sgabeblack@google.com 66813513Sgabeblack@google.com void 66913513Sgabeblack@google.com register_transport_dbg(MODULE *mod, 67013513Sgabeblack@google.com unsigned int (MODULE::*cb)(int id, transaction_type &), int id) 67113511Sgabeblack@google.com { 67213513Sgabeblack@google.com elaboration_check("register_transport_dbg"); 67313513Sgabeblack@google.com m_fw_process.set_transport_dbg_ptr(mod, cb); 67413513Sgabeblack@google.com m_fw_process.set_transport_dbg_user_id(id); 67513511Sgabeblack@google.com } 67613511Sgabeblack@google.com 67713513Sgabeblack@google.com void 67813513Sgabeblack@google.com register_get_direct_mem_ptr(MODULE *mod, 67913513Sgabeblack@google.com bool (MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), 68013513Sgabeblack@google.com int id) 68113511Sgabeblack@google.com { 68213513Sgabeblack@google.com elaboration_check("register_get_direct_mem_ptr"); 68313513Sgabeblack@google.com m_fw_process.set_get_direct_mem_ptr(mod, cb); 68413513Sgabeblack@google.com m_fw_process.set_get_dmi_user_id(id); 68513513Sgabeblack@google.com } 68613513Sgabeblack@google.com 68713513Sgabeblack@google.com protected: 68813513Sgabeblack@google.com void 68913513Sgabeblack@google.com start_of_simulation() 69013513Sgabeblack@google.com { 69113513Sgabeblack@google.com base_type::start_of_simulation(); 69213513Sgabeblack@google.com m_fw_process.start_of_simulation(); 69313511Sgabeblack@google.com } 69413511Sgabeblack@google.com 69513511Sgabeblack@google.com private: 69613513Sgabeblack@google.com // Make call on bw path. 69713513Sgabeblack@google.com sync_enum_type 69813513Sgabeblack@google.com bw_nb_transport(transaction_type &trans, phase_type &phase, 69913513Sgabeblack@google.com sc_core::sc_time &t) 70013513Sgabeblack@google.com { 70113513Sgabeblack@google.com return base_type::operator -> ()->nb_transport_bw(trans, phase, t); 70213513Sgabeblack@google.com } 70313511Sgabeblack@google.com 70413513Sgabeblack@google.com void 70513513Sgabeblack@google.com bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 70613513Sgabeblack@google.com { 70713513Sgabeblack@google.com base_type::operator -> ()->invalidate_direct_mem_ptr(s, e); 70813513Sgabeblack@google.com } 70913511Sgabeblack@google.com 71013513Sgabeblack@google.com // Helper class to handle bw path calls Needed to detect transaction 71113513Sgabeblack@google.com // end when called from b_transport. 71213513Sgabeblack@google.com class bw_process : public tlm::tlm_bw_transport_if<TYPES> 71313513Sgabeblack@google.com { 71413513Sgabeblack@google.com public: 71513513Sgabeblack@google.com bw_process(simple_target_socket_tagged_b *p_own) : m_owner(p_own) {} 71613511Sgabeblack@google.com 71713513Sgabeblack@google.com sync_enum_type 71813513Sgabeblack@google.com nb_transport_bw(transaction_type &trans, phase_type &phase, 71913513Sgabeblack@google.com sc_core::sc_time &t) 72013513Sgabeblack@google.com { 72113513Sgabeblack@google.com typename std::map<transaction_type *, 72213513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 72313513Sgabeblack@google.com m_owner->m_pending_trans.find(&trans); 72413513Sgabeblack@google.com 72513513Sgabeblack@google.com if (it == m_owner->m_pending_trans.end()) { 72613513Sgabeblack@google.com // Not a blocking call, forward. 72713513Sgabeblack@google.com return m_owner->bw_nb_transport(trans, phase, t); 72813513Sgabeblack@google.com } 72913513Sgabeblack@google.com if (phase == tlm::END_REQ) { 73013513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 73113513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 73213513Sgabeblack@google.com } 73313513Sgabeblack@google.com if (phase == tlm::BEGIN_RESP) { 73413513Sgabeblack@google.com if (m_owner->m_current_transaction == &trans) { 73513513Sgabeblack@google.com m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 73613513Sgabeblack@google.com } 73713513Sgabeblack@google.com it->second->notify(t); 73813513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 73913513Sgabeblack@google.com return tlm::TLM_COMPLETED; 74013513Sgabeblack@google.com } 74113513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 74213513Sgabeblack@google.com return tlm::TLM_COMPLETED; 74313513Sgabeblack@google.com } 74413513Sgabeblack@google.com 74513513Sgabeblack@google.com void 74613513Sgabeblack@google.com invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e) 74713513Sgabeblack@google.com { 74813513Sgabeblack@google.com return m_owner->bw_invalidate_direct_mem_ptr(s, e); 74913513Sgabeblack@google.com } 75013513Sgabeblack@google.com 75113513Sgabeblack@google.com private: 75213513Sgabeblack@google.com simple_target_socket_tagged_b *m_owner; 75313511Sgabeblack@google.com }; 75413511Sgabeblack@google.com 75513513Sgabeblack@google.com class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 75613513Sgabeblack@google.com public tlm::tlm_mm_interface 75713513Sgabeblack@google.com { 75813513Sgabeblack@google.com public: 75913513Sgabeblack@google.com typedef sync_enum_type (MODULE::*NBTransportPtr)( 76013513Sgabeblack@google.com int id, transaction_type &, phase_type &, 76113513Sgabeblack@google.com sc_core::sc_time &); 76213513Sgabeblack@google.com typedef void (MODULE::*BTransportPtr)( 76313513Sgabeblack@google.com int id, transaction_type &, sc_core::sc_time &); 76413513Sgabeblack@google.com typedef unsigned int (MODULE::*TransportDbgPtr)( 76513513Sgabeblack@google.com int id, transaction_type &); 76613513Sgabeblack@google.com typedef bool (MODULE::*GetDirectMemPtr)( 76713513Sgabeblack@google.com int id, transaction_type &, tlm::tlm_dmi &); 76813511Sgabeblack@google.com 76913513Sgabeblack@google.com fw_process(simple_target_socket_tagged_b *p_own) : 77013513Sgabeblack@google.com m_owner(p_own), m_mod(0), m_nb_transport_ptr(0), 77113513Sgabeblack@google.com m_b_transport_ptr(0), m_transport_dbg_ptr(0), 77213513Sgabeblack@google.com m_get_direct_mem_ptr(0), m_nb_transport_user_id(0), 77313513Sgabeblack@google.com m_b_transport_user_id(0), m_transport_dbg_user_id(0), 77413513Sgabeblack@google.com m_get_dmi_user_id(0), 77513513Sgabeblack@google.com m_peq(sc_core::sc_gen_unique_name("m_peq")), 77613513Sgabeblack@google.com m_response_in_progress(false) 77713513Sgabeblack@google.com {} 77813511Sgabeblack@google.com 77913513Sgabeblack@google.com void 78013513Sgabeblack@google.com start_of_simulation() 78113513Sgabeblack@google.com { 78213513Sgabeblack@google.com if (!m_b_transport_ptr && m_nb_transport_ptr) { 78313513Sgabeblack@google.com // Only spawn b2nb_thread if needed. 78413513Sgabeblack@google.com sc_core::sc_spawn_options opts; 78513513Sgabeblack@google.com opts.set_sensitivity(&m_peq.get_event()); 78613513Sgabeblack@google.com opts.dont_initialize(); 78713513Sgabeblack@google.com sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 78813513Sgabeblack@google.com sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 78913513Sgabeblack@google.com } 79013511Sgabeblack@google.com } 79113511Sgabeblack@google.com 79213513Sgabeblack@google.com void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; } 79313513Sgabeblack@google.com void set_b_transport_user_id(int id) { m_b_transport_user_id = id; } 79413513Sgabeblack@google.com void 79513513Sgabeblack@google.com set_transport_dbg_user_id(int id) 79613513Sgabeblack@google.com { 79713513Sgabeblack@google.com m_transport_dbg_user_id = id; 79813513Sgabeblack@google.com } 79913513Sgabeblack@google.com void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; } 80013511Sgabeblack@google.com 80113513Sgabeblack@google.com void 80213513Sgabeblack@google.com set_nb_transport_ptr(MODULE *mod, NBTransportPtr p) 80313513Sgabeblack@google.com { 80413513Sgabeblack@google.com if (m_nb_transport_ptr) { 80513513Sgabeblack@google.com m_owner->display_warning( 80613513Sgabeblack@google.com "non-blocking callback already registered"); 80713513Sgabeblack@google.com return; 80813513Sgabeblack@google.com } 80913513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 81013513Sgabeblack@google.com m_mod = mod; 81113513Sgabeblack@google.com m_nb_transport_ptr = p; 81213513Sgabeblack@google.com } 81313511Sgabeblack@google.com 81413513Sgabeblack@google.com void 81513513Sgabeblack@google.com set_b_transport_ptr(MODULE* mod, BTransportPtr p) 81613513Sgabeblack@google.com { 81713513Sgabeblack@google.com if (m_b_transport_ptr) { 81813513Sgabeblack@google.com m_owner->display_warning( 81913513Sgabeblack@google.com "blocking callback already registered"); 82013513Sgabeblack@google.com return; 82113513Sgabeblack@google.com } 82213513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 82313513Sgabeblack@google.com m_mod = mod; 82413513Sgabeblack@google.com m_b_transport_ptr = p; 82513513Sgabeblack@google.com } 82613511Sgabeblack@google.com 82713513Sgabeblack@google.com void 82813513Sgabeblack@google.com set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p) 82913513Sgabeblack@google.com { 83013513Sgabeblack@google.com if (m_transport_dbg_ptr) { 83113513Sgabeblack@google.com m_owner->display_warning( 83213513Sgabeblack@google.com "debug callback already registered"); 83313513Sgabeblack@google.com return; 83413513Sgabeblack@google.com } 83513513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 83613513Sgabeblack@google.com m_mod = mod; 83713513Sgabeblack@google.com m_transport_dbg_ptr = p; 83813513Sgabeblack@google.com } 83913511Sgabeblack@google.com 84013513Sgabeblack@google.com void 84113513Sgabeblack@google.com set_get_direct_mem_ptr(MODULE *mod, GetDirectMemPtr p) 84213513Sgabeblack@google.com { 84313513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 84413513Sgabeblack@google.com m_owner->display_warning( 84513513Sgabeblack@google.com "get DMI pointer callback already registered"); 84613513Sgabeblack@google.com } 84713513Sgabeblack@google.com sc_assert(!m_mod || m_mod == mod); 84813513Sgabeblack@google.com m_mod = mod; 84913513Sgabeblack@google.com m_get_direct_mem_ptr = p; 85013513Sgabeblack@google.com } 85113511Sgabeblack@google.com 85213513Sgabeblack@google.com // Interface implementation. 85313513Sgabeblack@google.com sync_enum_type 85413513Sgabeblack@google.com nb_transport_fw(transaction_type &trans, phase_type &phase, 85513513Sgabeblack@google.com sc_core::sc_time &t) 85613513Sgabeblack@google.com { 85713513Sgabeblack@google.com if (m_nb_transport_ptr) { 85813513Sgabeblack@google.com // Forward call. 85913513Sgabeblack@google.com sc_assert(m_mod); 86013513Sgabeblack@google.com return (m_mod->*m_nb_transport_ptr)( 86113513Sgabeblack@google.com m_nb_transport_user_id, trans, phase, t); 86213511Sgabeblack@google.com } 86313511Sgabeblack@google.com 86413513Sgabeblack@google.com // nb->b conversion 86513513Sgabeblack@google.com if (m_b_transport_ptr) { 86613513Sgabeblack@google.com if (phase == tlm::BEGIN_REQ) { 86713513Sgabeblack@google.com 86813513Sgabeblack@google.com // Prepare thread to do blocking call. 86913513Sgabeblack@google.com process_handle_class *ph = 87013513Sgabeblack@google.com m_process_handle.get_handle(&trans); 87113513Sgabeblack@google.com 87213513Sgabeblack@google.com if (!ph) { // Create new dynamic process. 87313513Sgabeblack@google.com ph = new process_handle_class(&trans); 87413513Sgabeblack@google.com m_process_handle.put_handle(ph); 87513513Sgabeblack@google.com 87613513Sgabeblack@google.com sc_core::sc_spawn_options opts; 87713513Sgabeblack@google.com opts.dont_initialize(); 87813513Sgabeblack@google.com opts.set_sensitivity(&ph->m_e); 87913513Sgabeblack@google.com 88013513Sgabeblack@google.com sc_core::sc_spawn( 88113513Sgabeblack@google.com sc_bind(&fw_process::nb2b_thread, this, ph), 88213513Sgabeblack@google.com sc_core::sc_gen_unique_name("nb2b_thread"), 88313513Sgabeblack@google.com &opts); 88413513Sgabeblack@google.com } 88513513Sgabeblack@google.com 88613513Sgabeblack@google.com ph->m_e.notify(t); 88713513Sgabeblack@google.com return tlm::TLM_ACCEPTED; 88813513Sgabeblack@google.com } 88913513Sgabeblack@google.com if (phase == tlm::END_RESP) { 89013513Sgabeblack@google.com m_response_in_progress = false; 89113513Sgabeblack@google.com m_end_response.notify(t); 89213513Sgabeblack@google.com return tlm::TLM_COMPLETED; 89313513Sgabeblack@google.com } 89413513Sgabeblack@google.com m_owner->display_error("invalid phase"); 89513513Sgabeblack@google.com return tlm::TLM_COMPLETED; 89613511Sgabeblack@google.com } 89713511Sgabeblack@google.com 89813513Sgabeblack@google.com m_owner->display_error( 89913513Sgabeblack@google.com "no non-blocking transport callback registered"); 90013513Sgabeblack@google.com return tlm::TLM_COMPLETED; 90113511Sgabeblack@google.com } 90213511Sgabeblack@google.com 90313513Sgabeblack@google.com void 90413513Sgabeblack@google.com b_transport(transaction_type &trans, sc_core::sc_time &t) 90513513Sgabeblack@google.com { 90613513Sgabeblack@google.com if (m_b_transport_ptr) { 90713513Sgabeblack@google.com // Forward call. 90813513Sgabeblack@google.com sc_assert(m_mod); 90913513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t); 91013513Sgabeblack@google.com return; 91113513Sgabeblack@google.com } 91213511Sgabeblack@google.com 91313513Sgabeblack@google.com // b->nb conversion 91413513Sgabeblack@google.com if (m_nb_transport_ptr) { 91513513Sgabeblack@google.com m_peq.notify(trans, t); 91613513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 91713513Sgabeblack@google.com 91813513Sgabeblack@google.com mm_end_event_ext mm_ext; 91913513Sgabeblack@google.com const bool mm_added = !trans.has_mm(); 92013513Sgabeblack@google.com 92113513Sgabeblack@google.com if (mm_added) { 92213513Sgabeblack@google.com trans.set_mm(this); 92313513Sgabeblack@google.com trans.set_auto_extension(&mm_ext); 92413513Sgabeblack@google.com trans.acquire(); 92513513Sgabeblack@google.com } 92613513Sgabeblack@google.com 92713513Sgabeblack@google.com // Wait until transaction is finished. 92813513Sgabeblack@google.com sc_core::sc_event end_event; 92913513Sgabeblack@google.com m_owner->m_pending_trans[&trans] = &end_event; 93013513Sgabeblack@google.com sc_core::wait(end_event); 93113513Sgabeblack@google.com 93213513Sgabeblack@google.com if (mm_added) { 93313513Sgabeblack@google.com // Release will not delete the transaction, it will 93413513Sgabeblack@google.com // notify mm_ext.done. 93513513Sgabeblack@google.com trans.release(); 93613513Sgabeblack@google.com if (trans.get_ref_count()) { 93713513Sgabeblack@google.com sc_core::wait(mm_ext.done); 93813513Sgabeblack@google.com } 93913513Sgabeblack@google.com trans.set_mm(0); 94013513Sgabeblack@google.com } 94113513Sgabeblack@google.com return; 94213513Sgabeblack@google.com } 94313513Sgabeblack@google.com 94413513Sgabeblack@google.com m_owner->display_error("no transport callback registered"); 94513513Sgabeblack@google.com } 94613513Sgabeblack@google.com 94713513Sgabeblack@google.com unsigned int 94813513Sgabeblack@google.com transport_dbg(transaction_type &trans) 94913513Sgabeblack@google.com { 95013513Sgabeblack@google.com if (m_transport_dbg_ptr) { 95113513Sgabeblack@google.com // Forward call. 95213513Sgabeblack@google.com sc_assert(m_mod); 95313513Sgabeblack@google.com return (m_mod->*m_transport_dbg_ptr)( 95413513Sgabeblack@google.com m_transport_dbg_user_id, trans); 95513513Sgabeblack@google.com } 95613513Sgabeblack@google.com // No debug support. 95713513Sgabeblack@google.com return 0; 95813513Sgabeblack@google.com } 95913513Sgabeblack@google.com 96013513Sgabeblack@google.com bool 96113513Sgabeblack@google.com get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data) 96213513Sgabeblack@google.com { 96313513Sgabeblack@google.com if (m_get_direct_mem_ptr) { 96413513Sgabeblack@google.com // Forward call. 96513513Sgabeblack@google.com sc_assert(m_mod); 96613513Sgabeblack@google.com return (m_mod->*m_get_direct_mem_ptr)( 96713513Sgabeblack@google.com m_get_dmi_user_id, trans, dmi_data); 96813513Sgabeblack@google.com } 96913513Sgabeblack@google.com // No DMI support. 97013513Sgabeblack@google.com dmi_data.allow_read_write(); 97113513Sgabeblack@google.com dmi_data.set_start_address(0x0); 97213513Sgabeblack@google.com dmi_data.set_end_address((sc_dt::uint64)-1); 97313513Sgabeblack@google.com return false; 97413513Sgabeblack@google.com } 97513513Sgabeblack@google.com 97613513Sgabeblack@google.com private: 97713513Sgabeblack@google.com 97813513Sgabeblack@google.com // Dynamic process handler for nb2b conversion. 97913513Sgabeblack@google.com class process_handle_class 98013513Sgabeblack@google.com { 98113513Sgabeblack@google.com public: 98213513Sgabeblack@google.com explicit process_handle_class(transaction_type *trans) : 98313513Sgabeblack@google.com m_trans(trans), m_suspend(false) 98413513Sgabeblack@google.com {} 98513513Sgabeblack@google.com 98613513Sgabeblack@google.com transaction_type *m_trans; 98713513Sgabeblack@google.com sc_core::sc_event m_e; 98813513Sgabeblack@google.com bool m_suspend; 98913513Sgabeblack@google.com }; 99013513Sgabeblack@google.com 99113513Sgabeblack@google.com class process_handle_list 99213513Sgabeblack@google.com { 99313513Sgabeblack@google.com public: 99413513Sgabeblack@google.com process_handle_list() {} 99513513Sgabeblack@google.com 99613513Sgabeblack@google.com ~process_handle_list() 99713513Sgabeblack@google.com { 99813513Sgabeblack@google.com for (typename std::vector< 99913513Sgabeblack@google.com process_handle_class *>::iterator it = v.begin(), 100013513Sgabeblack@google.com end = v.end(); it != end; ++it) { 100113513Sgabeblack@google.com delete *it; 100213513Sgabeblack@google.com } 100313513Sgabeblack@google.com } 100413513Sgabeblack@google.com 100513513Sgabeblack@google.com process_handle_class * 100613513Sgabeblack@google.com get_handle(transaction_type *trans) 100713513Sgabeblack@google.com { 100813513Sgabeblack@google.com typename std::vector<process_handle_class *>::iterator it; 100913513Sgabeblack@google.com 101013513Sgabeblack@google.com for (it = v.begin(); it != v.end(); it++) { 101113513Sgabeblack@google.com if ((*it)->m_suspend) { 101213513Sgabeblack@google.com // Found suspended dynamic process, re-use it. 101313513Sgabeblack@google.com (*it)->m_trans = trans; // Replace to new one. 101413513Sgabeblack@google.com (*it)->m_suspend = false; 101513513Sgabeblack@google.com return *it; 101613513Sgabeblack@google.com } 101713513Sgabeblack@google.com } 101813513Sgabeblack@google.com return NULL; // No suspended process. 101913513Sgabeblack@google.com } 102013513Sgabeblack@google.com 102113513Sgabeblack@google.com void put_handle(process_handle_class *ph) { v.push_back(ph); } 102213513Sgabeblack@google.com 102313513Sgabeblack@google.com private: 102413513Sgabeblack@google.com std::vector<process_handle_class *> v; 102513513Sgabeblack@google.com }; 102613513Sgabeblack@google.com 102713513Sgabeblack@google.com process_handle_list m_process_handle; 102813513Sgabeblack@google.com 102913513Sgabeblack@google.com void 103013513Sgabeblack@google.com nb2b_thread(process_handle_class *h) 103113513Sgabeblack@google.com { 103213513Sgabeblack@google.com 103313513Sgabeblack@google.com while (1) { 103413513Sgabeblack@google.com transaction_type *trans = h->m_trans; 103513513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 103613513Sgabeblack@google.com 103713513Sgabeblack@google.com // Forward call. 103813513Sgabeblack@google.com sc_assert(m_mod); 103913513Sgabeblack@google.com (m_mod->*m_b_transport_ptr)( 104013513Sgabeblack@google.com m_b_transport_user_id, *trans, t); 104113513Sgabeblack@google.com 104213513Sgabeblack@google.com sc_core::wait(t); 104313513Sgabeblack@google.com 104413513Sgabeblack@google.com // Return path. 104513513Sgabeblack@google.com while (m_response_in_progress) { 104613513Sgabeblack@google.com sc_core::wait(m_end_response); 104713513Sgabeblack@google.com } 104813513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 104913513Sgabeblack@google.com phase_type phase = tlm::BEGIN_RESP; 105013513Sgabeblack@google.com sync_enum_type sync = 105113513Sgabeblack@google.com m_owner->bw_nb_transport(*trans, phase, t); 105213513Sgabeblack@google.com if (!(sync == tlm::TLM_COMPLETED || 105313513Sgabeblack@google.com (sync == tlm::TLM_UPDATED && 105413513Sgabeblack@google.com phase == tlm::END_RESP))) { 105513513Sgabeblack@google.com m_response_in_progress = true; 105613513Sgabeblack@google.com } 105713513Sgabeblack@google.com 105813513Sgabeblack@google.com // Suspend until next transaction. 105913513Sgabeblack@google.com h->m_suspend = true; 106013513Sgabeblack@google.com sc_core::wait(); 106113513Sgabeblack@google.com } 106213513Sgabeblack@google.com } 106313513Sgabeblack@google.com 106413513Sgabeblack@google.com void 106513513Sgabeblack@google.com b2nb_thread() 106613513Sgabeblack@google.com { 106713513Sgabeblack@google.com while (true) { 106813513Sgabeblack@google.com transaction_type *trans; 106913513Sgabeblack@google.com while ((trans = m_peq.get_next_transaction()) != 0) { 107013513Sgabeblack@google.com sc_assert(m_mod); 107113513Sgabeblack@google.com sc_assert(m_nb_transport_ptr); 107213513Sgabeblack@google.com phase_type phase = tlm::BEGIN_REQ; 107313513Sgabeblack@google.com sc_core::sc_time t = sc_core::SC_ZERO_TIME; 107413513Sgabeblack@google.com 107513513Sgabeblack@google.com switch ((m_mod->*m_nb_transport_ptr)( 107613513Sgabeblack@google.com m_nb_transport_user_id, *trans, phase, t)) { 107713513Sgabeblack@google.com case tlm::TLM_COMPLETED: 107813513Sgabeblack@google.com { 107913513Sgabeblack@google.com // Notify transaction is finished. 108013513Sgabeblack@google.com typename std::map<transaction_type *, 108113513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 108213513Sgabeblack@google.com m_owner->m_pending_trans.find(trans); 108313513Sgabeblack@google.com sc_assert(it != m_owner->m_pending_trans.end()); 108413513Sgabeblack@google.com it->second->notify(t); 108513513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 108613513Sgabeblack@google.com break; 108713513Sgabeblack@google.com } 108813513Sgabeblack@google.com 108913513Sgabeblack@google.com case tlm::TLM_ACCEPTED: 109013513Sgabeblack@google.com case tlm::TLM_UPDATED: 109113513Sgabeblack@google.com switch (phase) { 109213513Sgabeblack@google.com case tlm::BEGIN_REQ: 109313513Sgabeblack@google.com m_owner->m_current_transaction = trans; 109413513Sgabeblack@google.com sc_core::wait(m_owner->m_end_request); 109513513Sgabeblack@google.com m_owner->m_current_transaction = 0; 109613513Sgabeblack@google.com break; 109713513Sgabeblack@google.com 109813513Sgabeblack@google.com case tlm::END_REQ: 109913513Sgabeblack@google.com sc_core::wait(t); 110013513Sgabeblack@google.com break; 110113513Sgabeblack@google.com 110213513Sgabeblack@google.com case tlm::BEGIN_RESP: 110313513Sgabeblack@google.com { 110413513Sgabeblack@google.com phase = tlm::END_RESP; 110513513Sgabeblack@google.com // This line is a bug fix added in TLM-2.0.2. 110613513Sgabeblack@google.com sc_core::wait(t); 110713513Sgabeblack@google.com t = sc_core::SC_ZERO_TIME; 110813513Sgabeblack@google.com (m_mod->*m_nb_transport_ptr)( 110913513Sgabeblack@google.com m_nb_transport_user_id, 111013513Sgabeblack@google.com *trans, phase, t); 111113513Sgabeblack@google.com 111213513Sgabeblack@google.com // Notify transaction is finished. 111313513Sgabeblack@google.com typename std::map<transaction_type *, 111413513Sgabeblack@google.com sc_core::sc_event *>::iterator it = 111513513Sgabeblack@google.com m_owner->m_pending_trans.find( 111613513Sgabeblack@google.com trans); 111713513Sgabeblack@google.com sc_assert(it != 111813513Sgabeblack@google.com m_owner->m_pending_trans.end()); 111913513Sgabeblack@google.com it->second->notify(t); 112013513Sgabeblack@google.com m_owner->m_pending_trans.erase(it); 112113513Sgabeblack@google.com break; 112213513Sgabeblack@google.com } 112313513Sgabeblack@google.com 112413513Sgabeblack@google.com default: 112513513Sgabeblack@google.com m_owner->display_error("invalid phase received"); 112613513Sgabeblack@google.com }; 112713513Sgabeblack@google.com break; 112813513Sgabeblack@google.com 112913513Sgabeblack@google.com default: 113013513Sgabeblack@google.com m_owner->display_error("invalid sync value received"); 113113513Sgabeblack@google.com } 113213513Sgabeblack@google.com } 113313513Sgabeblack@google.com sc_core::wait(); 113413513Sgabeblack@google.com } 113513513Sgabeblack@google.com } 113613513Sgabeblack@google.com 113713513Sgabeblack@google.com void 113813513Sgabeblack@google.com free(tlm::tlm_generic_payload *trans) 113913513Sgabeblack@google.com { 114013513Sgabeblack@google.com mm_end_event_ext *ext = 114113513Sgabeblack@google.com trans->template get_extension<mm_end_event_ext>(); 114213513Sgabeblack@google.com sc_assert(ext); 114313513Sgabeblack@google.com // Notify event first before freeing extensions (reset). 114413513Sgabeblack@google.com ext->done.notify(); 114513513Sgabeblack@google.com trans->reset(); 114613513Sgabeblack@google.com } 114713513Sgabeblack@google.com 114813513Sgabeblack@google.com private: 114913513Sgabeblack@google.com struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 115013513Sgabeblack@google.com { 115113513Sgabeblack@google.com tlm::tlm_extension_base *clone() const { return NULL; } 115213513Sgabeblack@google.com void free() {} 115313513Sgabeblack@google.com void copy_from(tlm::tlm_extension_base const &) {} 115413513Sgabeblack@google.com sc_core::sc_event done; 115513513Sgabeblack@google.com }; 115613513Sgabeblack@google.com 115713513Sgabeblack@google.com private: 115813513Sgabeblack@google.com simple_target_socket_tagged_b *m_owner; 115913513Sgabeblack@google.com MODULE *m_mod; 116013513Sgabeblack@google.com NBTransportPtr m_nb_transport_ptr; 116113513Sgabeblack@google.com BTransportPtr m_b_transport_ptr; 116213513Sgabeblack@google.com TransportDbgPtr m_transport_dbg_ptr; 116313513Sgabeblack@google.com GetDirectMemPtr m_get_direct_mem_ptr; 116413513Sgabeblack@google.com int m_nb_transport_user_id; 116513513Sgabeblack@google.com int m_b_transport_user_id; 116613513Sgabeblack@google.com int m_transport_dbg_user_id; 116713513Sgabeblack@google.com int m_get_dmi_user_id; 116813513Sgabeblack@google.com peq_with_get<transaction_type> m_peq; 116913513Sgabeblack@google.com bool m_response_in_progress; 117013513Sgabeblack@google.com sc_core::sc_event m_end_response; 117113511Sgabeblack@google.com }; 117213511Sgabeblack@google.com 117313511Sgabeblack@google.com private: 117413513Sgabeblack@google.com const sc_core::sc_object *get_socket() const { return this; } 117513511Sgabeblack@google.com 117613513Sgabeblack@google.com private: 117713513Sgabeblack@google.com fw_process m_fw_process; 117813513Sgabeblack@google.com bw_process m_bw_process; 117913513Sgabeblack@google.com std::map<transaction_type *, sc_core::sc_event *> m_pending_trans; 118013513Sgabeblack@google.com sc_core::sc_event m_end_request; 118113513Sgabeblack@google.com transaction_type* m_current_transaction; 118213511Sgabeblack@google.com}; 118313511Sgabeblack@google.com 118413513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 118513513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 118613513Sgabeblack@google.comclass simple_target_socket_tagged : 118713513Sgabeblack@google.com public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES> 118813511Sgabeblack@google.com{ 118913513Sgabeblack@google.com typedef simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES> socket_b; 119013513Sgabeblack@google.com public: 119113513Sgabeblack@google.com simple_target_socket_tagged() : socket_b() {} 119213513Sgabeblack@google.com explicit simple_target_socket_tagged(const char *name) : socket_b(name) {} 119313511Sgabeblack@google.com}; 119413511Sgabeblack@google.com 119513513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32, 119613513Sgabeblack@google.com typename TYPES=tlm::tlm_base_protocol_types> 119713513Sgabeblack@google.comclass simple_target_socket_tagged_optional : 119813513Sgabeblack@google.com public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES, 119913513Sgabeblack@google.com sc_core::SC_ZERO_OR_MORE_BOUND> 120013511Sgabeblack@google.com{ 120113513Sgabeblack@google.com typedef simple_target_socket_tagged_b< 120213513Sgabeblack@google.com MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 120313511Sgabeblack@google.com public: 120413513Sgabeblack@google.com simple_target_socket_tagged_optional() : socket_b() {} 120513513Sgabeblack@google.com explicit simple_target_socket_tagged_optional(const char *name) : 120613513Sgabeblack@google.com socket_b(name) 120713511Sgabeblack@google.com {} 120813511Sgabeblack@google.com}; 120913511Sgabeblack@google.com 121013511Sgabeblack@google.com} // namespace tlm_utils 121113513Sgabeblack@google.com 121213513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__ */ 1213