1/* 2 * Copyright 2019 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Copyright (c) 2016, Dresden University of Technology (TU Dresden) 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions are 32 * met: 33 * 34 * 1. Redistributions of source code must retain the above copyright notice, 35 * this list of conditions and the following disclaimer. 36 * 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 41 * 3. Neither the name of the copyright holder nor the names of its 42 * contributors may be used to endorse or promote products derived from 43 * this software without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 47 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 49 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * 57 * Authors: Gabe Black 58 * Christian Menard 59 */ 60 61#include "systemc/tlm_bridge/tlm_to_gem5.hh" 62
| 1/* 2 * Copyright 2019 Google, Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Copyright (c) 2016, Dresden University of Technology (TU Dresden) 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions are 32 * met: 33 * 34 * 1. Redistributions of source code must retain the above copyright notice, 35 * this list of conditions and the following disclaimer. 36 * 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 41 * 3. Neither the name of the copyright holder nor the names of its 42 * contributors may be used to endorse or promote products derived from 43 * this software without specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 47 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 49 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 52 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 53 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 54 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 55 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * 57 * Authors: Gabe Black 58 * Christian Menard 59 */ 60 61#include "systemc/tlm_bridge/tlm_to_gem5.hh" 62
|
| 63#include "params/TlmToGem5Bridge32.hh" 64#include "params/TlmToGem5Bridge64.hh"
|
63#include "sim/system.hh" 64#include "systemc/ext/core/sc_module_name.hh" 65 66namespace sc_gem5 67{ 68
| 65#include "sim/system.hh" 66#include "systemc/ext/core/sc_module_name.hh" 67 68namespace sc_gem5 69{ 70
|
| 71template <unsigned int BITWIDTH>
|
69void
| 72void
|
70TlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans)
| 73TlmToGem5Bridge<BITWIDTH>::sendEndReq(tlm::tlm_generic_payload &trans)
|
71{ 72 tlm::tlm_phase phase = tlm::END_REQ; 73 auto delay = sc_core::SC_ZERO_TIME; 74 75 auto status = socket->nb_transport_bw(trans, phase, delay); 76 panic_if(status != tlm::TLM_ACCEPTED, 77 "Unexpected status after sending END_REQ"); 78} 79
| 74{ 75 tlm::tlm_phase phase = tlm::END_REQ; 76 auto delay = sc_core::SC_ZERO_TIME; 77 78 auto status = socket->nb_transport_bw(trans, phase, delay); 79 panic_if(status != tlm::TLM_ACCEPTED, 80 "Unexpected status after sending END_REQ"); 81} 82
|
| 83template <unsigned int BITWIDTH>
|
80void
| 84void
|
81TlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans, 82 sc_core::sc_time &delay)
| 85TlmToGem5Bridge<BITWIDTH>::sendBeginResp(tlm::tlm_generic_payload &trans, 86 sc_core::sc_time &delay)
|
83{ 84 tlm::tlm_phase phase = tlm::BEGIN_RESP; 85 86 trans.set_response_status(tlm::TLM_OK_RESPONSE); 87 88 auto status = socket->nb_transport_bw(trans, phase, delay); 89 90 if (status == tlm::TLM_COMPLETED || 91 (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) { 92 // transaction completed -> no need to wait for tlm::END_RESP 93 responseInProgress = false; 94 } else if (status == tlm::TLM_ACCEPTED) { 95 // we need to wait for tlm::END_RESP 96 responseInProgress = true; 97 } else { 98 panic("Unexpected status after sending BEGIN_RESP"); 99 } 100} 101
| 87{ 88 tlm::tlm_phase phase = tlm::BEGIN_RESP; 89 90 trans.set_response_status(tlm::TLM_OK_RESPONSE); 91 92 auto status = socket->nb_transport_bw(trans, phase, delay); 93 94 if (status == tlm::TLM_COMPLETED || 95 (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) { 96 // transaction completed -> no need to wait for tlm::END_RESP 97 responseInProgress = false; 98 } else if (status == tlm::TLM_ACCEPTED) { 99 // we need to wait for tlm::END_RESP 100 responseInProgress = true; 101 } else { 102 panic("Unexpected status after sending BEGIN_RESP"); 103 } 104} 105
|
| 106template <unsigned int BITWIDTH>
|
102void
| 107void
|
103TlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans)
| 108TlmToGem5Bridge<BITWIDTH>::handleBeginReq(tlm::tlm_generic_payload &trans)
|
104{ 105 sc_assert(!waitForRetry); 106 sc_assert(pendingRequest == nullptr); 107 sc_assert(pendingPacket == nullptr); 108 109 trans.acquire(); 110 111 PacketPtr pkt = nullptr; 112 113 Gem5SystemC::Gem5Extension *extension = nullptr; 114 trans.get_extension(extension); 115 116 // If there is an extension, this transaction was initiated by the gem5 117 // world and we can pipe through the original packet. Otherwise, we 118 // generate a new packet based on the transaction. 119 if (extension != nullptr) { 120 extension->setPipeThrough(); 121 pkt = extension->getPacket(); 122 } else { 123 pkt = generatePacket(trans); 124 } 125 126 auto tlmSenderState = new TlmSenderState(trans); 127 pkt->pushSenderState(tlmSenderState); 128 129 if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately 130 sendEndReq(trans); 131 trans.release(); 132 } else { // port is blocked -> wait for retry before sending END_REQ 133 waitForRetry = true; 134 pendingRequest = &trans; 135 pendingPacket = pkt; 136 } 137} 138
| 109{ 110 sc_assert(!waitForRetry); 111 sc_assert(pendingRequest == nullptr); 112 sc_assert(pendingPacket == nullptr); 113 114 trans.acquire(); 115 116 PacketPtr pkt = nullptr; 117 118 Gem5SystemC::Gem5Extension *extension = nullptr; 119 trans.get_extension(extension); 120 121 // If there is an extension, this transaction was initiated by the gem5 122 // world and we can pipe through the original packet. Otherwise, we 123 // generate a new packet based on the transaction. 124 if (extension != nullptr) { 125 extension->setPipeThrough(); 126 pkt = extension->getPacket(); 127 } else { 128 pkt = generatePacket(trans); 129 } 130 131 auto tlmSenderState = new TlmSenderState(trans); 132 pkt->pushSenderState(tlmSenderState); 133 134 if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately 135 sendEndReq(trans); 136 trans.release(); 137 } else { // port is blocked -> wait for retry before sending END_REQ 138 waitForRetry = true; 139 pendingRequest = &trans; 140 pendingPacket = pkt; 141 } 142} 143
|
| 144template <unsigned int BITWIDTH>
|
139void
| 145void
|
140TlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans)
| 146TlmToGem5Bridge<BITWIDTH>::handleEndResp(tlm::tlm_generic_payload &trans)
|
141{ 142 sc_assert(responseInProgress); 143 144 responseInProgress = false; 145 146 checkTransaction(trans); 147 148 if (needToSendRetry) { 149 bmp.sendRetryResp(); 150 needToSendRetry = false; 151 } 152} 153
| 147{ 148 sc_assert(responseInProgress); 149 150 responseInProgress = false; 151 152 checkTransaction(trans); 153 154 if (needToSendRetry) { 155 bmp.sendRetryResp(); 156 needToSendRetry = false; 157 } 158} 159
|
| 160template <unsigned int BITWIDTH>
|
154PacketPtr
| 161PacketPtr
|
155TlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans)
| 162TlmToGem5Bridge<BITWIDTH>::generatePacket(tlm::tlm_generic_payload &trans)
|
156{ 157 MemCmd cmd; 158 159 switch (trans.get_command()) { 160 case tlm::TLM_READ_COMMAND: 161 cmd = MemCmd::ReadReq; 162 break; 163 case tlm::TLM_WRITE_COMMAND: 164 cmd = MemCmd::WriteReq; 165 break; 166 case tlm::TLM_IGNORE_COMMAND: 167 return nullptr; 168 default: 169 SC_REPORT_FATAL("TlmToGem5Bridge", 170 "received transaction with unsupported command"); 171 } 172 173 Request::Flags flags; 174 auto req = std::make_shared<Request>( 175 trans.get_address(), trans.get_data_length(), flags, masterId); 176 177 /* 178 * Allocate a new Packet. The packet will be deleted when it returns from 179 * the gem5 world as a response. 180 */ 181 auto pkt = new Packet(req, cmd); 182 pkt->dataStatic(trans.get_data_ptr()); 183 184 return pkt; 185} 186
| 163{ 164 MemCmd cmd; 165 166 switch (trans.get_command()) { 167 case tlm::TLM_READ_COMMAND: 168 cmd = MemCmd::ReadReq; 169 break; 170 case tlm::TLM_WRITE_COMMAND: 171 cmd = MemCmd::WriteReq; 172 break; 173 case tlm::TLM_IGNORE_COMMAND: 174 return nullptr; 175 default: 176 SC_REPORT_FATAL("TlmToGem5Bridge", 177 "received transaction with unsupported command"); 178 } 179 180 Request::Flags flags; 181 auto req = std::make_shared<Request>( 182 trans.get_address(), trans.get_data_length(), flags, masterId); 183 184 /* 185 * Allocate a new Packet. The packet will be deleted when it returns from 186 * the gem5 world as a response. 187 */ 188 auto pkt = new Packet(req, cmd); 189 pkt->dataStatic(trans.get_data_ptr()); 190 191 return pkt; 192} 193
|
| 194template <unsigned int BITWIDTH>
|
187void
| 195void
|
188TlmToGem5Bridge::destroyPacket(PacketPtr pkt)
| 196TlmToGem5Bridge<BITWIDTH>::destroyPacket(PacketPtr pkt)
|
189{ 190 delete pkt; 191} 192
| 197{ 198 delete pkt; 199} 200
|
| 201template <unsigned int BITWIDTH>
|
193void
| 202void
|
194TlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans)
| 203TlmToGem5Bridge<BITWIDTH>::checkTransaction(tlm::tlm_generic_payload &trans)
|
195{ 196 if (trans.is_response_error()) { 197 std::stringstream ss; 198 ss << "Transaction returned with error, response status = " 199 << trans.get_response_string(); 200 SC_REPORT_ERROR("TLM-2", ss.str().c_str()); 201 } 202} 203
| 204{ 205 if (trans.is_response_error()) { 206 std::stringstream ss; 207 ss << "Transaction returned with error, response status = " 208 << trans.get_response_string(); 209 SC_REPORT_ERROR("TLM-2", ss.str().c_str()); 210 } 211} 212
|
| 213template <unsigned int BITWIDTH>
|
204void
| 214void
|
205TlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans, 206 const tlm::tlm_phase &phase)
| 215TlmToGem5Bridge<BITWIDTH>::peq_cb(tlm::tlm_generic_payload &trans, 216 const tlm::tlm_phase &phase)
|
207{ 208 switch (phase) { 209 case tlm::BEGIN_REQ: 210 handleBeginReq(trans); 211 break; 212 case tlm::END_RESP: 213 handleEndResp(trans); 214 break; 215 default: 216 panic("unimplemented phase in callback"); 217 } 218} 219
| 217{ 218 switch (phase) { 219 case tlm::BEGIN_REQ: 220 handleBeginReq(trans); 221 break; 222 case tlm::END_RESP: 223 handleEndResp(trans); 224 break; 225 default: 226 panic("unimplemented phase in callback"); 227 } 228} 229
|
| 230template <unsigned int BITWIDTH>
|
220tlm::tlm_sync_enum
| 231tlm::tlm_sync_enum
|
221TlmToGem5Bridge::nb_transport_fw(
| 232TlmToGem5Bridge<BITWIDTH>::nb_transport_fw(
|
222 tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, 223 sc_core::sc_time &delay) 224{ 225 unsigned len = trans.get_data_length(); 226 unsigned char *byteEnable = trans.get_byte_enable_ptr(); 227 unsigned width = trans.get_streaming_width(); 228 229 // check the transaction attributes for unsupported features ... 230 if (byteEnable != 0) { 231 trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); 232 return tlm::TLM_COMPLETED; 233 } 234 if (width < len) { // is this a burst request? 235 trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); 236 return tlm::TLM_COMPLETED; 237 } 238 239 // ... and queue the valid transaction 240 trans.acquire(); 241 peq.notify(trans, phase, delay); 242 return tlm::TLM_ACCEPTED; 243} 244
| 233 tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, 234 sc_core::sc_time &delay) 235{ 236 unsigned len = trans.get_data_length(); 237 unsigned char *byteEnable = trans.get_byte_enable_ptr(); 238 unsigned width = trans.get_streaming_width(); 239 240 // check the transaction attributes for unsupported features ... 241 if (byteEnable != 0) { 242 trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); 243 return tlm::TLM_COMPLETED; 244 } 245 if (width < len) { // is this a burst request? 246 trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); 247 return tlm::TLM_COMPLETED; 248 } 249 250 // ... and queue the valid transaction 251 trans.acquire(); 252 peq.notify(trans, phase, delay); 253 return tlm::TLM_ACCEPTED; 254} 255
|
| 256template <unsigned int BITWIDTH>
|
245void
| 257void
|
246TlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans, 247 sc_core::sc_time &t)
| 258TlmToGem5Bridge<BITWIDTH>::b_transport(tlm::tlm_generic_payload &trans, 259 sc_core::sc_time &t)
|
248{ 249 Gem5SystemC::Gem5Extension *extension = nullptr; 250 trans.get_extension(extension); 251 252 PacketPtr pkt = nullptr; 253 254 // If there is an extension, this transaction was initiated by the gem5 255 // world and we can pipe through the original packet. 256 if (extension != nullptr) { 257 extension->setPipeThrough(); 258 pkt = extension->getPacket(); 259 } else { 260 pkt = generatePacket(trans); 261 } 262 263 Tick ticks = bmp.sendAtomic(pkt); 264 265 // send an atomic request to gem5 266 panic_if(pkt->needsResponse() && !pkt->isResponse(), 267 "Packet sending failed!\n"); 268 269 auto delay = 270 sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS); 271 272 // update time 273 t += delay; 274 275 if (extension == nullptr) 276 destroyPacket(pkt); 277 278 trans.set_response_status(tlm::TLM_OK_RESPONSE); 279} 280
| 260{ 261 Gem5SystemC::Gem5Extension *extension = nullptr; 262 trans.get_extension(extension); 263 264 PacketPtr pkt = nullptr; 265 266 // If there is an extension, this transaction was initiated by the gem5 267 // world and we can pipe through the original packet. 268 if (extension != nullptr) { 269 extension->setPipeThrough(); 270 pkt = extension->getPacket(); 271 } else { 272 pkt = generatePacket(trans); 273 } 274 275 Tick ticks = bmp.sendAtomic(pkt); 276 277 // send an atomic request to gem5 278 panic_if(pkt->needsResponse() && !pkt->isResponse(), 279 "Packet sending failed!\n"); 280 281 auto delay = 282 sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS); 283 284 // update time 285 t += delay; 286 287 if (extension == nullptr) 288 destroyPacket(pkt); 289 290 trans.set_response_status(tlm::TLM_OK_RESPONSE); 291} 292
|
| 293template <unsigned int BITWIDTH>
|
281unsigned int
| 294unsigned int
|
282TlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans)
| 295TlmToGem5Bridge<BITWIDTH>::transport_dbg(tlm::tlm_generic_payload &trans)
|
283{ 284 Gem5SystemC::Gem5Extension *extension = nullptr; 285 trans.get_extension(extension); 286 287 // If there is an extension, this transaction was initiated by the gem5 288 // world and we can pipe through the original packet. 289 if (extension != nullptr) { 290 extension->setPipeThrough(); 291 bmp.sendFunctional(extension->getPacket()); 292 } else { 293 auto pkt = generatePacket(trans); 294 if (pkt) { 295 bmp.sendFunctional(pkt); 296 destroyPacket(pkt); 297 } 298 } 299 300 return trans.get_data_length(); 301} 302
| 296{ 297 Gem5SystemC::Gem5Extension *extension = nullptr; 298 trans.get_extension(extension); 299 300 // If there is an extension, this transaction was initiated by the gem5 301 // world and we can pipe through the original packet. 302 if (extension != nullptr) { 303 extension->setPipeThrough(); 304 bmp.sendFunctional(extension->getPacket()); 305 } else { 306 auto pkt = generatePacket(trans); 307 if (pkt) { 308 bmp.sendFunctional(pkt); 309 destroyPacket(pkt); 310 } 311 } 312 313 return trans.get_data_length(); 314} 315
|
| 316template <unsigned int BITWIDTH>
|
303bool
| 317bool
|
304TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, 305 tlm::tlm_dmi &dmi_data)
| 318TlmToGem5Bridge<BITWIDTH>::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, 319 tlm::tlm_dmi &dmi_data)
|
306{ 307 return false; 308} 309
| 320{ 321 return false; 322} 323
|
| 324template <unsigned int BITWIDTH>
|
310bool
| 325bool
|
311TlmToGem5Bridge::recvTimingResp(PacketPtr pkt)
| 326TlmToGem5Bridge<BITWIDTH>::recvTimingResp(PacketPtr pkt)
|
312{ 313 // exclusion rule 314 // We need to Wait for END_RESP before sending next BEGIN_RESP 315 if (responseInProgress) { 316 sc_assert(!needToSendRetry); 317 needToSendRetry = true; 318 return false; 319 } 320 321 sc_assert(pkt->isResponse()); 322 323 /* 324 * Pay for annotated transport delays. 325 * 326 * See recvTimingReq in sc_slave_port.cc for a detailed description. 327 */ 328 auto delay = sc_core::sc_time::from_value(pkt->payloadDelay); 329 // reset the delays 330 pkt->payloadDelay = 0; 331 pkt->headerDelay = 0; 332 333 auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState()); 334 sc_assert(tlmSenderState != nullptr); 335 336 auto &trans = tlmSenderState->trans; 337 338 Gem5SystemC::Gem5Extension *extension = nullptr; 339 trans.get_extension(extension); 340 341 // clean up 342 delete tlmSenderState; 343 344 // If there is an extension the packet was piped through and we must not 345 // delete it. The packet travels back with the transaction. 346 if (extension == nullptr) 347 destroyPacket(pkt); 348 else 349 sc_assert(extension->isPipeThrough()); 350 351 sendBeginResp(trans, delay); 352 trans.release(); 353 354 return true; 355} 356
| 327{ 328 // exclusion rule 329 // We need to Wait for END_RESP before sending next BEGIN_RESP 330 if (responseInProgress) { 331 sc_assert(!needToSendRetry); 332 needToSendRetry = true; 333 return false; 334 } 335 336 sc_assert(pkt->isResponse()); 337 338 /* 339 * Pay for annotated transport delays. 340 * 341 * See recvTimingReq in sc_slave_port.cc for a detailed description. 342 */ 343 auto delay = sc_core::sc_time::from_value(pkt->payloadDelay); 344 // reset the delays 345 pkt->payloadDelay = 0; 346 pkt->headerDelay = 0; 347 348 auto tlmSenderState = dynamic_cast<TlmSenderState*>(pkt->popSenderState()); 349 sc_assert(tlmSenderState != nullptr); 350 351 auto &trans = tlmSenderState->trans; 352 353 Gem5SystemC::Gem5Extension *extension = nullptr; 354 trans.get_extension(extension); 355 356 // clean up 357 delete tlmSenderState; 358 359 // If there is an extension the packet was piped through and we must not 360 // delete it. The packet travels back with the transaction. 361 if (extension == nullptr) 362 destroyPacket(pkt); 363 else 364 sc_assert(extension->isPipeThrough()); 365 366 sendBeginResp(trans, delay); 367 trans.release(); 368 369 return true; 370} 371
|
| 372template <unsigned int BITWIDTH>
|
357void
| 373void
|
358TlmToGem5Bridge::recvReqRetry()
| 374TlmToGem5Bridge<BITWIDTH>::recvReqRetry()
|
359{ 360 sc_assert(waitForRetry); 361 sc_assert(pendingRequest != nullptr); 362 sc_assert(pendingPacket != nullptr); 363 364 if (bmp.sendTimingReq(pendingPacket)) { 365 waitForRetry = false; 366 pendingPacket = nullptr; 367 368 auto &trans = *pendingRequest; 369 sendEndReq(trans); 370 trans.release(); 371 372 pendingRequest = nullptr; 373 } 374} 375
| 375{ 376 sc_assert(waitForRetry); 377 sc_assert(pendingRequest != nullptr); 378 sc_assert(pendingPacket != nullptr); 379 380 if (bmp.sendTimingReq(pendingPacket)) { 381 waitForRetry = false; 382 pendingPacket = nullptr; 383 384 auto &trans = *pendingRequest; 385 sendEndReq(trans); 386 trans.release(); 387 388 pendingRequest = nullptr; 389 } 390} 391
|
| 392template <unsigned int BITWIDTH>
|
376void
| 393void
|
377TlmToGem5Bridge::recvRangeChange()
| 394TlmToGem5Bridge<BITWIDTH>::recvRangeChange()
|
378{ 379 SC_REPORT_WARNING("TlmToGem5Bridge", 380 "received address range change but ignored it"); 381} 382
| 395{ 396 SC_REPORT_WARNING("TlmToGem5Bridge", 397 "received address range change but ignored it"); 398} 399
|
| 400template <unsigned int BITWIDTH>
|
383::Port &
| 401::Port &
|
384TlmToGem5Bridge::gem5_getPort(const std::string &if_name, int idx)
| 402TlmToGem5Bridge<BITWIDTH>::gem5_getPort(const std::string &if_name, int idx)
|
385{ 386 if (if_name == "gem5") 387 return bmp; 388 else if (if_name == "tlm") 389 return wrapper; 390 391 return sc_core::sc_module::gem5_getPort(if_name, idx); 392} 393
| 403{ 404 if (if_name == "gem5") 405 return bmp; 406 else if (if_name == "tlm") 407 return wrapper; 408 409 return sc_core::sc_module::gem5_getPort(if_name, idx); 410} 411
|
394TlmToGem5Bridge::TlmToGem5Bridge(
| 412template <unsigned int BITWIDTH> 413TlmToGem5Bridge<BITWIDTH>::TlmToGem5Bridge(
|
395 Params *params, const sc_core::sc_module_name &mn) :
| 414 Params *params, const sc_core::sc_module_name &mn) :
|
396 sc_core::sc_module(mn), peq(this, &TlmToGem5Bridge::peq_cb),
| 415 TlmToGem5BridgeBase(mn), peq(this, &TlmToGem5Bridge<BITWIDTH>::peq_cb),
|
397 waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr), 398 needToSendRetry(false), responseInProgress(false), 399 bmp(std::string(name()) + "master", *this), socket("tlm_socket"), 400 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 401 system(params->system), 402 masterId(params->system->getGlobalMasterId( 403 std::string("[systemc].") + name())) 404{ 405} 406
| 416 waitForRetry(false), pendingRequest(nullptr), pendingPacket(nullptr), 417 needToSendRetry(false), responseInProgress(false), 418 bmp(std::string(name()) + "master", *this), socket("tlm_socket"), 419 wrapper(socket, std::string(name()) + ".tlm", InvalidPortID), 420 system(params->system), 421 masterId(params->system->getGlobalMasterId( 422 std::string("[systemc].") + name())) 423{ 424} 425
|
| 426template <unsigned int BITWIDTH>
|
407void
| 427void
|
408TlmToGem5Bridge::before_end_of_elaboration()
| 428TlmToGem5Bridge<BITWIDTH>::before_end_of_elaboration()
|
409{ 410 /* 411 * Register the TLM non-blocking interface when using gem5 Timing mode and 412 * the TLM blocking interface when using the gem5 Atomic mode. 413 * Then the magic (TM) in simple_target_socket automatically transforms 414 * non-blocking in blocking transactions and vice versa. 415 * 416 * NOTE: The mode may change during execution. 417 */ 418 if (system->isTimingMode()) { 419 SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface"); 420 socket.register_nb_transport_fw(
| 429{ 430 /* 431 * Register the TLM non-blocking interface when using gem5 Timing mode and 432 * the TLM blocking interface when using the gem5 Atomic mode. 433 * Then the magic (TM) in simple_target_socket automatically transforms 434 * non-blocking in blocking transactions and vice versa. 435 * 436 * NOTE: The mode may change during execution. 437 */ 438 if (system->isTimingMode()) { 439 SC_REPORT_INFO("TlmToGem5Bridge", "register non-blocking interface"); 440 socket.register_nb_transport_fw(
|
421 this, &TlmToGem5Bridge::nb_transport_fw);
| 441 this, &TlmToGem5Bridge<BITWIDTH>::nb_transport_fw);
|
422 } else if (system->isAtomicMode()) { 423 SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface"); 424 socket.register_b_transport(
| 442 } else if (system->isAtomicMode()) { 443 SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface"); 444 socket.register_b_transport(
|
425 this, &TlmToGem5Bridge::b_transport);
| 445 this, &TlmToGem5Bridge<BITWIDTH>::b_transport);
|
426 } else { 427 panic("gem5 operates neither in Timing nor in Atomic mode"); 428 } 429
| 446 } else { 447 panic("gem5 operates neither in Timing nor in Atomic mode"); 448 } 449
|
430 socket.register_transport_dbg(this, &TlmToGem5Bridge::transport_dbg);
| 450 socket.register_transport_dbg( 451 this, &TlmToGem5Bridge<BITWIDTH>::transport_dbg);
|
431 432 sc_core::sc_module::before_end_of_elaboration(); 433} 434 435} // namespace sc_gem5 436
| 452 453 sc_core::sc_module::before_end_of_elaboration(); 454} 455 456} // namespace sc_gem5 457
|
437sc_gem5::TlmToGem5Bridge * 438TlmToGem5BridgeParams::create()
| 458sc_gem5::TlmToGem5Bridge<32> * 459TlmToGem5Bridge32Params::create()
|
439{
| 460{
|
440 return new sc_gem5::TlmToGem5Bridge(
| 461 return new sc_gem5::TlmToGem5Bridge<32>(
|
441 this, sc_core::sc_module_name(name.c_str())); 442}
| 462 this, sc_core::sc_module_name(name.c_str())); 463}
|
| 464 465sc_gem5::TlmToGem5Bridge<64> * 466TlmToGem5Bridge64Params::create() 467{ 468 return new sc_gem5::TlmToGem5Bridge<64>( 469 this, sc_core::sc_module_name(name.c_str())); 470}
|
| |