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