simple_target_socket.h revision 12027
112027Sjungma@eit.uni-kl.de/***************************************************************************** 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412027Sjungma@eit.uni-kl.de more contributor license agreements. See the NOTICE file distributed 512027Sjungma@eit.uni-kl.de with this work for additional information regarding copyright ownership. 612027Sjungma@eit.uni-kl.de Accellera licenses this file to you under the Apache License, Version 2.0 712027Sjungma@eit.uni-kl.de (the "License"); you may not use this file except in compliance with the 812027Sjungma@eit.uni-kl.de License. You may obtain a copy of the License at 912027Sjungma@eit.uni-kl.de 1012027Sjungma@eit.uni-kl.de http://www.apache.org/licenses/LICENSE-2.0 1112027Sjungma@eit.uni-kl.de 1212027Sjungma@eit.uni-kl.de Unless required by applicable law or agreed to in writing, software 1312027Sjungma@eit.uni-kl.de distributed under the License is distributed on an "AS IS" BASIS, 1412027Sjungma@eit.uni-kl.de WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512027Sjungma@eit.uni-kl.de implied. See the License for the specific language governing 1612027Sjungma@eit.uni-kl.de permissions and limitations under the License. 1712027Sjungma@eit.uni-kl.de 1812027Sjungma@eit.uni-kl.de *****************************************************************************/ 1912027Sjungma@eit.uni-kl.de 2012027Sjungma@eit.uni-kl.de// ***************************************************************************** 2112027Sjungma@eit.uni-kl.de// Modified by John Aynsley, Doulos, Feb 2009, 2212027Sjungma@eit.uni-kl.de// Fix a bug in simple_target_socket and simple_target_socket_tagged 2312027Sjungma@eit.uni-kl.de// with the addition of one new line of code in each: wait(*e); 2412027Sjungma@eit.uni-kl.de// ***************************************************************************** 2512027Sjungma@eit.uni-kl.de 2612027Sjungma@eit.uni-kl.de// ***************************************************************************** 2712027Sjungma@eit.uni-kl.de// Modified by John Aynsley on behalf of Robert Guenzel, May 2011, 2812027Sjungma@eit.uni-kl.de// Fix a bug in simple_target_socket and simple_target_socket_tagged 2912027Sjungma@eit.uni-kl.de// with the addition of one new line of code in each: wait(t); 3012027Sjungma@eit.uni-kl.de// ***************************************************************************** 3112027Sjungma@eit.uni-kl.de 3212027Sjungma@eit.uni-kl.de 3312027Sjungma@eit.uni-kl.de#ifndef __SIMPLE_TARGET_SOCKET_H__ 3412027Sjungma@eit.uni-kl.de#define __SIMPLE_TARGET_SOCKET_H__ 3512027Sjungma@eit.uni-kl.de 3612027Sjungma@eit.uni-kl.de#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn 3712027Sjungma@eit.uni-kl.de# define SC_INCLUDE_DYNAMIC_PROCESSES 3812027Sjungma@eit.uni-kl.de#endif 3912027Sjungma@eit.uni-kl.de 4012027Sjungma@eit.uni-kl.de#include <systemc> 4112027Sjungma@eit.uni-kl.de#include <tlm> 4212027Sjungma@eit.uni-kl.de#include "tlm_utils/peq_with_get.h" 4312027Sjungma@eit.uni-kl.de#include <sstream> 4412027Sjungma@eit.uni-kl.de 4512027Sjungma@eit.uni-kl.denamespace tlm_utils { 4612027Sjungma@eit.uni-kl.de 4712027Sjungma@eit.uni-kl.detemplate <typename MODULE, 4812027Sjungma@eit.uni-kl.de unsigned int BUSWIDTH = 32, 4912027Sjungma@eit.uni-kl.de typename TYPES = tlm::tlm_base_protocol_types> 5012027Sjungma@eit.uni-kl.declass simple_target_socket : 5112027Sjungma@eit.uni-kl.de public tlm::tlm_target_socket<BUSWIDTH, TYPES> 5212027Sjungma@eit.uni-kl.de{ 5312027Sjungma@eit.uni-kl.de friend class fw_process; 5412027Sjungma@eit.uni-kl.de friend class bw_process; 5512027Sjungma@eit.uni-kl.depublic: 5612027Sjungma@eit.uni-kl.de typedef typename TYPES::tlm_payload_type transaction_type; 5712027Sjungma@eit.uni-kl.de typedef typename TYPES::tlm_phase_type phase_type; 5812027Sjungma@eit.uni-kl.de typedef tlm::tlm_sync_enum sync_enum_type; 5912027Sjungma@eit.uni-kl.de typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 6012027Sjungma@eit.uni-kl.de typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 6112027Sjungma@eit.uni-kl.de typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type; 6212027Sjungma@eit.uni-kl.de 6312027Sjungma@eit.uni-kl.depublic: 6412027Sjungma@eit.uni-kl.de simple_target_socket() : 6512027Sjungma@eit.uni-kl.de base_type(sc_core::sc_gen_unique_name("simple_target_socket")), 6612027Sjungma@eit.uni-kl.de m_fw_process(this), 6712027Sjungma@eit.uni-kl.de m_bw_process(this) 6812027Sjungma@eit.uni-kl.de { 6912027Sjungma@eit.uni-kl.de bind(m_fw_process); 7012027Sjungma@eit.uni-kl.de } 7112027Sjungma@eit.uni-kl.de 7212027Sjungma@eit.uni-kl.de explicit simple_target_socket(const char* n) : 7312027Sjungma@eit.uni-kl.de base_type(n), 7412027Sjungma@eit.uni-kl.de m_fw_process(this), 7512027Sjungma@eit.uni-kl.de m_bw_process(this) 7612027Sjungma@eit.uni-kl.de { 7712027Sjungma@eit.uni-kl.de bind(m_fw_process); 7812027Sjungma@eit.uni-kl.de } 7912027Sjungma@eit.uni-kl.de 8012027Sjungma@eit.uni-kl.de using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind; 8112027Sjungma@eit.uni-kl.de 8212027Sjungma@eit.uni-kl.de // bw transport must come thru us. 8312027Sjungma@eit.uni-kl.de tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;} 8412027Sjungma@eit.uni-kl.de 8512027Sjungma@eit.uni-kl.de // REGISTER_XXX 8612027Sjungma@eit.uni-kl.de void register_nb_transport_fw(MODULE* mod, 8712027Sjungma@eit.uni-kl.de sync_enum_type (MODULE::*cb)(transaction_type&, 8812027Sjungma@eit.uni-kl.de phase_type&, 8912027Sjungma@eit.uni-kl.de sc_core::sc_time&)) 9012027Sjungma@eit.uni-kl.de { 9112027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 9212027Sjungma@eit.uni-kl.de m_fw_process.set_nb_transport_ptr(mod, cb); 9312027Sjungma@eit.uni-kl.de } 9412027Sjungma@eit.uni-kl.de 9512027Sjungma@eit.uni-kl.de void register_b_transport(MODULE* mod, 9612027Sjungma@eit.uni-kl.de void (MODULE::*cb)(transaction_type&, 9712027Sjungma@eit.uni-kl.de sc_core::sc_time&)) 9812027Sjungma@eit.uni-kl.de { 9912027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 10012027Sjungma@eit.uni-kl.de m_fw_process.set_b_transport_ptr(mod, cb); 10112027Sjungma@eit.uni-kl.de } 10212027Sjungma@eit.uni-kl.de 10312027Sjungma@eit.uni-kl.de void register_transport_dbg(MODULE* mod, 10412027Sjungma@eit.uni-kl.de unsigned int (MODULE::*cb)(transaction_type&)) 10512027Sjungma@eit.uni-kl.de { 10612027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 10712027Sjungma@eit.uni-kl.de m_fw_process.set_transport_dbg_ptr(mod, cb); 10812027Sjungma@eit.uni-kl.de } 10912027Sjungma@eit.uni-kl.de 11012027Sjungma@eit.uni-kl.de void register_get_direct_mem_ptr(MODULE* mod, 11112027Sjungma@eit.uni-kl.de bool (MODULE::*cb)(transaction_type&, 11212027Sjungma@eit.uni-kl.de tlm::tlm_dmi&)) 11312027Sjungma@eit.uni-kl.de { 11412027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 11512027Sjungma@eit.uni-kl.de m_fw_process.set_get_direct_mem_ptr(mod, cb); 11612027Sjungma@eit.uni-kl.de } 11712027Sjungma@eit.uni-kl.de 11812027Sjungma@eit.uni-kl.deprivate: 11912027Sjungma@eit.uni-kl.de //make call on bw path. 12012027Sjungma@eit.uni-kl.de sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t) 12112027Sjungma@eit.uni-kl.de { 12212027Sjungma@eit.uni-kl.de return base_type::operator ->()->nb_transport_bw(trans, phase, t); 12312027Sjungma@eit.uni-kl.de } 12412027Sjungma@eit.uni-kl.de 12512027Sjungma@eit.uni-kl.de void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e) 12612027Sjungma@eit.uni-kl.de { 12712027Sjungma@eit.uni-kl.de base_type::operator ->()->invalidate_direct_mem_ptr(s, e); 12812027Sjungma@eit.uni-kl.de } 12912027Sjungma@eit.uni-kl.de 13012027Sjungma@eit.uni-kl.de //Helper class to handle bw path calls 13112027Sjungma@eit.uni-kl.de // Needed to detect transaction end when called from b_transport. 13212027Sjungma@eit.uni-kl.de class bw_process : public tlm::tlm_bw_transport_if<TYPES> 13312027Sjungma@eit.uni-kl.de { 13412027Sjungma@eit.uni-kl.de public: 13512027Sjungma@eit.uni-kl.de bw_process(simple_target_socket *p_own) : m_owner(p_own) 13612027Sjungma@eit.uni-kl.de { 13712027Sjungma@eit.uni-kl.de } 13812027Sjungma@eit.uni-kl.de 13912027Sjungma@eit.uni-kl.de sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t) 14012027Sjungma@eit.uni-kl.de { 14112027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it; 14212027Sjungma@eit.uni-kl.de 14312027Sjungma@eit.uni-kl.de it = m_owner->m_pending_trans.find(&trans); 14412027Sjungma@eit.uni-kl.de if(it == m_owner->m_pending_trans.end()) { 14512027Sjungma@eit.uni-kl.de // Not a blocking call, forward. 14612027Sjungma@eit.uni-kl.de return m_owner->bw_nb_transport(trans, phase, t); 14712027Sjungma@eit.uni-kl.de 14812027Sjungma@eit.uni-kl.de } else { 14912027Sjungma@eit.uni-kl.de if (phase == tlm::END_REQ) { 15012027Sjungma@eit.uni-kl.de m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15112027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; 15212027Sjungma@eit.uni-kl.de 15312027Sjungma@eit.uni-kl.de } else if (phase == tlm::BEGIN_RESP) { 15412027Sjungma@eit.uni-kl.de if (m_owner->m_current_transaction == &trans) { 15512027Sjungma@eit.uni-kl.de m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 15612027Sjungma@eit.uni-kl.de } 15712027Sjungma@eit.uni-kl.de //TODO: add response-accept delay? 15812027Sjungma@eit.uni-kl.de it->second->notify(t); 15912027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 16012027Sjungma@eit.uni-kl.de return tlm::TLM_COMPLETED; 16112027Sjungma@eit.uni-kl.de 16212027Sjungma@eit.uni-kl.de } else { 16312027Sjungma@eit.uni-kl.de assert(0); exit(1); 16412027Sjungma@eit.uni-kl.de } 16512027Sjungma@eit.uni-kl.de 16612027Sjungma@eit.uni-kl.de// return tlm::TLM_COMPLETED; //Should not reach here 16712027Sjungma@eit.uni-kl.de } 16812027Sjungma@eit.uni-kl.de } 16912027Sjungma@eit.uni-kl.de 17012027Sjungma@eit.uni-kl.de void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e) 17112027Sjungma@eit.uni-kl.de { 17212027Sjungma@eit.uni-kl.de return m_owner->bw_invalidate_direct_mem_ptr(s, e); 17312027Sjungma@eit.uni-kl.de } 17412027Sjungma@eit.uni-kl.de 17512027Sjungma@eit.uni-kl.de private: 17612027Sjungma@eit.uni-kl.de simple_target_socket *m_owner; 17712027Sjungma@eit.uni-kl.de }; 17812027Sjungma@eit.uni-kl.de 17912027Sjungma@eit.uni-kl.de class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 18012027Sjungma@eit.uni-kl.de public tlm::tlm_mm_interface 18112027Sjungma@eit.uni-kl.de { 18212027Sjungma@eit.uni-kl.de public: 18312027Sjungma@eit.uni-kl.de typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&, 18412027Sjungma@eit.uni-kl.de phase_type&, 18512027Sjungma@eit.uni-kl.de sc_core::sc_time&); 18612027Sjungma@eit.uni-kl.de typedef void (MODULE::*BTransportPtr)(transaction_type&, 18712027Sjungma@eit.uni-kl.de sc_core::sc_time&); 18812027Sjungma@eit.uni-kl.de typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&); 18912027Sjungma@eit.uni-kl.de typedef bool (MODULE::*GetDirectMemPtr)(transaction_type&, 19012027Sjungma@eit.uni-kl.de tlm::tlm_dmi&); 19112027Sjungma@eit.uni-kl.de 19212027Sjungma@eit.uni-kl.de fw_process(simple_target_socket *p_own) : 19312027Sjungma@eit.uni-kl.de m_name(p_own->name()), 19412027Sjungma@eit.uni-kl.de m_owner(p_own), 19512027Sjungma@eit.uni-kl.de m_mod(0), 19612027Sjungma@eit.uni-kl.de m_nb_transport_ptr(0), 19712027Sjungma@eit.uni-kl.de m_b_transport_ptr(0), 19812027Sjungma@eit.uni-kl.de m_transport_dbg_ptr(0), 19912027Sjungma@eit.uni-kl.de m_get_direct_mem_ptr(0), 20012027Sjungma@eit.uni-kl.de m_peq(sc_core::sc_gen_unique_name("m_peq")), 20112027Sjungma@eit.uni-kl.de m_response_in_progress(false) 20212027Sjungma@eit.uni-kl.de { 20312027Sjungma@eit.uni-kl.de sc_core::sc_spawn_options opts; 20412027Sjungma@eit.uni-kl.de opts.set_sensitivity(&m_peq.get_event()); 20512027Sjungma@eit.uni-kl.de sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 20612027Sjungma@eit.uni-kl.de sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 20712027Sjungma@eit.uni-kl.de } 20812027Sjungma@eit.uni-kl.de 20912027Sjungma@eit.uni-kl.de void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p) 21012027Sjungma@eit.uni-kl.de { 21112027Sjungma@eit.uni-kl.de if (m_nb_transport_ptr) { 21212027Sjungma@eit.uni-kl.de std::stringstream s; 21312027Sjungma@eit.uni-kl.de s << m_name << ": non-blocking callback allready registered"; 21412027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 21512027Sjungma@eit.uni-kl.de } else { 21612027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 21712027Sjungma@eit.uni-kl.de m_mod = mod; 21812027Sjungma@eit.uni-kl.de m_nb_transport_ptr = p; 21912027Sjungma@eit.uni-kl.de } 22012027Sjungma@eit.uni-kl.de } 22112027Sjungma@eit.uni-kl.de 22212027Sjungma@eit.uni-kl.de void set_b_transport_ptr(MODULE* mod, BTransportPtr p) 22312027Sjungma@eit.uni-kl.de { 22412027Sjungma@eit.uni-kl.de if (m_b_transport_ptr) { 22512027Sjungma@eit.uni-kl.de std::stringstream s; 22612027Sjungma@eit.uni-kl.de s << m_name << ": blocking callback allready registered"; 22712027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 22812027Sjungma@eit.uni-kl.de } else { 22912027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 23012027Sjungma@eit.uni-kl.de m_mod = mod; 23112027Sjungma@eit.uni-kl.de m_b_transport_ptr = p; 23212027Sjungma@eit.uni-kl.de } 23312027Sjungma@eit.uni-kl.de } 23412027Sjungma@eit.uni-kl.de 23512027Sjungma@eit.uni-kl.de void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p) 23612027Sjungma@eit.uni-kl.de { 23712027Sjungma@eit.uni-kl.de if (m_transport_dbg_ptr) { 23812027Sjungma@eit.uni-kl.de std::stringstream s; 23912027Sjungma@eit.uni-kl.de s << m_name << ": debug callback allready registered"; 24012027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 24112027Sjungma@eit.uni-kl.de } else { 24212027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 24312027Sjungma@eit.uni-kl.de m_mod = mod; 24412027Sjungma@eit.uni-kl.de m_transport_dbg_ptr = p; 24512027Sjungma@eit.uni-kl.de } 24612027Sjungma@eit.uni-kl.de } 24712027Sjungma@eit.uni-kl.de 24812027Sjungma@eit.uni-kl.de void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p) 24912027Sjungma@eit.uni-kl.de { 25012027Sjungma@eit.uni-kl.de if (m_get_direct_mem_ptr) { 25112027Sjungma@eit.uni-kl.de std::stringstream s; 25212027Sjungma@eit.uni-kl.de s << m_name << ": get DMI pointer callback allready registered"; 25312027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 25412027Sjungma@eit.uni-kl.de } else { 25512027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 25612027Sjungma@eit.uni-kl.de m_mod = mod; 25712027Sjungma@eit.uni-kl.de m_get_direct_mem_ptr = p; 25812027Sjungma@eit.uni-kl.de } 25912027Sjungma@eit.uni-kl.de } 26012027Sjungma@eit.uni-kl.de// Interface implementation 26112027Sjungma@eit.uni-kl.de sync_enum_type nb_transport_fw(transaction_type& trans, 26212027Sjungma@eit.uni-kl.de phase_type& phase, 26312027Sjungma@eit.uni-kl.de sc_core::sc_time& t) 26412027Sjungma@eit.uni-kl.de { 26512027Sjungma@eit.uni-kl.de if (m_nb_transport_ptr) { 26612027Sjungma@eit.uni-kl.de // forward call 26712027Sjungma@eit.uni-kl.de assert(m_mod); 26812027Sjungma@eit.uni-kl.de return (m_mod->*m_nb_transport_ptr)(trans, phase, t); 26912027Sjungma@eit.uni-kl.de 27012027Sjungma@eit.uni-kl.de } else if (m_b_transport_ptr) { 27112027Sjungma@eit.uni-kl.de if (phase == tlm::BEGIN_REQ) { 27212027Sjungma@eit.uni-kl.de // prepare thread to do blocking call 27312027Sjungma@eit.uni-kl.de process_handle_class * ph = m_process_handle.get_handle(&trans); 27412027Sjungma@eit.uni-kl.de 27512027Sjungma@eit.uni-kl.de if (!ph) { // create new dynamic process 27612027Sjungma@eit.uni-kl.de ph = new process_handle_class(&trans); 27712027Sjungma@eit.uni-kl.de m_process_handle.put_handle(ph); 27812027Sjungma@eit.uni-kl.de 27912027Sjungma@eit.uni-kl.de sc_core::sc_spawn_options opts; 28012027Sjungma@eit.uni-kl.de opts.dont_initialize(); 28112027Sjungma@eit.uni-kl.de opts.set_sensitivity(&ph->m_e); 28212027Sjungma@eit.uni-kl.de 28312027Sjungma@eit.uni-kl.de sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread,this, ph), 28412027Sjungma@eit.uni-kl.de sc_core::sc_gen_unique_name("nb2b_thread"), &opts); 28512027Sjungma@eit.uni-kl.de } 28612027Sjungma@eit.uni-kl.de 28712027Sjungma@eit.uni-kl.de ph->m_e.notify(t); 28812027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; 28912027Sjungma@eit.uni-kl.de 29012027Sjungma@eit.uni-kl.de } else if (phase == tlm::END_RESP) { 29112027Sjungma@eit.uni-kl.de m_response_in_progress = false; 29212027Sjungma@eit.uni-kl.de m_end_response.notify(t); 29312027Sjungma@eit.uni-kl.de return tlm::TLM_COMPLETED; 29412027Sjungma@eit.uni-kl.de 29512027Sjungma@eit.uni-kl.de } else { 29612027Sjungma@eit.uni-kl.de assert(0); exit(1); 29712027Sjungma@eit.uni-kl.de// return tlm::TLM_COMPLETED; ///< unreachable code 29812027Sjungma@eit.uni-kl.de } 29912027Sjungma@eit.uni-kl.de 30012027Sjungma@eit.uni-kl.de } else { 30112027Sjungma@eit.uni-kl.de std::stringstream s; 30212027Sjungma@eit.uni-kl.de s << m_name << ": no non-blocking transport callback registered"; 30312027Sjungma@eit.uni-kl.de SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 30412027Sjungma@eit.uni-kl.de } 30512027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; ///< unreachable code 30612027Sjungma@eit.uni-kl.de } 30712027Sjungma@eit.uni-kl.de 30812027Sjungma@eit.uni-kl.de void b_transport(transaction_type& trans, sc_core::sc_time& t) 30912027Sjungma@eit.uni-kl.de { 31012027Sjungma@eit.uni-kl.de if (m_b_transport_ptr) { 31112027Sjungma@eit.uni-kl.de // forward call 31212027Sjungma@eit.uni-kl.de assert(m_mod); 31312027Sjungma@eit.uni-kl.de (m_mod->*m_b_transport_ptr)(trans, t); 31412027Sjungma@eit.uni-kl.de return; 31512027Sjungma@eit.uni-kl.de 31612027Sjungma@eit.uni-kl.de } else if (m_nb_transport_ptr) { 31712027Sjungma@eit.uni-kl.de m_peq.notify(trans, t); 31812027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 31912027Sjungma@eit.uni-kl.de 32012027Sjungma@eit.uni-kl.de mm_end_event_ext mm_ext; 32112027Sjungma@eit.uni-kl.de const bool mm_added = !trans.has_mm(); 32212027Sjungma@eit.uni-kl.de 32312027Sjungma@eit.uni-kl.de if (mm_added) { 32412027Sjungma@eit.uni-kl.de trans.set_mm(this); 32512027Sjungma@eit.uni-kl.de trans.set_auto_extension(&mm_ext); 32612027Sjungma@eit.uni-kl.de trans.acquire(); 32712027Sjungma@eit.uni-kl.de } 32812027Sjungma@eit.uni-kl.de 32912027Sjungma@eit.uni-kl.de // wait until transaction is finished 33012027Sjungma@eit.uni-kl.de sc_core::sc_event end_event; 33112027Sjungma@eit.uni-kl.de m_owner->m_pending_trans[&trans] = &end_event; 33212027Sjungma@eit.uni-kl.de sc_core::wait(end_event); 33312027Sjungma@eit.uni-kl.de 33412027Sjungma@eit.uni-kl.de if (mm_added) { 33512027Sjungma@eit.uni-kl.de // release will not delete the transaction, it will notify mm_ext.done 33612027Sjungma@eit.uni-kl.de trans.release(); 33712027Sjungma@eit.uni-kl.de if (trans.get_ref_count()) { 33812027Sjungma@eit.uni-kl.de sc_core::wait(mm_ext.done); 33912027Sjungma@eit.uni-kl.de } 34012027Sjungma@eit.uni-kl.de trans.set_mm(0); 34112027Sjungma@eit.uni-kl.de } 34212027Sjungma@eit.uni-kl.de 34312027Sjungma@eit.uni-kl.de } else { 34412027Sjungma@eit.uni-kl.de std::stringstream s; 34512027Sjungma@eit.uni-kl.de s << m_name << ": no blocking transport callback registered"; 34612027Sjungma@eit.uni-kl.de SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 34712027Sjungma@eit.uni-kl.de } 34812027Sjungma@eit.uni-kl.de } 34912027Sjungma@eit.uni-kl.de 35012027Sjungma@eit.uni-kl.de unsigned int transport_dbg(transaction_type& trans) 35112027Sjungma@eit.uni-kl.de { 35212027Sjungma@eit.uni-kl.de if (m_transport_dbg_ptr) { 35312027Sjungma@eit.uni-kl.de // forward call 35412027Sjungma@eit.uni-kl.de assert(m_mod); 35512027Sjungma@eit.uni-kl.de return (m_mod->*m_transport_dbg_ptr)(trans); 35612027Sjungma@eit.uni-kl.de 35712027Sjungma@eit.uni-kl.de } else { 35812027Sjungma@eit.uni-kl.de // No debug support 35912027Sjungma@eit.uni-kl.de return 0; 36012027Sjungma@eit.uni-kl.de } 36112027Sjungma@eit.uni-kl.de } 36212027Sjungma@eit.uni-kl.de 36312027Sjungma@eit.uni-kl.de bool get_direct_mem_ptr(transaction_type& trans, 36412027Sjungma@eit.uni-kl.de tlm::tlm_dmi& dmi_data) 36512027Sjungma@eit.uni-kl.de { 36612027Sjungma@eit.uni-kl.de if (m_get_direct_mem_ptr) { 36712027Sjungma@eit.uni-kl.de // forward call 36812027Sjungma@eit.uni-kl.de assert(m_mod); 36912027Sjungma@eit.uni-kl.de return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data); 37012027Sjungma@eit.uni-kl.de 37112027Sjungma@eit.uni-kl.de } else { 37212027Sjungma@eit.uni-kl.de // No DMI support 37312027Sjungma@eit.uni-kl.de dmi_data.allow_read_write(); 37412027Sjungma@eit.uni-kl.de dmi_data.set_start_address(0x0); 37512027Sjungma@eit.uni-kl.de dmi_data.set_end_address((sc_dt::uint64)-1); 37612027Sjungma@eit.uni-kl.de return false; 37712027Sjungma@eit.uni-kl.de } 37812027Sjungma@eit.uni-kl.de } 37912027Sjungma@eit.uni-kl.de 38012027Sjungma@eit.uni-kl.de private: 38112027Sjungma@eit.uni-kl.de 38212027Sjungma@eit.uni-kl.de// dynamic process handler for nb2b conversion 38312027Sjungma@eit.uni-kl.de 38412027Sjungma@eit.uni-kl.de class process_handle_class { 38512027Sjungma@eit.uni-kl.de public: 38612027Sjungma@eit.uni-kl.de explicit process_handle_class(transaction_type * trans) 38712027Sjungma@eit.uni-kl.de : m_trans(trans),m_suspend(false) {} 38812027Sjungma@eit.uni-kl.de 38912027Sjungma@eit.uni-kl.de transaction_type* m_trans; 39012027Sjungma@eit.uni-kl.de sc_core::sc_event m_e; 39112027Sjungma@eit.uni-kl.de bool m_suspend; 39212027Sjungma@eit.uni-kl.de }; 39312027Sjungma@eit.uni-kl.de 39412027Sjungma@eit.uni-kl.de class process_handle_list { 39512027Sjungma@eit.uni-kl.de public: 39612027Sjungma@eit.uni-kl.de process_handle_list() {} 39712027Sjungma@eit.uni-kl.de 39812027Sjungma@eit.uni-kl.de ~process_handle_list() { 39912027Sjungma@eit.uni-kl.de for( typename std::vector<process_handle_class*>::iterator 40012027Sjungma@eit.uni-kl.de it=v.begin(), end = v.end(); it != end; ++it ) 40112027Sjungma@eit.uni-kl.de delete *it; 40212027Sjungma@eit.uni-kl.de } 40312027Sjungma@eit.uni-kl.de 40412027Sjungma@eit.uni-kl.de process_handle_class* get_handle(transaction_type *trans) 40512027Sjungma@eit.uni-kl.de { 40612027Sjungma@eit.uni-kl.de typename std::vector<process_handle_class*>::iterator it; 40712027Sjungma@eit.uni-kl.de 40812027Sjungma@eit.uni-kl.de for(it = v.begin(); it != v.end(); it++) { 40912027Sjungma@eit.uni-kl.de if ((*it)->m_suspend) { // found suspended dynamic process, re-use it 41012027Sjungma@eit.uni-kl.de (*it)->m_trans = trans; // replace to new one 41112027Sjungma@eit.uni-kl.de (*it)->m_suspend = false; 41212027Sjungma@eit.uni-kl.de return *it; 41312027Sjungma@eit.uni-kl.de } 41412027Sjungma@eit.uni-kl.de } 41512027Sjungma@eit.uni-kl.de return NULL; // no suspended process 41612027Sjungma@eit.uni-kl.de } 41712027Sjungma@eit.uni-kl.de 41812027Sjungma@eit.uni-kl.de void put_handle(process_handle_class* ph) 41912027Sjungma@eit.uni-kl.de { 42012027Sjungma@eit.uni-kl.de v.push_back(ph); 42112027Sjungma@eit.uni-kl.de } 42212027Sjungma@eit.uni-kl.de 42312027Sjungma@eit.uni-kl.de private: 42412027Sjungma@eit.uni-kl.de std::vector<process_handle_class*> v; 42512027Sjungma@eit.uni-kl.de }; 42612027Sjungma@eit.uni-kl.de 42712027Sjungma@eit.uni-kl.de process_handle_list m_process_handle; 42812027Sjungma@eit.uni-kl.de 42912027Sjungma@eit.uni-kl.de 43012027Sjungma@eit.uni-kl.de void nb2b_thread(process_handle_class* h) 43112027Sjungma@eit.uni-kl.de { 43212027Sjungma@eit.uni-kl.de 43312027Sjungma@eit.uni-kl.de while(1) { 43412027Sjungma@eit.uni-kl.de transaction_type *trans = h->m_trans; 43512027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 43612027Sjungma@eit.uni-kl.de 43712027Sjungma@eit.uni-kl.de // forward call 43812027Sjungma@eit.uni-kl.de assert(m_mod); 43912027Sjungma@eit.uni-kl.de (m_mod->*m_b_transport_ptr)(*trans, t); 44012027Sjungma@eit.uni-kl.de 44112027Sjungma@eit.uni-kl.de sc_core::wait(t); 44212027Sjungma@eit.uni-kl.de 44312027Sjungma@eit.uni-kl.de // return path 44412027Sjungma@eit.uni-kl.de while (m_response_in_progress) { 44512027Sjungma@eit.uni-kl.de sc_core::wait(m_end_response); 44612027Sjungma@eit.uni-kl.de } 44712027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 44812027Sjungma@eit.uni-kl.de phase_type phase = tlm::BEGIN_RESP; 44912027Sjungma@eit.uni-kl.de sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t); 45012027Sjungma@eit.uni-kl.de if ( !(sync == tlm::TLM_COMPLETED || 45112027Sjungma@eit.uni-kl.de (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) { 45212027Sjungma@eit.uni-kl.de m_response_in_progress = true; 45312027Sjungma@eit.uni-kl.de } 45412027Sjungma@eit.uni-kl.de 45512027Sjungma@eit.uni-kl.de // suspend until next transaction 45612027Sjungma@eit.uni-kl.de h->m_suspend = true; 45712027Sjungma@eit.uni-kl.de sc_core::wait(); 45812027Sjungma@eit.uni-kl.de } 45912027Sjungma@eit.uni-kl.de } 46012027Sjungma@eit.uni-kl.de 46112027Sjungma@eit.uni-kl.de void b2nb_thread() 46212027Sjungma@eit.uni-kl.de { 46312027Sjungma@eit.uni-kl.de while (true) { 46412027Sjungma@eit.uni-kl.de sc_core::wait(m_peq.get_event()); 46512027Sjungma@eit.uni-kl.de 46612027Sjungma@eit.uni-kl.de transaction_type* trans; 46712027Sjungma@eit.uni-kl.de while ((trans = m_peq.get_next_transaction())!=0) { 46812027Sjungma@eit.uni-kl.de assert(m_mod); 46912027Sjungma@eit.uni-kl.de assert(m_nb_transport_ptr); 47012027Sjungma@eit.uni-kl.de phase_type phase = tlm::BEGIN_REQ; 47112027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 47212027Sjungma@eit.uni-kl.de 47312027Sjungma@eit.uni-kl.de switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) { 47412027Sjungma@eit.uni-kl.de case tlm::TLM_COMPLETED: 47512027Sjungma@eit.uni-kl.de { 47612027Sjungma@eit.uni-kl.de // notify transaction is finished 47712027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it = 47812027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.find(trans); 47912027Sjungma@eit.uni-kl.de assert(it != m_owner->m_pending_trans.end()); 48012027Sjungma@eit.uni-kl.de it->second->notify(t); 48112027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 48212027Sjungma@eit.uni-kl.de break; 48312027Sjungma@eit.uni-kl.de } 48412027Sjungma@eit.uni-kl.de 48512027Sjungma@eit.uni-kl.de case tlm::TLM_ACCEPTED: 48612027Sjungma@eit.uni-kl.de case tlm::TLM_UPDATED: 48712027Sjungma@eit.uni-kl.de switch (phase) { 48812027Sjungma@eit.uni-kl.de case tlm::BEGIN_REQ: 48912027Sjungma@eit.uni-kl.de m_owner->m_current_transaction = trans; 49012027Sjungma@eit.uni-kl.de sc_core::wait(m_owner->m_end_request); 49112027Sjungma@eit.uni-kl.de m_owner->m_current_transaction = 0; 49212027Sjungma@eit.uni-kl.de break; 49312027Sjungma@eit.uni-kl.de 49412027Sjungma@eit.uni-kl.de case tlm::END_REQ: 49512027Sjungma@eit.uni-kl.de sc_core::wait(t); 49612027Sjungma@eit.uni-kl.de break; 49712027Sjungma@eit.uni-kl.de 49812027Sjungma@eit.uni-kl.de case tlm::BEGIN_RESP: 49912027Sjungma@eit.uni-kl.de { 50012027Sjungma@eit.uni-kl.de phase = tlm::END_RESP; 50112027Sjungma@eit.uni-kl.de sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2 50212027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 50312027Sjungma@eit.uni-kl.de (m_mod->*m_nb_transport_ptr)(*trans, phase, t); 50412027Sjungma@eit.uni-kl.de 50512027Sjungma@eit.uni-kl.de // notify transaction is finished 50612027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it = 50712027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.find(trans); 50812027Sjungma@eit.uni-kl.de assert(it != m_owner->m_pending_trans.end()); 50912027Sjungma@eit.uni-kl.de it->second->notify(t); 51012027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 51112027Sjungma@eit.uni-kl.de break; 51212027Sjungma@eit.uni-kl.de } 51312027Sjungma@eit.uni-kl.de 51412027Sjungma@eit.uni-kl.de default: 51512027Sjungma@eit.uni-kl.de assert(0); exit(1); 51612027Sjungma@eit.uni-kl.de }; 51712027Sjungma@eit.uni-kl.de break; 51812027Sjungma@eit.uni-kl.de 51912027Sjungma@eit.uni-kl.de default: 52012027Sjungma@eit.uni-kl.de assert(0); exit(1); 52112027Sjungma@eit.uni-kl.de }; 52212027Sjungma@eit.uni-kl.de } 52312027Sjungma@eit.uni-kl.de } 52412027Sjungma@eit.uni-kl.de } 52512027Sjungma@eit.uni-kl.de 52612027Sjungma@eit.uni-kl.de void free(tlm::tlm_generic_payload* trans) 52712027Sjungma@eit.uni-kl.de { 52812027Sjungma@eit.uni-kl.de mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>(); 52912027Sjungma@eit.uni-kl.de assert(ext); 53012027Sjungma@eit.uni-kl.de // notif event first before freeing extensions (reset) 53112027Sjungma@eit.uni-kl.de ext->done.notify(); 53212027Sjungma@eit.uni-kl.de trans->reset(); 53312027Sjungma@eit.uni-kl.de } 53412027Sjungma@eit.uni-kl.de 53512027Sjungma@eit.uni-kl.de private: 53612027Sjungma@eit.uni-kl.de struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 53712027Sjungma@eit.uni-kl.de { 53812027Sjungma@eit.uni-kl.de tlm::tlm_extension_base* clone() const { return NULL; } 53912027Sjungma@eit.uni-kl.de void free() {} 54012027Sjungma@eit.uni-kl.de void copy_from(tlm::tlm_extension_base const &) {} 54112027Sjungma@eit.uni-kl.de sc_core::sc_event done; 54212027Sjungma@eit.uni-kl.de }; 54312027Sjungma@eit.uni-kl.de 54412027Sjungma@eit.uni-kl.de private: 54512027Sjungma@eit.uni-kl.de const std::string m_name; 54612027Sjungma@eit.uni-kl.de simple_target_socket *m_owner; 54712027Sjungma@eit.uni-kl.de MODULE* m_mod; 54812027Sjungma@eit.uni-kl.de NBTransportPtr m_nb_transport_ptr; 54912027Sjungma@eit.uni-kl.de BTransportPtr m_b_transport_ptr; 55012027Sjungma@eit.uni-kl.de TransportDbgPtr m_transport_dbg_ptr; 55112027Sjungma@eit.uni-kl.de GetDirectMemPtr m_get_direct_mem_ptr; 55212027Sjungma@eit.uni-kl.de peq_with_get<transaction_type> m_peq; 55312027Sjungma@eit.uni-kl.de bool m_response_in_progress; 55412027Sjungma@eit.uni-kl.de sc_core::sc_event m_end_response; 55512027Sjungma@eit.uni-kl.de }; 55612027Sjungma@eit.uni-kl.de 55712027Sjungma@eit.uni-kl.deprivate: 55812027Sjungma@eit.uni-kl.de fw_process m_fw_process; 55912027Sjungma@eit.uni-kl.de bw_process m_bw_process; 56012027Sjungma@eit.uni-kl.de std::map<transaction_type*, sc_core::sc_event *> m_pending_trans; 56112027Sjungma@eit.uni-kl.de sc_core::sc_event m_end_request; 56212027Sjungma@eit.uni-kl.de transaction_type* m_current_transaction; 56312027Sjungma@eit.uni-kl.de}; 56412027Sjungma@eit.uni-kl.de 56512027Sjungma@eit.uni-kl.de//ID Tagged version 56612027Sjungma@eit.uni-kl.detemplate <typename MODULE, 56712027Sjungma@eit.uni-kl.de unsigned int BUSWIDTH = 32, 56812027Sjungma@eit.uni-kl.de typename TYPES = tlm::tlm_base_protocol_types> 56912027Sjungma@eit.uni-kl.declass simple_target_socket_tagged : 57012027Sjungma@eit.uni-kl.de public tlm::tlm_target_socket<BUSWIDTH, TYPES> 57112027Sjungma@eit.uni-kl.de{ 57212027Sjungma@eit.uni-kl.de friend class fw_process; 57312027Sjungma@eit.uni-kl.de friend class bw_process; 57412027Sjungma@eit.uni-kl.depublic: 57512027Sjungma@eit.uni-kl.de typedef typename TYPES::tlm_payload_type transaction_type; 57612027Sjungma@eit.uni-kl.de typedef typename TYPES::tlm_phase_type phase_type; 57712027Sjungma@eit.uni-kl.de typedef tlm::tlm_sync_enum sync_enum_type; 57812027Sjungma@eit.uni-kl.de typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 57912027Sjungma@eit.uni-kl.de typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 58012027Sjungma@eit.uni-kl.de typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type; 58112027Sjungma@eit.uni-kl.de 58212027Sjungma@eit.uni-kl.depublic: 58312027Sjungma@eit.uni-kl.de simple_target_socket_tagged() : 58412027Sjungma@eit.uni-kl.de base_type(sc_core::sc_gen_unique_name("simple_target_socket_tagged")), 58512027Sjungma@eit.uni-kl.de m_fw_process(this), 58612027Sjungma@eit.uni-kl.de m_bw_process(this) 58712027Sjungma@eit.uni-kl.de { 58812027Sjungma@eit.uni-kl.de bind(m_fw_process); 58912027Sjungma@eit.uni-kl.de } 59012027Sjungma@eit.uni-kl.de 59112027Sjungma@eit.uni-kl.de explicit simple_target_socket_tagged(const char* n) : 59212027Sjungma@eit.uni-kl.de base_type(n), 59312027Sjungma@eit.uni-kl.de m_fw_process(this), 59412027Sjungma@eit.uni-kl.de m_bw_process(this) 59512027Sjungma@eit.uni-kl.de { 59612027Sjungma@eit.uni-kl.de bind(m_fw_process); 59712027Sjungma@eit.uni-kl.de } 59812027Sjungma@eit.uni-kl.de 59912027Sjungma@eit.uni-kl.de using tlm::tlm_target_socket<BUSWIDTH, TYPES>::bind; 60012027Sjungma@eit.uni-kl.de 60112027Sjungma@eit.uni-kl.de // bw transport must come thru us. 60212027Sjungma@eit.uni-kl.de tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;} 60312027Sjungma@eit.uni-kl.de 60412027Sjungma@eit.uni-kl.de // REGISTER_XXX 60512027Sjungma@eit.uni-kl.de void register_nb_transport_fw(MODULE* mod, 60612027Sjungma@eit.uni-kl.de sync_enum_type (MODULE::*cb)(int id, 60712027Sjungma@eit.uni-kl.de transaction_type&, 60812027Sjungma@eit.uni-kl.de phase_type&, 60912027Sjungma@eit.uni-kl.de sc_core::sc_time&), 61012027Sjungma@eit.uni-kl.de int id) 61112027Sjungma@eit.uni-kl.de { 61212027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 61312027Sjungma@eit.uni-kl.de m_fw_process.set_nb_transport_ptr(mod, cb); 61412027Sjungma@eit.uni-kl.de m_fw_process.set_nb_transport_user_id(id); 61512027Sjungma@eit.uni-kl.de } 61612027Sjungma@eit.uni-kl.de 61712027Sjungma@eit.uni-kl.de void register_b_transport(MODULE* mod, 61812027Sjungma@eit.uni-kl.de void (MODULE::*cb)(int id, 61912027Sjungma@eit.uni-kl.de transaction_type&, 62012027Sjungma@eit.uni-kl.de sc_core::sc_time&), 62112027Sjungma@eit.uni-kl.de int id) 62212027Sjungma@eit.uni-kl.de { 62312027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 62412027Sjungma@eit.uni-kl.de m_fw_process.set_b_transport_ptr(mod, cb); 62512027Sjungma@eit.uni-kl.de m_fw_process.set_b_transport_user_id(id); 62612027Sjungma@eit.uni-kl.de } 62712027Sjungma@eit.uni-kl.de 62812027Sjungma@eit.uni-kl.de void register_transport_dbg(MODULE* mod, 62912027Sjungma@eit.uni-kl.de unsigned int (MODULE::*cb)(int id, 63012027Sjungma@eit.uni-kl.de transaction_type&), 63112027Sjungma@eit.uni-kl.de int id) 63212027Sjungma@eit.uni-kl.de { 63312027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 63412027Sjungma@eit.uni-kl.de m_fw_process.set_transport_dbg_ptr(mod, cb); 63512027Sjungma@eit.uni-kl.de m_fw_process.set_transport_dbg_user_id(id); 63612027Sjungma@eit.uni-kl.de } 63712027Sjungma@eit.uni-kl.de 63812027Sjungma@eit.uni-kl.de void register_get_direct_mem_ptr(MODULE* mod, 63912027Sjungma@eit.uni-kl.de bool (MODULE::*cb)(int id, 64012027Sjungma@eit.uni-kl.de transaction_type&, 64112027Sjungma@eit.uni-kl.de tlm::tlm_dmi&), 64212027Sjungma@eit.uni-kl.de int id) 64312027Sjungma@eit.uni-kl.de { 64412027Sjungma@eit.uni-kl.de assert(!sc_core::sc_get_curr_simcontext()->elaboration_done()); 64512027Sjungma@eit.uni-kl.de m_fw_process.set_get_direct_mem_ptr(mod, cb); 64612027Sjungma@eit.uni-kl.de m_fw_process.set_get_dmi_user_id(id); 64712027Sjungma@eit.uni-kl.de } 64812027Sjungma@eit.uni-kl.de 64912027Sjungma@eit.uni-kl.deprivate: 65012027Sjungma@eit.uni-kl.de //make call on bw path. 65112027Sjungma@eit.uni-kl.de sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t) 65212027Sjungma@eit.uni-kl.de { 65312027Sjungma@eit.uni-kl.de return base_type::operator ->()->nb_transport_bw(trans, phase, t); 65412027Sjungma@eit.uni-kl.de } 65512027Sjungma@eit.uni-kl.de 65612027Sjungma@eit.uni-kl.de void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e) 65712027Sjungma@eit.uni-kl.de { 65812027Sjungma@eit.uni-kl.de base_type::operator ->()->invalidate_direct_mem_ptr(s, e); 65912027Sjungma@eit.uni-kl.de } 66012027Sjungma@eit.uni-kl.de 66112027Sjungma@eit.uni-kl.de //Helper class to handle bw path calls 66212027Sjungma@eit.uni-kl.de // Needed to detect transaction end when called from b_transport. 66312027Sjungma@eit.uni-kl.de class bw_process : public tlm::tlm_bw_transport_if<TYPES> 66412027Sjungma@eit.uni-kl.de { 66512027Sjungma@eit.uni-kl.de public: 66612027Sjungma@eit.uni-kl.de bw_process(simple_target_socket_tagged *p_own) : m_owner(p_own) 66712027Sjungma@eit.uni-kl.de { 66812027Sjungma@eit.uni-kl.de } 66912027Sjungma@eit.uni-kl.de 67012027Sjungma@eit.uni-kl.de sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t) 67112027Sjungma@eit.uni-kl.de { 67212027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it; 67312027Sjungma@eit.uni-kl.de 67412027Sjungma@eit.uni-kl.de it = m_owner->m_pending_trans.find(&trans); 67512027Sjungma@eit.uni-kl.de if(it == m_owner->m_pending_trans.end()) { 67612027Sjungma@eit.uni-kl.de // Not a blocking call, forward. 67712027Sjungma@eit.uni-kl.de return m_owner->bw_nb_transport(trans, phase, t); 67812027Sjungma@eit.uni-kl.de 67912027Sjungma@eit.uni-kl.de } else { 68012027Sjungma@eit.uni-kl.de if (phase == tlm::END_REQ) { 68112027Sjungma@eit.uni-kl.de m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 68212027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; 68312027Sjungma@eit.uni-kl.de 68412027Sjungma@eit.uni-kl.de } else if (phase == tlm::BEGIN_RESP) { 68512027Sjungma@eit.uni-kl.de if (m_owner->m_current_transaction == &trans) { 68612027Sjungma@eit.uni-kl.de m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME); 68712027Sjungma@eit.uni-kl.de } 68812027Sjungma@eit.uni-kl.de //TODO: add response-accept delay? 68912027Sjungma@eit.uni-kl.de it->second->notify(t); 69012027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 69112027Sjungma@eit.uni-kl.de return tlm::TLM_COMPLETED; 69212027Sjungma@eit.uni-kl.de 69312027Sjungma@eit.uni-kl.de } else { 69412027Sjungma@eit.uni-kl.de assert(0); exit(1); 69512027Sjungma@eit.uni-kl.de } 69612027Sjungma@eit.uni-kl.de 69712027Sjungma@eit.uni-kl.de// return tlm::TLM_COMPLETED; //Should not reach here 69812027Sjungma@eit.uni-kl.de } 69912027Sjungma@eit.uni-kl.de } 70012027Sjungma@eit.uni-kl.de 70112027Sjungma@eit.uni-kl.de void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e) 70212027Sjungma@eit.uni-kl.de { 70312027Sjungma@eit.uni-kl.de return m_owner->bw_invalidate_direct_mem_ptr(s, e); 70412027Sjungma@eit.uni-kl.de } 70512027Sjungma@eit.uni-kl.de 70612027Sjungma@eit.uni-kl.de private: 70712027Sjungma@eit.uni-kl.de simple_target_socket_tagged *m_owner; 70812027Sjungma@eit.uni-kl.de }; 70912027Sjungma@eit.uni-kl.de 71012027Sjungma@eit.uni-kl.de class fw_process : public tlm::tlm_fw_transport_if<TYPES>, 71112027Sjungma@eit.uni-kl.de public tlm::tlm_mm_interface 71212027Sjungma@eit.uni-kl.de { 71312027Sjungma@eit.uni-kl.de public: 71412027Sjungma@eit.uni-kl.de typedef sync_enum_type (MODULE::*NBTransportPtr)(int id, 71512027Sjungma@eit.uni-kl.de transaction_type&, 71612027Sjungma@eit.uni-kl.de phase_type&, 71712027Sjungma@eit.uni-kl.de sc_core::sc_time&); 71812027Sjungma@eit.uni-kl.de typedef void (MODULE::*BTransportPtr)(int id, 71912027Sjungma@eit.uni-kl.de transaction_type&, 72012027Sjungma@eit.uni-kl.de sc_core::sc_time&); 72112027Sjungma@eit.uni-kl.de typedef unsigned int (MODULE::*TransportDbgPtr)(int id, 72212027Sjungma@eit.uni-kl.de transaction_type&); 72312027Sjungma@eit.uni-kl.de typedef bool (MODULE::*GetDirectMemPtr)(int id, 72412027Sjungma@eit.uni-kl.de transaction_type&, 72512027Sjungma@eit.uni-kl.de tlm::tlm_dmi&); 72612027Sjungma@eit.uni-kl.de 72712027Sjungma@eit.uni-kl.de fw_process(simple_target_socket_tagged *p_own) : 72812027Sjungma@eit.uni-kl.de m_name(p_own->name()), 72912027Sjungma@eit.uni-kl.de m_owner(p_own), 73012027Sjungma@eit.uni-kl.de m_mod(0), 73112027Sjungma@eit.uni-kl.de m_nb_transport_ptr(0), 73212027Sjungma@eit.uni-kl.de m_b_transport_ptr(0), 73312027Sjungma@eit.uni-kl.de m_transport_dbg_ptr(0), 73412027Sjungma@eit.uni-kl.de m_get_direct_mem_ptr(0), 73512027Sjungma@eit.uni-kl.de m_nb_transport_user_id(0), 73612027Sjungma@eit.uni-kl.de m_b_transport_user_id(0), 73712027Sjungma@eit.uni-kl.de m_transport_dbg_user_id(0), 73812027Sjungma@eit.uni-kl.de m_get_dmi_user_id(0), 73912027Sjungma@eit.uni-kl.de m_peq(sc_core::sc_gen_unique_name("m_peq")), 74012027Sjungma@eit.uni-kl.de m_response_in_progress(false) 74112027Sjungma@eit.uni-kl.de { 74212027Sjungma@eit.uni-kl.de sc_core::sc_spawn_options opts; 74312027Sjungma@eit.uni-kl.de opts.set_sensitivity(&m_peq.get_event()); 74412027Sjungma@eit.uni-kl.de sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this), 74512027Sjungma@eit.uni-kl.de sc_core::sc_gen_unique_name("b2nb_thread"), &opts); 74612027Sjungma@eit.uni-kl.de } 74712027Sjungma@eit.uni-kl.de 74812027Sjungma@eit.uni-kl.de void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; } 74912027Sjungma@eit.uni-kl.de void set_b_transport_user_id(int id) { m_b_transport_user_id = id; } 75012027Sjungma@eit.uni-kl.de void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; } 75112027Sjungma@eit.uni-kl.de void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; } 75212027Sjungma@eit.uni-kl.de 75312027Sjungma@eit.uni-kl.de void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p) 75412027Sjungma@eit.uni-kl.de { 75512027Sjungma@eit.uni-kl.de if (m_nb_transport_ptr) { 75612027Sjungma@eit.uni-kl.de std::stringstream s; 75712027Sjungma@eit.uni-kl.de s << m_name << ": non-blocking callback allready registered"; 75812027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 75912027Sjungma@eit.uni-kl.de } else { 76012027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 76112027Sjungma@eit.uni-kl.de m_mod = mod; 76212027Sjungma@eit.uni-kl.de m_nb_transport_ptr = p; 76312027Sjungma@eit.uni-kl.de } 76412027Sjungma@eit.uni-kl.de } 76512027Sjungma@eit.uni-kl.de 76612027Sjungma@eit.uni-kl.de void set_b_transport_ptr(MODULE* mod, BTransportPtr p) 76712027Sjungma@eit.uni-kl.de { 76812027Sjungma@eit.uni-kl.de if (m_b_transport_ptr) { 76912027Sjungma@eit.uni-kl.de std::stringstream s; 77012027Sjungma@eit.uni-kl.de s << m_name << ": blocking callback allready registered"; 77112027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 77212027Sjungma@eit.uni-kl.de } else { 77312027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 77412027Sjungma@eit.uni-kl.de m_mod = mod; 77512027Sjungma@eit.uni-kl.de m_b_transport_ptr = p; 77612027Sjungma@eit.uni-kl.de } 77712027Sjungma@eit.uni-kl.de } 77812027Sjungma@eit.uni-kl.de 77912027Sjungma@eit.uni-kl.de void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p) 78012027Sjungma@eit.uni-kl.de { 78112027Sjungma@eit.uni-kl.de if (m_transport_dbg_ptr) { 78212027Sjungma@eit.uni-kl.de std::stringstream s; 78312027Sjungma@eit.uni-kl.de s << m_name << ": debug callback allready registered"; 78412027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 78512027Sjungma@eit.uni-kl.de } else { 78612027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 78712027Sjungma@eit.uni-kl.de m_mod = mod; 78812027Sjungma@eit.uni-kl.de m_transport_dbg_ptr = p; 78912027Sjungma@eit.uni-kl.de } 79012027Sjungma@eit.uni-kl.de } 79112027Sjungma@eit.uni-kl.de 79212027Sjungma@eit.uni-kl.de void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p) 79312027Sjungma@eit.uni-kl.de { 79412027Sjungma@eit.uni-kl.de if (m_get_direct_mem_ptr) { 79512027Sjungma@eit.uni-kl.de std::stringstream s; 79612027Sjungma@eit.uni-kl.de s << m_name << ": get DMI pointer callback allready registered"; 79712027Sjungma@eit.uni-kl.de SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 79812027Sjungma@eit.uni-kl.de } else { 79912027Sjungma@eit.uni-kl.de assert(!m_mod || m_mod == mod); 80012027Sjungma@eit.uni-kl.de m_mod = mod; 80112027Sjungma@eit.uni-kl.de m_get_direct_mem_ptr = p; 80212027Sjungma@eit.uni-kl.de } 80312027Sjungma@eit.uni-kl.de } 80412027Sjungma@eit.uni-kl.de// Interface implementation 80512027Sjungma@eit.uni-kl.de sync_enum_type nb_transport_fw(transaction_type& trans, 80612027Sjungma@eit.uni-kl.de phase_type& phase, 80712027Sjungma@eit.uni-kl.de sc_core::sc_time& t) 80812027Sjungma@eit.uni-kl.de { 80912027Sjungma@eit.uni-kl.de if (m_nb_transport_ptr) { 81012027Sjungma@eit.uni-kl.de // forward call 81112027Sjungma@eit.uni-kl.de assert(m_mod); 81212027Sjungma@eit.uni-kl.de return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t); 81312027Sjungma@eit.uni-kl.de 81412027Sjungma@eit.uni-kl.de } else if (m_b_transport_ptr) { 81512027Sjungma@eit.uni-kl.de if (phase == tlm::BEGIN_REQ) { 81612027Sjungma@eit.uni-kl.de 81712027Sjungma@eit.uni-kl.de // prepare thread to do blocking call 81812027Sjungma@eit.uni-kl.de process_handle_class * ph = m_process_handle.get_handle(&trans); 81912027Sjungma@eit.uni-kl.de 82012027Sjungma@eit.uni-kl.de if (!ph) { // create new dynamic process 82112027Sjungma@eit.uni-kl.de ph = new process_handle_class(&trans); 82212027Sjungma@eit.uni-kl.de m_process_handle.put_handle(ph); 82312027Sjungma@eit.uni-kl.de 82412027Sjungma@eit.uni-kl.de sc_core::sc_spawn_options opts; 82512027Sjungma@eit.uni-kl.de opts.dont_initialize(); 82612027Sjungma@eit.uni-kl.de opts.set_sensitivity(&ph->m_e); 82712027Sjungma@eit.uni-kl.de 82812027Sjungma@eit.uni-kl.de sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, ph), 82912027Sjungma@eit.uni-kl.de sc_core::sc_gen_unique_name("nb2b_thread"), &opts); 83012027Sjungma@eit.uni-kl.de } 83112027Sjungma@eit.uni-kl.de 83212027Sjungma@eit.uni-kl.de ph->m_e.notify(t); 83312027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; 83412027Sjungma@eit.uni-kl.de 83512027Sjungma@eit.uni-kl.de } else if (phase == tlm::END_RESP) { 83612027Sjungma@eit.uni-kl.de m_response_in_progress = false; 83712027Sjungma@eit.uni-kl.de m_end_response.notify(t); 83812027Sjungma@eit.uni-kl.de return tlm::TLM_COMPLETED; 83912027Sjungma@eit.uni-kl.de 84012027Sjungma@eit.uni-kl.de } else { 84112027Sjungma@eit.uni-kl.de assert(0); exit(1); 84212027Sjungma@eit.uni-kl.de// return tlm::TLM_COMPLETED; ///< unreachable code 84312027Sjungma@eit.uni-kl.de } 84412027Sjungma@eit.uni-kl.de 84512027Sjungma@eit.uni-kl.de } else { 84612027Sjungma@eit.uni-kl.de std::stringstream s; 84712027Sjungma@eit.uni-kl.de s << m_name << ": no non-blocking transport callback registered"; 84812027Sjungma@eit.uni-kl.de SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 84912027Sjungma@eit.uni-kl.de } 85012027Sjungma@eit.uni-kl.de return tlm::TLM_ACCEPTED; ///< unreachable code 85112027Sjungma@eit.uni-kl.de } 85212027Sjungma@eit.uni-kl.de 85312027Sjungma@eit.uni-kl.de void b_transport(transaction_type& trans, sc_core::sc_time& t) 85412027Sjungma@eit.uni-kl.de { 85512027Sjungma@eit.uni-kl.de if (m_b_transport_ptr) { 85612027Sjungma@eit.uni-kl.de // forward call 85712027Sjungma@eit.uni-kl.de assert(m_mod); 85812027Sjungma@eit.uni-kl.de (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t); 85912027Sjungma@eit.uni-kl.de return; 86012027Sjungma@eit.uni-kl.de 86112027Sjungma@eit.uni-kl.de } else if (m_nb_transport_ptr) { 86212027Sjungma@eit.uni-kl.de m_peq.notify(trans, t); 86312027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 86412027Sjungma@eit.uni-kl.de 86512027Sjungma@eit.uni-kl.de mm_end_event_ext mm_ext; 86612027Sjungma@eit.uni-kl.de const bool mm_added = !trans.has_mm(); 86712027Sjungma@eit.uni-kl.de 86812027Sjungma@eit.uni-kl.de if (mm_added){ 86912027Sjungma@eit.uni-kl.de trans.set_mm(this); 87012027Sjungma@eit.uni-kl.de trans.set_auto_extension(&mm_ext); 87112027Sjungma@eit.uni-kl.de trans.acquire(); 87212027Sjungma@eit.uni-kl.de } 87312027Sjungma@eit.uni-kl.de 87412027Sjungma@eit.uni-kl.de // wait until transaction is finished 87512027Sjungma@eit.uni-kl.de sc_core::sc_event end_event; 87612027Sjungma@eit.uni-kl.de m_owner->m_pending_trans[&trans] = &end_event; 87712027Sjungma@eit.uni-kl.de sc_core::wait(end_event); 87812027Sjungma@eit.uni-kl.de 87912027Sjungma@eit.uni-kl.de if (mm_added) { 88012027Sjungma@eit.uni-kl.de // release will not delete the transaction, it will notify mm_ext.done 88112027Sjungma@eit.uni-kl.de trans.release(); 88212027Sjungma@eit.uni-kl.de if (trans.get_ref_count()) { 88312027Sjungma@eit.uni-kl.de sc_core::wait(mm_ext.done); 88412027Sjungma@eit.uni-kl.de } 88512027Sjungma@eit.uni-kl.de trans.set_mm(0); 88612027Sjungma@eit.uni-kl.de } 88712027Sjungma@eit.uni-kl.de 88812027Sjungma@eit.uni-kl.de } else { 88912027Sjungma@eit.uni-kl.de std::stringstream s; 89012027Sjungma@eit.uni-kl.de s << m_name << ": no transport callback registered"; 89112027Sjungma@eit.uni-kl.de SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 89212027Sjungma@eit.uni-kl.de } 89312027Sjungma@eit.uni-kl.de } 89412027Sjungma@eit.uni-kl.de 89512027Sjungma@eit.uni-kl.de unsigned int transport_dbg(transaction_type& trans) 89612027Sjungma@eit.uni-kl.de { 89712027Sjungma@eit.uni-kl.de if (m_transport_dbg_ptr) { 89812027Sjungma@eit.uni-kl.de // forward call 89912027Sjungma@eit.uni-kl.de assert(m_mod); 90012027Sjungma@eit.uni-kl.de return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans); 90112027Sjungma@eit.uni-kl.de 90212027Sjungma@eit.uni-kl.de } else { 90312027Sjungma@eit.uni-kl.de // No debug support 90412027Sjungma@eit.uni-kl.de return 0; 90512027Sjungma@eit.uni-kl.de } 90612027Sjungma@eit.uni-kl.de } 90712027Sjungma@eit.uni-kl.de 90812027Sjungma@eit.uni-kl.de bool get_direct_mem_ptr(transaction_type& trans, 90912027Sjungma@eit.uni-kl.de tlm::tlm_dmi& dmi_data) 91012027Sjungma@eit.uni-kl.de { 91112027Sjungma@eit.uni-kl.de if (m_get_direct_mem_ptr) { 91212027Sjungma@eit.uni-kl.de // forward call 91312027Sjungma@eit.uni-kl.de assert(m_mod); 91412027Sjungma@eit.uni-kl.de return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data); 91512027Sjungma@eit.uni-kl.de 91612027Sjungma@eit.uni-kl.de } else { 91712027Sjungma@eit.uni-kl.de // No DMI support 91812027Sjungma@eit.uni-kl.de dmi_data.allow_read_write(); 91912027Sjungma@eit.uni-kl.de dmi_data.set_start_address(0x0); 92012027Sjungma@eit.uni-kl.de dmi_data.set_end_address((sc_dt::uint64)-1); 92112027Sjungma@eit.uni-kl.de return false; 92212027Sjungma@eit.uni-kl.de } 92312027Sjungma@eit.uni-kl.de } 92412027Sjungma@eit.uni-kl.de 92512027Sjungma@eit.uni-kl.de private: 92612027Sjungma@eit.uni-kl.de// dynamic process handler for nb2b conversion 92712027Sjungma@eit.uni-kl.de 92812027Sjungma@eit.uni-kl.de class process_handle_class { 92912027Sjungma@eit.uni-kl.de public: 93012027Sjungma@eit.uni-kl.de explicit process_handle_class(transaction_type * trans) 93112027Sjungma@eit.uni-kl.de : m_trans(trans),m_suspend(false){} 93212027Sjungma@eit.uni-kl.de 93312027Sjungma@eit.uni-kl.de transaction_type* m_trans; 93412027Sjungma@eit.uni-kl.de sc_core::sc_event m_e; 93512027Sjungma@eit.uni-kl.de bool m_suspend; 93612027Sjungma@eit.uni-kl.de }; 93712027Sjungma@eit.uni-kl.de 93812027Sjungma@eit.uni-kl.de class process_handle_list { 93912027Sjungma@eit.uni-kl.de public: 94012027Sjungma@eit.uni-kl.de process_handle_list() {} 94112027Sjungma@eit.uni-kl.de 94212027Sjungma@eit.uni-kl.de ~process_handle_list() { 94312027Sjungma@eit.uni-kl.de for( typename std::vector<process_handle_class*>::iterator 94412027Sjungma@eit.uni-kl.de it=v.begin(), end = v.end(); it != end; ++it ) 94512027Sjungma@eit.uni-kl.de delete *it; 94612027Sjungma@eit.uni-kl.de } 94712027Sjungma@eit.uni-kl.de 94812027Sjungma@eit.uni-kl.de process_handle_class* get_handle(transaction_type *trans) 94912027Sjungma@eit.uni-kl.de { 95012027Sjungma@eit.uni-kl.de typename std::vector<process_handle_class*>::iterator it; 95112027Sjungma@eit.uni-kl.de 95212027Sjungma@eit.uni-kl.de for(it = v.begin(); it != v.end(); it++) { 95312027Sjungma@eit.uni-kl.de if ((*it)->m_suspend) { // found suspended dynamic process, re-use it 95412027Sjungma@eit.uni-kl.de (*it)->m_trans = trans; // replace to new one 95512027Sjungma@eit.uni-kl.de (*it)->m_suspend = false; 95612027Sjungma@eit.uni-kl.de return *it; 95712027Sjungma@eit.uni-kl.de } 95812027Sjungma@eit.uni-kl.de } 95912027Sjungma@eit.uni-kl.de return NULL; // no suspended process 96012027Sjungma@eit.uni-kl.de } 96112027Sjungma@eit.uni-kl.de 96212027Sjungma@eit.uni-kl.de void put_handle(process_handle_class* ph) 96312027Sjungma@eit.uni-kl.de { 96412027Sjungma@eit.uni-kl.de v.push_back(ph); 96512027Sjungma@eit.uni-kl.de } 96612027Sjungma@eit.uni-kl.de 96712027Sjungma@eit.uni-kl.de private: 96812027Sjungma@eit.uni-kl.de std::vector<process_handle_class*> v; 96912027Sjungma@eit.uni-kl.de }; 97012027Sjungma@eit.uni-kl.de 97112027Sjungma@eit.uni-kl.de process_handle_list m_process_handle; 97212027Sjungma@eit.uni-kl.de 97312027Sjungma@eit.uni-kl.de void nb2b_thread(process_handle_class* h) 97412027Sjungma@eit.uni-kl.de { 97512027Sjungma@eit.uni-kl.de 97612027Sjungma@eit.uni-kl.de while(1) { 97712027Sjungma@eit.uni-kl.de transaction_type * trans = h->m_trans; 97812027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 97912027Sjungma@eit.uni-kl.de 98012027Sjungma@eit.uni-kl.de // forward call 98112027Sjungma@eit.uni-kl.de assert(m_mod); 98212027Sjungma@eit.uni-kl.de (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t); 98312027Sjungma@eit.uni-kl.de 98412027Sjungma@eit.uni-kl.de sc_core::wait(t); 98512027Sjungma@eit.uni-kl.de 98612027Sjungma@eit.uni-kl.de // return path 98712027Sjungma@eit.uni-kl.de while (m_response_in_progress) { 98812027Sjungma@eit.uni-kl.de sc_core::wait(m_end_response); 98912027Sjungma@eit.uni-kl.de } 99012027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 99112027Sjungma@eit.uni-kl.de phase_type phase = tlm::BEGIN_RESP; 99212027Sjungma@eit.uni-kl.de sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t); 99312027Sjungma@eit.uni-kl.de if ( !(sync == tlm::TLM_COMPLETED || 99412027Sjungma@eit.uni-kl.de (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) { 99512027Sjungma@eit.uni-kl.de m_response_in_progress = true; 99612027Sjungma@eit.uni-kl.de } 99712027Sjungma@eit.uni-kl.de 99812027Sjungma@eit.uni-kl.de // suspend until next transaction 99912027Sjungma@eit.uni-kl.de h->m_suspend = true; 100012027Sjungma@eit.uni-kl.de sc_core::wait(); 100112027Sjungma@eit.uni-kl.de } 100212027Sjungma@eit.uni-kl.de } 100312027Sjungma@eit.uni-kl.de 100412027Sjungma@eit.uni-kl.de void b2nb_thread() 100512027Sjungma@eit.uni-kl.de { 100612027Sjungma@eit.uni-kl.de while (true) { 100712027Sjungma@eit.uni-kl.de sc_core::wait(m_peq.get_event()); 100812027Sjungma@eit.uni-kl.de 100912027Sjungma@eit.uni-kl.de transaction_type* trans; 101012027Sjungma@eit.uni-kl.de while ((trans = m_peq.get_next_transaction())!=0) { 101112027Sjungma@eit.uni-kl.de assert(m_mod); 101212027Sjungma@eit.uni-kl.de assert(m_nb_transport_ptr); 101312027Sjungma@eit.uni-kl.de phase_type phase = tlm::BEGIN_REQ; 101412027Sjungma@eit.uni-kl.de sc_core::sc_time t = sc_core::SC_ZERO_TIME; 101512027Sjungma@eit.uni-kl.de 101612027Sjungma@eit.uni-kl.de switch ((m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t)) { 101712027Sjungma@eit.uni-kl.de case tlm::TLM_COMPLETED: 101812027Sjungma@eit.uni-kl.de { 101912027Sjungma@eit.uni-kl.de // notify transaction is finished 102012027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it = 102112027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.find(trans); 102212027Sjungma@eit.uni-kl.de assert(it != m_owner->m_pending_trans.end()); 102312027Sjungma@eit.uni-kl.de it->second->notify(t); 102412027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 102512027Sjungma@eit.uni-kl.de break; 102612027Sjungma@eit.uni-kl.de } 102712027Sjungma@eit.uni-kl.de 102812027Sjungma@eit.uni-kl.de case tlm::TLM_ACCEPTED: 102912027Sjungma@eit.uni-kl.de case tlm::TLM_UPDATED: 103012027Sjungma@eit.uni-kl.de switch (phase) { 103112027Sjungma@eit.uni-kl.de case tlm::BEGIN_REQ: 103212027Sjungma@eit.uni-kl.de m_owner->m_current_transaction = trans; 103312027Sjungma@eit.uni-kl.de sc_core::wait(m_owner->m_end_request); 103412027Sjungma@eit.uni-kl.de m_owner->m_current_transaction = 0; 103512027Sjungma@eit.uni-kl.de break; 103612027Sjungma@eit.uni-kl.de 103712027Sjungma@eit.uni-kl.de case tlm::END_REQ: 103812027Sjungma@eit.uni-kl.de sc_core::wait(t); 103912027Sjungma@eit.uni-kl.de break; 104012027Sjungma@eit.uni-kl.de 104112027Sjungma@eit.uni-kl.de case tlm::BEGIN_RESP: 104212027Sjungma@eit.uni-kl.de { 104312027Sjungma@eit.uni-kl.de phase = tlm::END_RESP; 104412027Sjungma@eit.uni-kl.de sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2 104512027Sjungma@eit.uni-kl.de t = sc_core::SC_ZERO_TIME; 104612027Sjungma@eit.uni-kl.de (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t); 104712027Sjungma@eit.uni-kl.de 104812027Sjungma@eit.uni-kl.de // notify transaction is finished 104912027Sjungma@eit.uni-kl.de typename std::map<transaction_type*, sc_core::sc_event *>::iterator it = 105012027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.find(trans); 105112027Sjungma@eit.uni-kl.de assert(it != m_owner->m_pending_trans.end()); 105212027Sjungma@eit.uni-kl.de it->second->notify(t); 105312027Sjungma@eit.uni-kl.de m_owner->m_pending_trans.erase(it); 105412027Sjungma@eit.uni-kl.de break; 105512027Sjungma@eit.uni-kl.de } 105612027Sjungma@eit.uni-kl.de 105712027Sjungma@eit.uni-kl.de default: 105812027Sjungma@eit.uni-kl.de assert(0); exit(1); 105912027Sjungma@eit.uni-kl.de }; 106012027Sjungma@eit.uni-kl.de break; 106112027Sjungma@eit.uni-kl.de 106212027Sjungma@eit.uni-kl.de default: 106312027Sjungma@eit.uni-kl.de assert(0); exit(1); 106412027Sjungma@eit.uni-kl.de }; 106512027Sjungma@eit.uni-kl.de } 106612027Sjungma@eit.uni-kl.de } 106712027Sjungma@eit.uni-kl.de } 106812027Sjungma@eit.uni-kl.de 106912027Sjungma@eit.uni-kl.de void free(tlm::tlm_generic_payload* trans) 107012027Sjungma@eit.uni-kl.de { 107112027Sjungma@eit.uni-kl.de mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>(); 107212027Sjungma@eit.uni-kl.de assert(ext); 107312027Sjungma@eit.uni-kl.de // notif event first before freeing extensions (reset) 107412027Sjungma@eit.uni-kl.de ext->done.notify(); 107512027Sjungma@eit.uni-kl.de trans->reset(); 107612027Sjungma@eit.uni-kl.de } 107712027Sjungma@eit.uni-kl.de 107812027Sjungma@eit.uni-kl.de private: 107912027Sjungma@eit.uni-kl.de struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext> 108012027Sjungma@eit.uni-kl.de { 108112027Sjungma@eit.uni-kl.de tlm::tlm_extension_base* clone() const { return NULL; } 108212027Sjungma@eit.uni-kl.de void free() {} 108312027Sjungma@eit.uni-kl.de void copy_from(tlm::tlm_extension_base const &) {} 108412027Sjungma@eit.uni-kl.de sc_core::sc_event done; 108512027Sjungma@eit.uni-kl.de }; 108612027Sjungma@eit.uni-kl.de 108712027Sjungma@eit.uni-kl.de private: 108812027Sjungma@eit.uni-kl.de const std::string m_name; 108912027Sjungma@eit.uni-kl.de simple_target_socket_tagged *m_owner; 109012027Sjungma@eit.uni-kl.de MODULE* m_mod; 109112027Sjungma@eit.uni-kl.de NBTransportPtr m_nb_transport_ptr; 109212027Sjungma@eit.uni-kl.de BTransportPtr m_b_transport_ptr; 109312027Sjungma@eit.uni-kl.de TransportDbgPtr m_transport_dbg_ptr; 109412027Sjungma@eit.uni-kl.de GetDirectMemPtr m_get_direct_mem_ptr; 109512027Sjungma@eit.uni-kl.de int m_nb_transport_user_id; 109612027Sjungma@eit.uni-kl.de int m_b_transport_user_id; 109712027Sjungma@eit.uni-kl.de int m_transport_dbg_user_id; 109812027Sjungma@eit.uni-kl.de int m_get_dmi_user_id; 109912027Sjungma@eit.uni-kl.de peq_with_get<transaction_type> m_peq; 110012027Sjungma@eit.uni-kl.de bool m_response_in_progress; 110112027Sjungma@eit.uni-kl.de sc_core::sc_event m_end_response; 110212027Sjungma@eit.uni-kl.de }; 110312027Sjungma@eit.uni-kl.de 110412027Sjungma@eit.uni-kl.deprivate: 110512027Sjungma@eit.uni-kl.de fw_process m_fw_process; 110612027Sjungma@eit.uni-kl.de bw_process m_bw_process; 110712027Sjungma@eit.uni-kl.de std::map<transaction_type*, sc_core::sc_event *> m_pending_trans; 110812027Sjungma@eit.uni-kl.de sc_core::sc_event m_end_request; 110912027Sjungma@eit.uni-kl.de transaction_type* m_current_transaction; 111012027Sjungma@eit.uni-kl.de}; 111112027Sjungma@eit.uni-kl.de 111212027Sjungma@eit.uni-kl.de} 111312027Sjungma@eit.uni-kl.de 111412027Sjungma@eit.uni-kl.de#endif 1115