1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20#ifndef __EXTENSIONS_ADAPTORS_H__ 21#define __EXTENSIONS_ADAPTORS_H__ 22 23#include "tlm.h" 24#include "my_extension.h" 25 26#include "tlm_utils/simple_initiator_socket.h" 27#include "tlm_utils/simple_target_socket.h" 28 29template <unsigned int BUSWIDTH = 32> 30class adapt_ext2gp : public sc_core::sc_module 31{ 32 public: 33 typedef tlm::tlm_generic_payload initiator_payload_type; 34 typedef tlm::tlm_generic_payload target_payload_type; 35 typedef tlm_utils::simple_initiator_socket<adapt_ext2gp, BUSWIDTH, 36 tlm::tlm_base_protocol_types> initiator_socket_type; 37 typedef tlm_utils::simple_target_socket<adapt_ext2gp, BUSWIDTH, 38 my_extended_payload_types> target_socket_type; 39 40 target_socket_type target_socket; 41 initiator_socket_type initiator_socket; 42 43 SC_HAS_PROCESS(adapt_ext2gp); 44 adapt_ext2gp(sc_core::sc_module_name name_) 45 : sc_core::sc_module(name_) 46 { 47 target_socket.register_nb_transport_fw(this, &adapt_ext2gp::forward_nb_transport); 48 target_socket.register_transport_dbg(this, &adapt_ext2gp::transport_debug); 49 target_socket.register_get_direct_mem_ptr(this, &adapt_ext2gp::get_dmi_pointer); 50 51 initiator_socket.register_nb_transport_bw(this, &adapt_ext2gp::backward_nb_transport); 52 initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_ext2gp::invalidate_dmi_pointers); 53 } 54 55 /////////////// 56 // NB transport 57 /////////////// 58 59 // Forward direction: The initiator calls this method with an extended 60 // payload. We leave the extension class in the vector, and it will be 61 // ignored by the GP target. 62 tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, 63 tlm::tlm_phase& phase, 64 sc_core::sc_time& t) 65 { 66 return initiator_socket->nb_transport_fw(trans, phase, t); 67 } 68 // Backward direction: we can assume here that the payload we get 69 // as parameter is the same one that the initiator sent out. Thus, the 70 // extension vector is known to be present. 71 tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, 72 tlm::tlm_phase& phase, 73 sc_core::sc_time& t) 74 { 75 return target_socket->nb_transport_bw(trans, phase, t); 76 } 77 78 bool get_dmi_pointer(target_payload_type& trans, 79 tlm::tlm_dmi& dmi_data) 80 { 81 bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, 82 dmi_data); 83 return tmp_ret; 84 } 85 86 ////////////////////////// 87 // simple call forwarders: 88 ////////////////////////// 89 unsigned int transport_debug(target_payload_type& trans) 90 { 91 return initiator_socket->transport_dbg(trans); 92 } 93 void invalidate_dmi_pointers(sc_dt::uint64 start_range, 94 sc_dt::uint64 end_range) 95 { 96 target_socket->invalidate_direct_mem_ptr(start_range, 97 end_range); 98 } 99}; 100 101template <unsigned int BUSWIDTH = 32> 102class adapt_gp2ext : public sc_core::sc_module 103{ 104 public: 105 typedef tlm::tlm_generic_payload initiator_payload_type; 106 typedef tlm::tlm_generic_payload target_payload_type; 107 typedef tlm_utils::simple_initiator_socket<adapt_gp2ext, BUSWIDTH, 108 my_extended_payload_types> initiator_socket_type; 109 typedef tlm_utils::simple_target_socket<adapt_gp2ext, BUSWIDTH, 110 tlm::tlm_base_protocol_types> target_socket_type; 111 112 target_socket_type target_socket; 113 initiator_socket_type initiator_socket; 114 115 SC_HAS_PROCESS(adapt_gp2ext); 116 adapt_gp2ext(sc_core::sc_module_name name_) 117 : sc_core::sc_module(name_) 118 { 119 // Optionally, we can initialize our private extension class 120 // here, if required. 121 122 target_socket.register_nb_transport_fw(this, &adapt_gp2ext::forward_nb_transport); 123 target_socket.register_transport_dbg(this, &adapt_gp2ext::transport_debug); 124 target_socket.register_get_direct_mem_ptr(this, &adapt_gp2ext::get_dmi_pointer); 125 126 initiator_socket.register_nb_transport_bw(this, &adapt_gp2ext::backward_nb_transport); 127 initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_gp2ext::invalidate_dmi_pointers); 128 129 m_ext.m_data = 13; 130 } 131 132 /////////////// 133 // NB transport 134 /////////////// 135 136 // Forward direction: We extend the payload on the fly (if needed). 137 tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, 138 tlm::tlm_phase& phase, 139 sc_core::sc_time& t) 140 { 141 // If the mandatory extension is not there, we need to add it and 142 // store it so that we can re-construc the original state. 143 // Otherwise we don't touch the extension, so that we don't overwrite 144 // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) 145 // setup. 146 // Note, however, that there might be situations where we might need to 147 // re-initialize the extension, e.g. for mutable data fields in 148 // different system setups. 149 trans.get_extension(m_initiator_ext); 150 if (!m_initiator_ext) 151 { 152 m_initiator_ext = trans.set_extension(&m_ext); 153 } 154 tlm::tlm_sync_enum tmp = 155 initiator_socket->nb_transport_fw(trans, phase, t); 156 if (tmp == tlm::TLM_COMPLETED) 157 { 158 m_initiator_ext = trans.set_extension(m_initiator_ext); 159 } 160 return tmp; 161 } 162 // Backward direction: only restore of original extension and static_cast. 163 tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, 164 tlm::tlm_phase& phase, 165 sc_core::sc_time& t) 166 { 167 m_initiator_ext = trans.set_extension(m_initiator_ext); 168 return target_socket->nb_transport_bw(trans, phase, t); 169 } 170 171 bool get_dmi_pointer(target_payload_type& trans, 172 tlm::tlm_dmi& dmi_data) 173 { 174 // If the mandatory extension is not there, we need to add it and 175 // store it so that we can re-construc the original state. 176 // Otherwise we don't touch the extension, so that we don't overwrite 177 // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) 178 // setup. 179 my_extension* tmp_ext; 180 trans.get_extension(tmp_ext); 181 if (!tmp_ext) 182 { 183 trans.set_extension(&m_ext); 184 } 185 bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, 186 dmi_data); 187 if(!tmp_ext) 188 { 189 trans.clear_extension(tmp_ext); 190 } 191 return tmp_ret; 192 } 193 ////////////////////////// 194 // simple call forwarders: 195 ////////////////////////// 196 unsigned int transport_debug(target_payload_type& trans) 197 { 198 return initiator_socket->transport_dbg(trans); 199 } 200 void invalidate_dmi_pointers(sc_dt::uint64 start_range, 201 sc_dt::uint64 end_range) 202 { 203 target_socket->invalidate_direct_mem_ptr(start_range, 204 end_range); 205 } 206 207private: 208 my_extension m_ext; 209 my_extension* m_initiator_ext; 210}; 211 212#endif 213