diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 98cd8fe9..b90a7ea1 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -103,6 +103,9 @@ void ArbiterFifo::end_of_elaboration() for (unsigned i = 0; i < tSocket.size(); i++) // initiator side pendingResponses.push_back(std::queue()); + + lastEndReq = std::vector(iSocket.size(), sc_max_time()); + lastEndResp = std::vector(tSocket.size(), sc_max_time()); } void ArbiterReorder::end_of_elaboration() @@ -114,6 +117,9 @@ void ArbiterReorder::end_of_elaboration() pendingResponses.push_back(std::set()); nextThreadPayloadIDToReturn.push_back(0); } + + lastEndReq = std::vector(iSocket.size(), sc_max_time()); + lastEndResp = std::vector(tSocket.size(), sc_max_time()); } tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload &payload, @@ -277,14 +283,15 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c tlm_generic_payload *tPayload = pendingRequests[channelId].front(); pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; - // TODO: what if END_REQ was in the same cycle? - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = lastEndReq[channelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; iSocket[static_cast(channelId)]->nb_transport_fw(*tPayload, tPhase, tDelay); } } else if (cbPhase == END_REQ) // from memory controller { + lastEndReq[channelId] = sc_time_stamp(); + if (!pendingRequests[channelId].empty()) { tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); @@ -316,8 +323,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c tlm_generic_payload *tPayload = pendingResponses[threadId].front(); pendingResponses[threadId].pop(); tlm_phase tPhase = BEGIN_RESP; - // TODO: what if one BEGIN_RESP has already been sent in this cycle? - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = lastEndResp[threadId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) @@ -326,6 +332,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c } else if (cbPhase == END_RESP) // from initiator { + lastEndResp[threadId] = sc_time_stamp(); cbPayload.release(); activeTransactions[threadId]--; @@ -389,14 +396,15 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase tlm_generic_payload *tPayload = pendingRequests[channelId].front(); pendingRequests[channelId].pop(); tlm_phase tPhase = BEGIN_REQ; - // TODO: what if END_REQ was in the same cycle? - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = lastEndReq[channelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; iSocket[static_cast(channelId)]->nb_transport_fw(*tPayload, tPhase, tDelay); } } else if (cbPhase == END_REQ) // from memory controller { + lastEndReq[channelId] = sc_time_stamp(); + if (!pendingRequests[channelId].empty()) { tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); @@ -432,8 +440,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase threadIsBusy[threadId] = true; tlm_phase tPhase = BEGIN_RESP; - // TODO: what if one BEGIN_RESP has already been sent in this cycle? - sc_time tDelay = SC_ZERO_TIME; + sc_time tDelay = lastEndResp[threadId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; tlm_sync_enum returnValue = tSocket[static_cast(threadId)]->nb_transport_bw(*tPayload, tPhase, tDelay); if (returnValue == TLM_UPDATED) @@ -443,6 +450,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase } else if (cbPhase == END_RESP) // from initiator { + lastEndResp[threadId] = sc_time_stamp(); cbPayload.release(); activeTransactions[threadId]--; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 46540dc9..4554d49a 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -116,6 +116,9 @@ private: virtual void end_of_elaboration() override; virtual void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase) override; std::vector> pendingResponses; + + std::vector lastEndReq; + std::vector lastEndResp; }; class ArbiterReorder final : public Arbiter @@ -137,6 +140,9 @@ private: }; std::vector> pendingResponses; + std::vector lastEndReq; + std::vector lastEndResp; + std::vector nextThreadPayloadIDToReturn; };