From 3598bdf09027b2ef3e8c206fac4076266129a285 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Thu, 30 Apr 2020 13:37:08 +0200 Subject: [PATCH] Added support for early completion on initiator side (BEGIN_RESP). --- DRAMSys/library/src/simulation/Arbiter.cpp | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 01234602..b273485d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -88,8 +88,8 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, } else if (phase == END_RESP) { + // TODO: why one additional cycle??? notDelay += Configuration::getInstance().memSpec->tCK; - payload.release(); } PRINTDEBUGMESSAGE(name(), "[fw] " + phaseNameToString(phase) + " notification in " + @@ -138,7 +138,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { // This channel was available. Forward the new transaction to the memory controller. channelIsFree[channelId] = false; - tlm_phase tPhase = phase; + tlm_phase tPhase = BEGIN_REQ; sc_time tDelay = SC_ZERO_TIME; iSocket[channelId]->nb_transport_fw(payload, tPhase, tDelay); // TODO: early completion of channel controller!!! @@ -155,7 +155,7 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) channelIsFree[channelId] = true; // The arbiter receives a transaction which phase is END_REQ from memory controller and forwards it to the requester device. - tlm_phase tPhase = phase; + tlm_phase tPhase = END_REQ; sc_time tDelay = SC_ZERO_TIME; tSocket[threadId]->nb_transport_bw(payload, tPhase, tDelay); @@ -180,10 +180,14 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // device if (pendingResponses[threadId].empty()) { - tlm_phase tPhase = phase; + tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; - tSocket[threadId]->nb_transport_bw(payload, tPhase, tDelay); - // TODO: early completion of initiator!!! + tlm_sync_enum returnValue = tSocket[threadId]->nb_transport_bw(payload, tPhase, tDelay); + if (returnValue != TLM_ACCEPTED) + { + tPhase = END_RESP; + payloadEventQueue.notify(payload, tPhase, tDelay); + } } // Enqueue the transaction in BEGIN_RESP phase until the initiator @@ -194,12 +198,13 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) { // Send the END_RESP message to the memory { - tlm_phase tPhase = phase; + tlm_phase tPhase = END_RESP; sc_time tDelay = SC_ZERO_TIME; iSocket[channelId]->nb_transport_fw(payload, tPhase, tDelay); } // Drop one element of the queue of BEGIN_RESP from memory to this device pendingResponses[threadId].pop(); + payload.release(); // Check if there are queued transactoins with phase BEGIN_RESP from memory to this device if (!pendingResponses[threadId].empty()) @@ -209,8 +214,12 @@ void Arbiter::peqCallback(tlm_generic_payload &payload, const tlm_phase &phase) // Send ONE extra BEGIN_RESP to the device tlm_phase tPhase = BEGIN_RESP; sc_time tDelay = SC_ZERO_TIME; - tSocket[threadId]->nb_transport_bw(payloadToSend, tPhase, tDelay); - // TODO: early completion of initiator!!! + tlm_sync_enum returnValue = tSocket[threadId]->nb_transport_bw(payloadToSend, tPhase, tDelay); + if (returnValue != TLM_ACCEPTED) + { + tPhase = END_RESP; + payloadEventQueue.notify(payloadToSend, tPhase, tDelay); + } } } else