tlm_to_gem5.cc revision 13821:f9252f27ded7
15083Sgblack@eecs.umich.edu/* 25083Sgblack@eecs.umich.edu * Copyright 2019 Google, Inc. 35083Sgblack@eecs.umich.edu * 47087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 57087Snate@binkert.org * modification, are permitted provided that the following conditions are 67087Snate@binkert.org * met: redistributions of source code must retain the above copyright 77087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 87087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 97087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 107087Snate@binkert.org * documentation and/or other materials provided with the distribution; 117087Snate@binkert.org * neither the name of the copyright holders nor the names of its 125083Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 137087Snate@binkert.org * this software without specific prior written permission. 147087Snate@binkert.org * 157087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 167087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 177087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 187087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 197087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 207087Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 215083Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 227087Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 235083Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245083Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 255083Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265083Sgblack@eecs.umich.edu * 275083Sgblack@eecs.umich.edu * Copyright (c) 2016, Dresden University of Technology (TU Dresden) 285083Sgblack@eecs.umich.edu * All rights reserved. 295083Sgblack@eecs.umich.edu * 305083Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 315083Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 325083Sgblack@eecs.umich.edu * met: 335083Sgblack@eecs.umich.edu * 345083Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright notice, 355083Sgblack@eecs.umich.edu * this list of conditions and the following disclaimer. 365083Sgblack@eecs.umich.edu * 375083Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright 385083Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 395083Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution. 405083Sgblack@eecs.umich.edu * 415083Sgblack@eecs.umich.edu * 3. Neither the name of the copyright holder nor the names of its 425083Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 435083Sgblack@eecs.umich.edu * this software without specific prior written permission. 445083Sgblack@eecs.umich.edu * 455083Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 465083Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 475083Sgblack@eecs.umich.edu * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 485083Sgblack@eecs.umich.edu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 495083Sgblack@eecs.umich.edu * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 505083Sgblack@eecs.umich.edu * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 515083Sgblack@eecs.umich.edu * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 525083Sgblack@eecs.umich.edu * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 535083Sgblack@eecs.umich.edu * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 545083Sgblack@eecs.umich.edu * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 555083Sgblack@eecs.umich.edu * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 565083Sgblack@eecs.umich.edu * 575083Sgblack@eecs.umich.edu * Authors: Gabe Black 585083Sgblack@eecs.umich.edu * Christian Menard 595083Sgblack@eecs.umich.edu */ 605083Sgblack@eecs.umich.edu 615083Sgblack@eecs.umich.edu#include "systemc/tlm_bridge/tlm_to_gem5.hh" 625083Sgblack@eecs.umich.edu 635083Sgblack@eecs.umich.edu#include "sim/system.hh" 645083Sgblack@eecs.umich.edu#include "systemc/ext/core/sc_module_name.hh" 655083Sgblack@eecs.umich.edu 665083Sgblack@eecs.umich.edunamespace sc_gem5 675083Sgblack@eecs.umich.edu{ 685083Sgblack@eecs.umich.edu 695083Sgblack@eecs.umich.eduvoid 705083Sgblack@eecs.umich.eduTlmToGem5Bridge::sendEndReq(tlm::tlm_generic_payload &trans) 715083Sgblack@eecs.umich.edu{ 725083Sgblack@eecs.umich.edu tlm::tlm_phase phase = tlm::END_REQ; 735083Sgblack@eecs.umich.edu auto delay = sc_core::SC_ZERO_TIME; 745083Sgblack@eecs.umich.edu 755083Sgblack@eecs.umich.edu auto status = socket->nb_transport_bw(trans, phase, delay); 765083Sgblack@eecs.umich.edu panic_if(status != tlm::TLM_ACCEPTED, 775083Sgblack@eecs.umich.edu "Unexpected status after sending END_REQ"); 785083Sgblack@eecs.umich.edu} 797620Sgblack@eecs.umich.edu 806345Sgblack@eecs.umich.eduvoid 815083Sgblack@eecs.umich.eduTlmToGem5Bridge::sendBeginResp(tlm::tlm_generic_payload &trans, 825083Sgblack@eecs.umich.edu sc_core::sc_time &delay) 835083Sgblack@eecs.umich.edu{ 845083Sgblack@eecs.umich.edu tlm::tlm_phase phase = tlm::BEGIN_RESP; 855083Sgblack@eecs.umich.edu 865083Sgblack@eecs.umich.edu trans.set_response_status(tlm::TLM_OK_RESPONSE); 875083Sgblack@eecs.umich.edu 885083Sgblack@eecs.umich.edu auto status = socket->nb_transport_bw(trans, phase, delay); 897620Sgblack@eecs.umich.edu 906345Sgblack@eecs.umich.edu if (status == tlm::TLM_COMPLETED || 915083Sgblack@eecs.umich.edu (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) { 927620Sgblack@eecs.umich.edu // transaction completed -> no need to wait for tlm::END_RESP 935083Sgblack@eecs.umich.edu responseInProgress = false; 945083Sgblack@eecs.umich.edu } else if (status == tlm::TLM_ACCEPTED) { 955083Sgblack@eecs.umich.edu // we need to wait for tlm::END_RESP 967626Sgblack@eecs.umich.edu responseInProgress = true; 975083Sgblack@eecs.umich.edu } else { 985083Sgblack@eecs.umich.edu panic("Unexpected status after sending BEGIN_RESP"); 995083Sgblack@eecs.umich.edu } 1005083Sgblack@eecs.umich.edu} 1015083Sgblack@eecs.umich.edu 1025083Sgblack@eecs.umich.eduvoid 1035083Sgblack@eecs.umich.eduTlmToGem5Bridge::handleBeginReq(tlm::tlm_generic_payload &trans) 1045083Sgblack@eecs.umich.edu{ 1055083Sgblack@eecs.umich.edu sc_assert(!waitForRetry); 1065083Sgblack@eecs.umich.edu sc_assert(pendingRequest == nullptr); 1075083Sgblack@eecs.umich.edu sc_assert(pendingPacket == nullptr); 1085083Sgblack@eecs.umich.edu 1095083Sgblack@eecs.umich.edu trans.acquire(); 1105083Sgblack@eecs.umich.edu 1115083Sgblack@eecs.umich.edu PacketPtr pkt = nullptr; 1125083Sgblack@eecs.umich.edu 1135083Sgblack@eecs.umich.edu Gem5SystemC::Gem5Extension *extension = nullptr; 1145083Sgblack@eecs.umich.edu trans.get_extension(extension); 1155083Sgblack@eecs.umich.edu 1165083Sgblack@eecs.umich.edu // If there is an extension, this transaction was initiated by the gem5 1175083Sgblack@eecs.umich.edu // world and we can pipe through the original packet. Otherwise, we 1185083Sgblack@eecs.umich.edu // generate a new packet based on the transaction. 1195083Sgblack@eecs.umich.edu if (extension != nullptr) { 1205083Sgblack@eecs.umich.edu extension->setPipeThrough(); 1215083Sgblack@eecs.umich.edu pkt = extension->getPacket(); 1225083Sgblack@eecs.umich.edu } else { 1235083Sgblack@eecs.umich.edu pkt = generatePacket(trans); 1245083Sgblack@eecs.umich.edu } 1255083Sgblack@eecs.umich.edu 1265083Sgblack@eecs.umich.edu auto tlmSenderState = new TlmSenderState(trans); 1275083Sgblack@eecs.umich.edu pkt->pushSenderState(tlmSenderState); 1285083Sgblack@eecs.umich.edu 1295083Sgblack@eecs.umich.edu if (bmp.sendTimingReq(pkt)) { // port is free -> send END_REQ immediately 1305083Sgblack@eecs.umich.edu sendEndReq(trans); 1315083Sgblack@eecs.umich.edu trans.release(); 1325083Sgblack@eecs.umich.edu } else { // port is blocked -> wait for retry before sending END_REQ 1335083Sgblack@eecs.umich.edu waitForRetry = true; 1345083Sgblack@eecs.umich.edu pendingRequest = &trans; 1355083Sgblack@eecs.umich.edu pendingPacket = pkt; 1365083Sgblack@eecs.umich.edu } 1375083Sgblack@eecs.umich.edu} 1385083Sgblack@eecs.umich.edu 1395083Sgblack@eecs.umich.eduvoid 1405083Sgblack@eecs.umich.eduTlmToGem5Bridge::handleEndResp(tlm::tlm_generic_payload &trans) 1415083Sgblack@eecs.umich.edu{ 1425083Sgblack@eecs.umich.edu sc_assert(responseInProgress); 1435083Sgblack@eecs.umich.edu 1445083Sgblack@eecs.umich.edu responseInProgress = false; 1455083Sgblack@eecs.umich.edu 1465083Sgblack@eecs.umich.edu checkTransaction(trans); 1475083Sgblack@eecs.umich.edu 1485083Sgblack@eecs.umich.edu if (needToSendRetry) { 1495083Sgblack@eecs.umich.edu bmp.sendRetryResp(); 1505083Sgblack@eecs.umich.edu needToSendRetry = false; 1515083Sgblack@eecs.umich.edu } 1525083Sgblack@eecs.umich.edu} 1535083Sgblack@eecs.umich.edu 1545083Sgblack@eecs.umich.eduPacketPtr 1555083Sgblack@eecs.umich.eduTlmToGem5Bridge::generatePacket(tlm::tlm_generic_payload &trans) 1565083Sgblack@eecs.umich.edu{ 1575083Sgblack@eecs.umich.edu MemCmd cmd; 1585083Sgblack@eecs.umich.edu 1595083Sgblack@eecs.umich.edu switch (trans.get_command()) { 1605083Sgblack@eecs.umich.edu case tlm::TLM_READ_COMMAND: 1615083Sgblack@eecs.umich.edu cmd = MemCmd::ReadReq; 1625083Sgblack@eecs.umich.edu break; 1635083Sgblack@eecs.umich.edu case tlm::TLM_WRITE_COMMAND: 1645083Sgblack@eecs.umich.edu cmd = MemCmd::WriteReq; 1655083Sgblack@eecs.umich.edu break; 1665083Sgblack@eecs.umich.edu case tlm::TLM_IGNORE_COMMAND: 1675083Sgblack@eecs.umich.edu return nullptr; 1685083Sgblack@eecs.umich.edu default: 1695083Sgblack@eecs.umich.edu SC_REPORT_FATAL("TlmToGem5Bridge", 1705083Sgblack@eecs.umich.edu "received transaction with unsupported command"); 1715083Sgblack@eecs.umich.edu } 1725083Sgblack@eecs.umich.edu 1735083Sgblack@eecs.umich.edu Request::Flags flags; 1745083Sgblack@eecs.umich.edu auto req = std::make_shared<Request>( 1755083Sgblack@eecs.umich.edu trans.get_address(), trans.get_data_length(), flags, masterId); 1765083Sgblack@eecs.umich.edu 1775083Sgblack@eecs.umich.edu /* 1785083Sgblack@eecs.umich.edu * Allocate a new Packet. The packet will be deleted when it returns from 1795083Sgblack@eecs.umich.edu * the gem5 world as a response. 1805083Sgblack@eecs.umich.edu */ 1815083Sgblack@eecs.umich.edu auto pkt = new Packet(req, cmd); 1825083Sgblack@eecs.umich.edu pkt->dataStatic(trans.get_data_ptr()); 1835083Sgblack@eecs.umich.edu 1845083Sgblack@eecs.umich.edu return pkt; 1855083Sgblack@eecs.umich.edu} 1865083Sgblack@eecs.umich.edu 1875083Sgblack@eecs.umich.eduvoid 1885083Sgblack@eecs.umich.eduTlmToGem5Bridge::destroyPacket(PacketPtr pkt) 1895083Sgblack@eecs.umich.edu{ 1905083Sgblack@eecs.umich.edu delete pkt; 1915083Sgblack@eecs.umich.edu} 1925083Sgblack@eecs.umich.edu 1935083Sgblack@eecs.umich.eduvoid 1945083Sgblack@eecs.umich.eduTlmToGem5Bridge::checkTransaction(tlm::tlm_generic_payload &trans) 1955083Sgblack@eecs.umich.edu{ 1965083Sgblack@eecs.umich.edu if (trans.is_response_error()) { 1975083Sgblack@eecs.umich.edu std::stringstream ss; 1985083Sgblack@eecs.umich.edu ss << "Transaction returned with error, response status = " 1995083Sgblack@eecs.umich.edu << trans.get_response_string(); 2007620Sgblack@eecs.umich.edu SC_REPORT_ERROR("TLM-2", ss.str().c_str()); 2017620Sgblack@eecs.umich.edu } 2025083Sgblack@eecs.umich.edu} 2035083Sgblack@eecs.umich.edu 2045083Sgblack@eecs.umich.eduvoid 2055083Sgblack@eecs.umich.eduTlmToGem5Bridge::peq_cb(tlm::tlm_generic_payload &trans, 2065083Sgblack@eecs.umich.edu const tlm::tlm_phase &phase) 2075083Sgblack@eecs.umich.edu{ 2085083Sgblack@eecs.umich.edu switch (phase) { 2095083Sgblack@eecs.umich.edu case tlm::BEGIN_REQ: 2105083Sgblack@eecs.umich.edu handleBeginReq(trans); 2115083Sgblack@eecs.umich.edu break; 2126345Sgblack@eecs.umich.edu case tlm::END_RESP: 2135083Sgblack@eecs.umich.edu handleEndResp(trans); 2146345Sgblack@eecs.umich.edu break; 2155083Sgblack@eecs.umich.edu default: 2168588Sgblack@eecs.umich.edu panic("unimplemented phase in callback"); 2178588Sgblack@eecs.umich.edu } 2189010Snilay@cs.wisc.edu} 2199010Snilay@cs.wisc.edu 2205083Sgblack@eecs.umich.edutlm::tlm_sync_enum 2215083Sgblack@eecs.umich.eduTlmToGem5Bridge::nb_transport_fw( 2228588Sgblack@eecs.umich.edu tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, 2235083Sgblack@eecs.umich.edu sc_core::sc_time &delay) 2245083Sgblack@eecs.umich.edu{ 2255083Sgblack@eecs.umich.edu unsigned len = trans.get_data_length(); 2265083Sgblack@eecs.umich.edu unsigned char *byteEnable = trans.get_byte_enable_ptr(); 2275083Sgblack@eecs.umich.edu unsigned width = trans.get_streaming_width(); 2285083Sgblack@eecs.umich.edu 2295083Sgblack@eecs.umich.edu // check the transaction attributes for unsupported features ... 2305083Sgblack@eecs.umich.edu if (byteEnable != 0) { 2316345Sgblack@eecs.umich.edu trans.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE); 2326345Sgblack@eecs.umich.edu return tlm::TLM_COMPLETED; 2335083Sgblack@eecs.umich.edu } 2345083Sgblack@eecs.umich.edu if (width < len) { // is this a burst request? 2355083Sgblack@eecs.umich.edu trans.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE); 2365083Sgblack@eecs.umich.edu return tlm::TLM_COMPLETED; 2375083Sgblack@eecs.umich.edu } 2385083Sgblack@eecs.umich.edu 2395083Sgblack@eecs.umich.edu // ... and queue the valid transaction 2405083Sgblack@eecs.umich.edu trans.acquire(); 2415083Sgblack@eecs.umich.edu peq.notify(trans, phase, delay); 2425083Sgblack@eecs.umich.edu return tlm::TLM_ACCEPTED; 2435083Sgblack@eecs.umich.edu} 2445083Sgblack@eecs.umich.edu 2455083Sgblack@eecs.umich.eduvoid 2465083Sgblack@eecs.umich.eduTlmToGem5Bridge::b_transport(tlm::tlm_generic_payload &trans, 2475083Sgblack@eecs.umich.edu sc_core::sc_time &t) 2485083Sgblack@eecs.umich.edu{ 2495083Sgblack@eecs.umich.edu Gem5SystemC::Gem5Extension *extension = nullptr; 2505083Sgblack@eecs.umich.edu trans.get_extension(extension); 2515083Sgblack@eecs.umich.edu 2525083Sgblack@eecs.umich.edu PacketPtr pkt = nullptr; 2535083Sgblack@eecs.umich.edu 2545083Sgblack@eecs.umich.edu // If there is an extension, this transaction was initiated by the gem5 2555083Sgblack@eecs.umich.edu // world and we can pipe through the original packet. 2565083Sgblack@eecs.umich.edu if (extension != nullptr) { 2575083Sgblack@eecs.umich.edu extension->setPipeThrough(); 2585083Sgblack@eecs.umich.edu pkt = extension->getPacket(); 2595083Sgblack@eecs.umich.edu } else { 2605083Sgblack@eecs.umich.edu pkt = generatePacket(trans); 2615083Sgblack@eecs.umich.edu } 2625083Sgblack@eecs.umich.edu 2635083Sgblack@eecs.umich.edu Tick ticks = bmp.sendAtomic(pkt); 2645083Sgblack@eecs.umich.edu 2655083Sgblack@eecs.umich.edu // send an atomic request to gem5 2665083Sgblack@eecs.umich.edu panic_if(pkt->needsResponse() && !pkt->isResponse(), 2675083Sgblack@eecs.umich.edu "Packet sending failed!\n"); 2685083Sgblack@eecs.umich.edu 2695083Sgblack@eecs.umich.edu auto delay = 2705083Sgblack@eecs.umich.edu sc_core::sc_time((double)(ticks / SimClock::Int::ps), sc_core::SC_PS); 2715083Sgblack@eecs.umich.edu 2725083Sgblack@eecs.umich.edu // update time 2735083Sgblack@eecs.umich.edu t += delay; 2745083Sgblack@eecs.umich.edu 2755083Sgblack@eecs.umich.edu if (extension == nullptr) 2766345Sgblack@eecs.umich.edu destroyPacket(pkt); 2775083Sgblack@eecs.umich.edu 2785083Sgblack@eecs.umich.edu trans.set_response_status(tlm::TLM_OK_RESPONSE); 2795083Sgblack@eecs.umich.edu} 2805083Sgblack@eecs.umich.edu 2815083Sgblack@eecs.umich.eduunsigned int 2825083Sgblack@eecs.umich.eduTlmToGem5Bridge::transport_dbg(tlm::tlm_generic_payload &trans) 2835083Sgblack@eecs.umich.edu{ 2845083Sgblack@eecs.umich.edu Gem5SystemC::Gem5Extension *extension = nullptr; 2855083Sgblack@eecs.umich.edu trans.get_extension(extension); 2865083Sgblack@eecs.umich.edu 2879010Snilay@cs.wisc.edu // If there is an extension, this transaction was initiated by the gem5 2889010Snilay@cs.wisc.edu // world and we can pipe through the original packet. 2899010Snilay@cs.wisc.edu if (extension != nullptr) { 2909010Snilay@cs.wisc.edu extension->setPipeThrough(); 2919010Snilay@cs.wisc.edu bmp.sendFunctional(extension->getPacket()); 2929010Snilay@cs.wisc.edu } else { 2939010Snilay@cs.wisc.edu auto pkt = generatePacket(trans); 2945083Sgblack@eecs.umich.edu if (pkt) { 2959010Snilay@cs.wisc.edu bmp.sendFunctional(pkt); 2965083Sgblack@eecs.umich.edu destroyPacket(pkt); 2975083Sgblack@eecs.umich.edu } 2985083Sgblack@eecs.umich.edu } 2995083Sgblack@eecs.umich.edu 300 return trans.get_data_length(); 301} 302 303bool 304TlmToGem5Bridge::get_direct_mem_ptr(tlm::tlm_generic_payload &trans, 305 tlm::tlm_dmi &dmi_data) 306{ 307 return false; 308} 309 310bool 311TlmToGem5Bridge::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 357void 358TlmToGem5Bridge::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 376void 377TlmToGem5Bridge::recvRangeChange() 378{ 379 SC_REPORT_WARNING("TlmToGem5Bridge", 380 "received address range change but ignored it"); 381} 382 383::Port & 384TlmToGem5Bridge::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 394TlmToGem5Bridge::TlmToGem5Bridge( 395 Params *params, const sc_core::sc_module_name &mn) : 396 sc_core::sc_module(mn), peq(this, &TlmToGem5Bridge::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 407void 408TlmToGem5Bridge::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( 421 this, &TlmToGem5Bridge::nb_transport_fw); 422 } else if (system->isAtomicMode()) { 423 SC_REPORT_INFO("TlmToGem5Bridge", "register blocking interface"); 424 socket.register_b_transport( 425 this, &TlmToGem5Bridge::b_transport); 426 } else { 427 panic("gem5 operates neither in Timing nor in Atomic mode"); 428 } 429 430 socket.register_transport_dbg(this, &TlmToGem5Bridge::transport_dbg); 431 432 sc_core::sc_module::before_end_of_elaboration(); 433} 434 435} // namespace sc_gem5 436 437sc_gem5::TlmToGem5Bridge * 438TlmToGem5BridgeParams::create() 439{ 440 return new sc_gem5::TlmToGem5Bridge( 441 this, sc_core::sc_module_name(name.c_str())); 442} 443