112047Schristian.menard@tu-dresden.de/* 212047Schristian.menard@tu-dresden.de * Copyright (c) 2015, University of Kaiserslautern 312047Schristian.menard@tu-dresden.de * Copyright (c) 2016, Dresden University of Technology (TU Dresden) 412047Schristian.menard@tu-dresden.de * All rights reserved. 512047Schristian.menard@tu-dresden.de * 612047Schristian.menard@tu-dresden.de * Redistribution and use in source and binary forms, with or without 712047Schristian.menard@tu-dresden.de * modification, are permitted provided that the following conditions are 812047Schristian.menard@tu-dresden.de * met: 912047Schristian.menard@tu-dresden.de * 1012047Schristian.menard@tu-dresden.de * 1. Redistributions of source code must retain the above copyright notice, 1112047Schristian.menard@tu-dresden.de * this list of conditions and the following disclaimer. 1212047Schristian.menard@tu-dresden.de * 1312047Schristian.menard@tu-dresden.de * 2. Redistributions in binary form must reproduce the above copyright 1412047Schristian.menard@tu-dresden.de * notice, this list of conditions and the following disclaimer in the 1512047Schristian.menard@tu-dresden.de * documentation and/or other materials provided with the distribution. 1612047Schristian.menard@tu-dresden.de * 1712047Schristian.menard@tu-dresden.de * 3. Neither the name of the copyright holder nor the names of its 1812047Schristian.menard@tu-dresden.de * contributors may be used to endorse or promote products derived from 1912047Schristian.menard@tu-dresden.de * this software without specific prior written permission. 2012047Schristian.menard@tu-dresden.de * 2112047Schristian.menard@tu-dresden.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2212047Schristian.menard@tu-dresden.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2312047Schristian.menard@tu-dresden.de * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2412047Schristian.menard@tu-dresden.de * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 2512047Schristian.menard@tu-dresden.de * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2612047Schristian.menard@tu-dresden.de * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2712047Schristian.menard@tu-dresden.de * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2812047Schristian.menard@tu-dresden.de * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2912047Schristian.menard@tu-dresden.de * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3012047Schristian.menard@tu-dresden.de * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3112047Schristian.menard@tu-dresden.de * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3212047Schristian.menard@tu-dresden.de * 3312047Schristian.menard@tu-dresden.de * Authors: Matthias Jung 3412047Schristian.menard@tu-dresden.de * Abdul Mutaal Ahmad 3512047Schristian.menard@tu-dresden.de * Christian Menard 3612047Schristian.menard@tu-dresden.de */ 3712047Schristian.menard@tu-dresden.de 3812047Schristian.menard@tu-dresden.de#include "sc_ext.hh" 3912047Schristian.menard@tu-dresden.de#include "sc_mm.hh" 4012047Schristian.menard@tu-dresden.de#include "sc_slave_port.hh" 4112047Schristian.menard@tu-dresden.de#include "slave_transactor.hh" 4212047Schristian.menard@tu-dresden.de 4312047Schristian.menard@tu-dresden.denamespace Gem5SystemC 4412047Schristian.menard@tu-dresden.de{ 4512047Schristian.menard@tu-dresden.de 4612047Schristian.menard@tu-dresden.de/** 4712047Schristian.menard@tu-dresden.de * Instantiate a tlm memory manager that takes care about all the 4812047Schristian.menard@tu-dresden.de * tlm transactions in the system 4912047Schristian.menard@tu-dresden.de */ 5012047Schristian.menard@tu-dresden.deMemoryManager mm; 5112047Schristian.menard@tu-dresden.de 5212047Schristian.menard@tu-dresden.de/** 5312047Schristian.menard@tu-dresden.de * Convert a gem5 packet to a TLM payload by copying all the relevant 5412047Schristian.menard@tu-dresden.de * information to a previously allocated tlm payload 5512047Schristian.menard@tu-dresden.de */ 5612047Schristian.menard@tu-dresden.devoid 5712047Schristian.menard@tu-dresden.depacket2payload(PacketPtr packet, tlm::tlm_generic_payload &trans) 5812047Schristian.menard@tu-dresden.de{ 5912047Schristian.menard@tu-dresden.de trans.set_address(packet->getAddr()); 6012047Schristian.menard@tu-dresden.de 6112047Schristian.menard@tu-dresden.de /* Check if this transaction was allocated by mm */ 6212047Schristian.menard@tu-dresden.de sc_assert(trans.has_mm()); 6312047Schristian.menard@tu-dresden.de 6412047Schristian.menard@tu-dresden.de unsigned int size = packet->getSize(); 6512047Schristian.menard@tu-dresden.de unsigned char *data = packet->getPtr<unsigned char>(); 6612047Schristian.menard@tu-dresden.de 6712047Schristian.menard@tu-dresden.de trans.set_data_length(size); 6812047Schristian.menard@tu-dresden.de trans.set_streaming_width(size); 6912047Schristian.menard@tu-dresden.de trans.set_data_ptr(data); 7012047Schristian.menard@tu-dresden.de 7112047Schristian.menard@tu-dresden.de if (packet->isRead()) { 7212047Schristian.menard@tu-dresden.de trans.set_command(tlm::TLM_READ_COMMAND); 7312047Schristian.menard@tu-dresden.de } 7412047Schristian.menard@tu-dresden.de else if (packet->isInvalidate()) { 7512047Schristian.menard@tu-dresden.de /* Do nothing */ 7612047Schristian.menard@tu-dresden.de } else if (packet->isWrite()) { 7712047Schristian.menard@tu-dresden.de trans.set_command(tlm::TLM_WRITE_COMMAND); 7812047Schristian.menard@tu-dresden.de } else { 7912047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort", "No R/W packet"); 8012047Schristian.menard@tu-dresden.de } 8112047Schristian.menard@tu-dresden.de} 8212047Schristian.menard@tu-dresden.de 8312047Schristian.menard@tu-dresden.de/** 8412047Schristian.menard@tu-dresden.de * Similar to TLM's blocking transport (LT) 8512047Schristian.menard@tu-dresden.de */ 8612047Schristian.menard@tu-dresden.deTick 8712047Schristian.menard@tu-dresden.deSCSlavePort::recvAtomic(PacketPtr packet) 8812047Schristian.menard@tu-dresden.de{ 8912047Schristian.menard@tu-dresden.de CAUGHT_UP; 9012047Schristian.menard@tu-dresden.de SC_REPORT_INFO("SCSlavePort", "recvAtomic hasn't been tested much"); 9112047Schristian.menard@tu-dresden.de 9212047Schristian.menard@tu-dresden.de panic_if(packet->cacheResponding(), "Should not see packets where cache " 9312047Schristian.menard@tu-dresden.de "is responding"); 9412047Schristian.menard@tu-dresden.de 9512047Schristian.menard@tu-dresden.de panic_if(!(packet->isRead() || packet->isWrite()), 9612047Schristian.menard@tu-dresden.de "Should only see read and writes at TLM memory\n"); 9712047Schristian.menard@tu-dresden.de 9812047Schristian.menard@tu-dresden.de 9912047Schristian.menard@tu-dresden.de sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 10012047Schristian.menard@tu-dresden.de 10112047Schristian.menard@tu-dresden.de 10212047Schristian.menard@tu-dresden.de /* Prepare the transaction */ 10312047Schristian.menard@tu-dresden.de tlm::tlm_generic_payload * trans = mm.allocate(); 10412047Schristian.menard@tu-dresden.de trans->acquire(); 10512047Schristian.menard@tu-dresden.de packet2payload(packet, *trans); 10612047Schristian.menard@tu-dresden.de 10712047Schristian.menard@tu-dresden.de /* Attach the packet pointer to the TLM transaction to keep track */ 10812047Schristian.menard@tu-dresden.de Gem5Extension* extension = new Gem5Extension(packet); 10912047Schristian.menard@tu-dresden.de trans->set_auto_extension(extension); 11012047Schristian.menard@tu-dresden.de 11112047Schristian.menard@tu-dresden.de /* Execute b_transport: */ 11212047Schristian.menard@tu-dresden.de if (packet->cmd == MemCmd::SwapReq) { 11312047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort", "SwapReq not supported"); 11412047Schristian.menard@tu-dresden.de } else if (packet->isRead()) { 11512047Schristian.menard@tu-dresden.de transactor->socket->b_transport(*trans, delay); 11612047Schristian.menard@tu-dresden.de } else if (packet->isInvalidate()) { 11712047Schristian.menard@tu-dresden.de // do nothing 11812047Schristian.menard@tu-dresden.de } else if (packet->isWrite()) { 11912047Schristian.menard@tu-dresden.de transactor->socket->b_transport(*trans, delay); 12012047Schristian.menard@tu-dresden.de } else { 12112047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort", "Typo of request not supported"); 12212047Schristian.menard@tu-dresden.de } 12312047Schristian.menard@tu-dresden.de 12412047Schristian.menard@tu-dresden.de if (packet->needsResponse()) { 12512047Schristian.menard@tu-dresden.de packet->makeResponse(); 12612047Schristian.menard@tu-dresden.de } 12712047Schristian.menard@tu-dresden.de 12812047Schristian.menard@tu-dresden.de trans->release(); 12912047Schristian.menard@tu-dresden.de 13012047Schristian.menard@tu-dresden.de return delay.value(); 13112047Schristian.menard@tu-dresden.de} 13212047Schristian.menard@tu-dresden.de 13312047Schristian.menard@tu-dresden.de/** 13412047Schristian.menard@tu-dresden.de * Similar to TLM's debug transport 13512047Schristian.menard@tu-dresden.de */ 13612047Schristian.menard@tu-dresden.devoid 13712047Schristian.menard@tu-dresden.deSCSlavePort::recvFunctional(PacketPtr packet) 13812047Schristian.menard@tu-dresden.de{ 13912047Schristian.menard@tu-dresden.de /* Prepare the transaction */ 14012047Schristian.menard@tu-dresden.de tlm::tlm_generic_payload * trans = mm.allocate(); 14112047Schristian.menard@tu-dresden.de trans->acquire(); 14212047Schristian.menard@tu-dresden.de packet2payload(packet, *trans); 14312047Schristian.menard@tu-dresden.de 14412047Schristian.menard@tu-dresden.de /* Attach the packet pointer to the TLM transaction to keep track */ 14512047Schristian.menard@tu-dresden.de Gem5Extension* extension = new Gem5Extension(packet); 14612047Schristian.menard@tu-dresden.de trans->set_auto_extension(extension); 14712047Schristian.menard@tu-dresden.de 14812047Schristian.menard@tu-dresden.de /* Execute Debug Transport: */ 14912047Schristian.menard@tu-dresden.de unsigned int bytes = transactor->socket->transport_dbg(*trans); 15012047Schristian.menard@tu-dresden.de if (bytes != trans->get_data_length()) { 15112047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort","debug transport was not completed"); 15212047Schristian.menard@tu-dresden.de } 15312047Schristian.menard@tu-dresden.de 15412047Schristian.menard@tu-dresden.de trans->release(); 15512047Schristian.menard@tu-dresden.de} 15612047Schristian.menard@tu-dresden.de 15712047Schristian.menard@tu-dresden.debool 15812047Schristian.menard@tu-dresden.deSCSlavePort::recvTimingSnoopResp(PacketPtr packet) 15912047Schristian.menard@tu-dresden.de{ 16012047Schristian.menard@tu-dresden.de /* Snooping should be implemented with tlm_dbg_transport */ 16112047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvTimingSnoopResp"); 16212047Schristian.menard@tu-dresden.de return false; 16312047Schristian.menard@tu-dresden.de} 16412047Schristian.menard@tu-dresden.de 16512047Schristian.menard@tu-dresden.devoid 16612047Schristian.menard@tu-dresden.deSCSlavePort::recvFunctionalSnoop(PacketPtr packet) 16712047Schristian.menard@tu-dresden.de{ 16812047Schristian.menard@tu-dresden.de /* Snooping should be implemented with tlm_dbg_transport */ 16912047Schristian.menard@tu-dresden.de SC_REPORT_FATAL("SCSlavePort","unimplemented func.: recvFunctionalSnoop"); 17012047Schristian.menard@tu-dresden.de} 17112047Schristian.menard@tu-dresden.de 17212047Schristian.menard@tu-dresden.de/** 17312047Schristian.menard@tu-dresden.de * Similar to TLM's non-blocking transport (AT) 17412047Schristian.menard@tu-dresden.de */ 17512047Schristian.menard@tu-dresden.debool 17612047Schristian.menard@tu-dresden.deSCSlavePort::recvTimingReq(PacketPtr packet) 17712047Schristian.menard@tu-dresden.de{ 17812047Schristian.menard@tu-dresden.de CAUGHT_UP; 17912047Schristian.menard@tu-dresden.de 18012047Schristian.menard@tu-dresden.de panic_if(packet->cacheResponding(), "Should not see packets where cache " 18112047Schristian.menard@tu-dresden.de "is responding"); 18212047Schristian.menard@tu-dresden.de 18312047Schristian.menard@tu-dresden.de panic_if(!(packet->isRead() || packet->isWrite()), 18412047Schristian.menard@tu-dresden.de "Should only see read and writes at TLM memory\n"); 18512047Schristian.menard@tu-dresden.de 18612047Schristian.menard@tu-dresden.de 18712047Schristian.menard@tu-dresden.de /* We should never get a second request after noting that a retry is 18812047Schristian.menard@tu-dresden.de * required */ 18912047Schristian.menard@tu-dresden.de sc_assert(!needToSendRequestRetry); 19012047Schristian.menard@tu-dresden.de 19112047Schristian.menard@tu-dresden.de /* Remember if a request comes in while we're blocked so that a retry 19212047Schristian.menard@tu-dresden.de * can be sent to gem5 */ 19312047Schristian.menard@tu-dresden.de if (blockingRequest) { 19412047Schristian.menard@tu-dresden.de needToSendRequestRetry = true; 19512047Schristian.menard@tu-dresden.de return false; 19612047Schristian.menard@tu-dresden.de } 19712047Schristian.menard@tu-dresden.de 19812047Schristian.menard@tu-dresden.de /* NOTE: normal tlm is blocking here. But in our case we return false 19912047Schristian.menard@tu-dresden.de * and tell gem5 when a retry can be done. This is the main difference 20012047Schristian.menard@tu-dresden.de * in the protocol: 20112047Schristian.menard@tu-dresden.de * if (requestInProgress) 20212047Schristian.menard@tu-dresden.de * { 20312047Schristian.menard@tu-dresden.de * wait(endRequestEvent); 20412047Schristian.menard@tu-dresden.de * } 20512047Schristian.menard@tu-dresden.de * requestInProgress = trans; 20612047Schristian.menard@tu-dresden.de */ 20712047Schristian.menard@tu-dresden.de 20812047Schristian.menard@tu-dresden.de /* Prepare the transaction */ 20912047Schristian.menard@tu-dresden.de tlm::tlm_generic_payload * trans = mm.allocate(); 21012047Schristian.menard@tu-dresden.de trans->acquire(); 21112047Schristian.menard@tu-dresden.de packet2payload(packet, *trans); 21212047Schristian.menard@tu-dresden.de 21312047Schristian.menard@tu-dresden.de /* Attach the packet pointer to the TLM transaction to keep track */ 21412047Schristian.menard@tu-dresden.de Gem5Extension* extension = new Gem5Extension(packet); 21512047Schristian.menard@tu-dresden.de trans->set_auto_extension(extension); 21612047Schristian.menard@tu-dresden.de 21712047Schristian.menard@tu-dresden.de /* 21812047Schristian.menard@tu-dresden.de * Pay for annotated transport delays. 21912047Schristian.menard@tu-dresden.de * 22012047Schristian.menard@tu-dresden.de * The header delay marks the point in time, when the packet first is seen 22112047Schristian.menard@tu-dresden.de * by the transactor. This is the point int time, when the transactor needs 22212047Schristian.menard@tu-dresden.de * to send the BEGIN_REQ to the SystemC world. 22312047Schristian.menard@tu-dresden.de * 22412047Schristian.menard@tu-dresden.de * NOTE: We drop the payload delay here. Normally, the receiver would be 22512047Schristian.menard@tu-dresden.de * responsible for handling the payload delay. In this case, however, 22612047Schristian.menard@tu-dresden.de * the receiver is a SystemC module and has no notion of the gem5 22712047Schristian.menard@tu-dresden.de * transport protocol and we cannot simply forward the 22812047Schristian.menard@tu-dresden.de * payload delay to the receiving module. Instead, we expect the 22912047Schristian.menard@tu-dresden.de * receiving SystemC module to model the payload delay by deferring 23012047Schristian.menard@tu-dresden.de * the END_REQ. This could lead to incorrect delays, if the XBar 23112047Schristian.menard@tu-dresden.de * payload delay is longer than the time the receiver needs to accept 23212047Schristian.menard@tu-dresden.de * the request (time between BEGIN_REQ and END_REQ). 23312047Schristian.menard@tu-dresden.de * 23412047Schristian.menard@tu-dresden.de * TODO: We could detect the case described above by remembering the 23512047Schristian.menard@tu-dresden.de * payload delay and comparing it to the time between BEGIN_REQ and 23612047Schristian.menard@tu-dresden.de * END_REQ. Then, a warning should be printed. 23712047Schristian.menard@tu-dresden.de */ 23812047Schristian.menard@tu-dresden.de auto delay = sc_core::sc_time::from_value(packet->payloadDelay); 23912047Schristian.menard@tu-dresden.de // reset the delays 24012047Schristian.menard@tu-dresden.de packet->payloadDelay = 0; 24112047Schristian.menard@tu-dresden.de packet->headerDelay = 0; 24212047Schristian.menard@tu-dresden.de 24312047Schristian.menard@tu-dresden.de /* Starting TLM non-blocking sequence (AT) Refer to IEEE1666-2011 SystemC 24412047Schristian.menard@tu-dresden.de * Standard Page 507 for a visualisation of the procedure */ 24512047Schristian.menard@tu-dresden.de tlm::tlm_phase phase = tlm::BEGIN_REQ; 24612047Schristian.menard@tu-dresden.de tlm::tlm_sync_enum status; 24712047Schristian.menard@tu-dresden.de status = transactor->socket->nb_transport_fw(*trans, phase, delay); 24812047Schristian.menard@tu-dresden.de /* Check returned value: */ 24912047Schristian.menard@tu-dresden.de if (status == tlm::TLM_ACCEPTED) { 25012047Schristian.menard@tu-dresden.de sc_assert(phase == tlm::BEGIN_REQ); 25112047Schristian.menard@tu-dresden.de /* Accepted but is now blocking until END_REQ (exclusion rule)*/ 25212047Schristian.menard@tu-dresden.de blockingRequest = trans; 25312047Schristian.menard@tu-dresden.de } else if (status == tlm::TLM_UPDATED) { 25412047Schristian.menard@tu-dresden.de /* The Timing annotation must be honored: */ 25512047Schristian.menard@tu-dresden.de sc_assert(phase == tlm::END_REQ || phase == tlm::BEGIN_RESP); 25612047Schristian.menard@tu-dresden.de 25712047Schristian.menard@tu-dresden.de PayloadEvent<SCSlavePort> * pe; 25812047Schristian.menard@tu-dresden.de pe = new PayloadEvent<SCSlavePort>(*this, 25912047Schristian.menard@tu-dresden.de &SCSlavePort::pec, "PEQ"); 26012047Schristian.menard@tu-dresden.de pe->notify(*trans, phase, delay); 26112047Schristian.menard@tu-dresden.de } else if (status == tlm::TLM_COMPLETED) { 26212047Schristian.menard@tu-dresden.de /* Transaction is over nothing has do be done. */ 26312047Schristian.menard@tu-dresden.de sc_assert(phase == tlm::END_RESP); 26412047Schristian.menard@tu-dresden.de trans->release(); 26512047Schristian.menard@tu-dresden.de } 26612047Schristian.menard@tu-dresden.de 26712047Schristian.menard@tu-dresden.de return true; 26812047Schristian.menard@tu-dresden.de} 26912047Schristian.menard@tu-dresden.de 27012047Schristian.menard@tu-dresden.devoid 27112047Schristian.menard@tu-dresden.deSCSlavePort::pec( 27212047Schristian.menard@tu-dresden.de PayloadEvent<SCSlavePort> * pe, 27312047Schristian.menard@tu-dresden.de tlm::tlm_generic_payload& trans, 27412047Schristian.menard@tu-dresden.de const tlm::tlm_phase& phase) 27512047Schristian.menard@tu-dresden.de{ 27612047Schristian.menard@tu-dresden.de sc_time delay; 27712047Schristian.menard@tu-dresden.de 27812047Schristian.menard@tu-dresden.de if (phase == tlm::END_REQ || 27912047Schristian.menard@tu-dresden.de &trans == blockingRequest && phase == tlm::BEGIN_RESP) { 28012047Schristian.menard@tu-dresden.de sc_assert(&trans == blockingRequest); 28112047Schristian.menard@tu-dresden.de blockingRequest = NULL; 28212047Schristian.menard@tu-dresden.de 28312047Schristian.menard@tu-dresden.de /* Did another request arrive while blocked, schedule a retry */ 28412047Schristian.menard@tu-dresden.de if (needToSendRequestRetry) { 28512047Schristian.menard@tu-dresden.de needToSendRequestRetry = false; 28612047Schristian.menard@tu-dresden.de sendRetryReq(); 28712047Schristian.menard@tu-dresden.de } 28812047Schristian.menard@tu-dresden.de } 28912047Schristian.menard@tu-dresden.de if (phase == tlm::BEGIN_RESP) 29012047Schristian.menard@tu-dresden.de { 29112047Schristian.menard@tu-dresden.de CAUGHT_UP; 29212047Schristian.menard@tu-dresden.de 29312047Schristian.menard@tu-dresden.de auto& extension = Gem5Extension::getExtension(trans); 29412047Schristian.menard@tu-dresden.de auto packet = extension.getPacket(); 29512047Schristian.menard@tu-dresden.de 29612047Schristian.menard@tu-dresden.de sc_assert(!blockingResponse); 29712047Schristian.menard@tu-dresden.de 29812047Schristian.menard@tu-dresden.de bool need_retry = false; 29912047Schristian.menard@tu-dresden.de 30012047Schristian.menard@tu-dresden.de /* 30112047Schristian.menard@tu-dresden.de * If the packet was piped through and needs a response, we don't need 30212047Schristian.menard@tu-dresden.de * to touch the packet and can forward it directly as a response. 30312047Schristian.menard@tu-dresden.de * Otherwise, we need to make a response and send the transformed 30412047Schristian.menard@tu-dresden.de * packet. 30512047Schristian.menard@tu-dresden.de */ 30612047Schristian.menard@tu-dresden.de if (extension.isPipeThrough()) { 30712047Schristian.menard@tu-dresden.de if (packet->isResponse()) { 30812047Schristian.menard@tu-dresden.de need_retry = !sendTimingResp(packet); 30912047Schristian.menard@tu-dresden.de } 31012047Schristian.menard@tu-dresden.de } else if (packet->needsResponse()) { 31112047Schristian.menard@tu-dresden.de packet->makeResponse(); 31212047Schristian.menard@tu-dresden.de need_retry = !sendTimingResp(packet); 31312047Schristian.menard@tu-dresden.de } 31412047Schristian.menard@tu-dresden.de 31512047Schristian.menard@tu-dresden.de if (need_retry) { 31612047Schristian.menard@tu-dresden.de blockingResponse = &trans; 31712047Schristian.menard@tu-dresden.de } else { 31812047Schristian.menard@tu-dresden.de if (phase == tlm::BEGIN_RESP) { 31912047Schristian.menard@tu-dresden.de /* Send END_RESP and we're finished: */ 32012047Schristian.menard@tu-dresden.de tlm::tlm_phase fw_phase = tlm::END_RESP; 32112047Schristian.menard@tu-dresden.de sc_time delay = SC_ZERO_TIME; 32212047Schristian.menard@tu-dresden.de transactor->socket->nb_transport_fw(trans, fw_phase, delay); 32312047Schristian.menard@tu-dresden.de /* Release the transaction with all the extensions */ 32412047Schristian.menard@tu-dresden.de trans.release(); 32512047Schristian.menard@tu-dresden.de } 32612047Schristian.menard@tu-dresden.de } 32712047Schristian.menard@tu-dresden.de } 32812047Schristian.menard@tu-dresden.de delete pe; 32912047Schristian.menard@tu-dresden.de} 33012047Schristian.menard@tu-dresden.de 33112047Schristian.menard@tu-dresden.devoid 33212047Schristian.menard@tu-dresden.deSCSlavePort::recvRespRetry() 33312047Schristian.menard@tu-dresden.de{ 33412047Schristian.menard@tu-dresden.de CAUGHT_UP; 33512047Schristian.menard@tu-dresden.de 33612047Schristian.menard@tu-dresden.de /* Retry a response */ 33712047Schristian.menard@tu-dresden.de sc_assert(blockingResponse); 33812047Schristian.menard@tu-dresden.de 33912047Schristian.menard@tu-dresden.de tlm::tlm_generic_payload *trans = blockingResponse; 34012047Schristian.menard@tu-dresden.de blockingResponse = NULL; 34112047Schristian.menard@tu-dresden.de PacketPtr packet = Gem5Extension::getExtension(trans).getPacket(); 34212047Schristian.menard@tu-dresden.de 34312047Schristian.menard@tu-dresden.de bool need_retry = !sendTimingResp(packet); 34412047Schristian.menard@tu-dresden.de 34512047Schristian.menard@tu-dresden.de sc_assert(!need_retry); 34612047Schristian.menard@tu-dresden.de 34712047Schristian.menard@tu-dresden.de sc_core::sc_time delay = sc_core::SC_ZERO_TIME; 34812047Schristian.menard@tu-dresden.de tlm::tlm_phase phase = tlm::END_RESP; 34912047Schristian.menard@tu-dresden.de transactor->socket->nb_transport_fw(*trans, phase, delay); 35012047Schristian.menard@tu-dresden.de // Release transaction with all the extensions 35112047Schristian.menard@tu-dresden.de trans->release(); 35212047Schristian.menard@tu-dresden.de} 35312047Schristian.menard@tu-dresden.de 35412047Schristian.menard@tu-dresden.detlm::tlm_sync_enum 35512047Schristian.menard@tu-dresden.deSCSlavePort::nb_transport_bw(tlm::tlm_generic_payload& trans, 35612047Schristian.menard@tu-dresden.de tlm::tlm_phase& phase, 35712047Schristian.menard@tu-dresden.de sc_core::sc_time& delay) 35812047Schristian.menard@tu-dresden.de{ 35912047Schristian.menard@tu-dresden.de PayloadEvent<SCSlavePort> * pe; 36012047Schristian.menard@tu-dresden.de pe = new PayloadEvent<SCSlavePort>(*this, &SCSlavePort::pec, "PE"); 36112047Schristian.menard@tu-dresden.de pe->notify(trans, phase, delay); 36212047Schristian.menard@tu-dresden.de return tlm::TLM_ACCEPTED; 36312047Schristian.menard@tu-dresden.de} 36412047Schristian.menard@tu-dresden.de 36512047Schristian.menard@tu-dresden.deSCSlavePort::SCSlavePort(const std::string &name_, 36612047Schristian.menard@tu-dresden.de const std::string &systemc_name, 36712047Schristian.menard@tu-dresden.de ExternalSlave &owner_) : 36812047Schristian.menard@tu-dresden.de ExternalSlave::Port(name_, owner_), 36912047Schristian.menard@tu-dresden.de blockingRequest(NULL), 37012047Schristian.menard@tu-dresden.de needToSendRequestRetry(false), 37112047Schristian.menard@tu-dresden.de blockingResponse(NULL), 37212047Schristian.menard@tu-dresden.de transactor(nullptr) 37312047Schristian.menard@tu-dresden.de{ 37412047Schristian.menard@tu-dresden.de} 37512047Schristian.menard@tu-dresden.de 37612047Schristian.menard@tu-dresden.devoid 37712047Schristian.menard@tu-dresden.deSCSlavePort::bindToTransactor(Gem5SlaveTransactor* transactor) 37812047Schristian.menard@tu-dresden.de{ 37912047Schristian.menard@tu-dresden.de sc_assert(this->transactor == nullptr); 38012047Schristian.menard@tu-dresden.de 38112047Schristian.menard@tu-dresden.de this->transactor = transactor; 38212047Schristian.menard@tu-dresden.de 38312047Schristian.menard@tu-dresden.de transactor->socket.register_nb_transport_bw(this, 38412047Schristian.menard@tu-dresden.de &SCSlavePort::nb_transport_bw); 38512047Schristian.menard@tu-dresden.de} 38612047Schristian.menard@tu-dresden.de 38712047Schristian.menard@tu-dresden.deExternalSlave::Port* 38812047Schristian.menard@tu-dresden.deSCSlavePortHandler::getExternalPort(const std::string &name, 38912047Schristian.menard@tu-dresden.de ExternalSlave &owner, 39012047Schristian.menard@tu-dresden.de const std::string &port_data) 39112047Schristian.menard@tu-dresden.de{ 39212047Schristian.menard@tu-dresden.de // Create and register a new SystemC slave port 39312047Schristian.menard@tu-dresden.de auto* port = new SCSlavePort(name, port_data, owner); 39412047Schristian.menard@tu-dresden.de 39512047Schristian.menard@tu-dresden.de control.registerSlavePort(port_data, port); 39612047Schristian.menard@tu-dresden.de 39712047Schristian.menard@tu-dresden.de return port; 39812047Schristian.menard@tu-dresden.de} 39912047Schristian.menard@tu-dresden.de 40012047Schristian.menard@tu-dresden.de} 401