From 7253b348008d4a70a062f7c244a0a2471db00913 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 2 Jul 2021 14:37:47 +0200 Subject: [PATCH] Fix arbitration delays in FIFO arbiter. --- DRAMSys/library/src/simulation/Arbiter.cpp | 115 ++++++++++++++------- DRAMSys/library/src/simulation/Arbiter.h | 3 + 2 files changed, 82 insertions(+), 36 deletions(-) diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index e4f0c515..703840f4 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -280,22 +280,25 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c tSocket[static_cast(threadId)]->nb_transport_bw(cbPayload, tPhase, tDelay); - pendingRequests[channelId].push(&cbPayload); + // TODO: move to REQ_ARBITRATION PEQ + payloadEventQueue.notify(cbPayload, REQ_ARBITRATION, arbitrationDelayFw); + //pendingRequests[channelId].push(&cbPayload); } else outstandingEndReq[threadId] = &cbPayload; - if (!channelIsBusy[channelId] && !pendingRequests[channelId].empty()) - { - channelIsBusy[channelId] = true; - - tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); - pendingRequests[channelId].pop(); - tlm_phase tPhase = BEGIN_REQ; - sc_time tDelay = lastEndReq[channelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; - - iSocket[static_cast(channelId)]->nb_transport_fw(tPayload, tPhase, tDelay); - } + // TODO: move to REQ_ARBITRATION +// if (!channelIsBusy[channelId] && !pendingRequests[channelId].empty()) +// { +// channelIsBusy[channelId] = true; +// +// tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); +// pendingRequests[channelId].pop(); +// tlm_phase tPhase = BEGIN_REQ; +// 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 { @@ -323,21 +326,23 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c iSocket[static_cast(channelId)]->nb_transport_fw(cbPayload, tPhase, tDelay); } - pendingResponses[threadId].push(&cbPayload); + // TODO: move to PEQ with RESP_ARBITRATION + payloadEventQueue.notify(cbPayload, RESP_ARBITRATION, arbitrationDelayBw); + //pendingResponses[threadId].push(&cbPayload); - if (!threadIsBusy[threadId]) - { - threadIsBusy[threadId] = true; - - tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); - pendingResponses[threadId].pop(); - tlm_phase tPhase = BEGIN_RESP; - 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) - payloadEventQueue.notify(tPayload, tPhase, tDelay); - } +// if (!threadIsBusy[threadId]) +// { +// threadIsBusy[threadId] = true; +// +// tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); +// pendingResponses[threadId].pop(); +// tlm_phase tPhase = BEGIN_RESP; +// 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) +// payloadEventQueue.notify(tPayload, tPhase, tDelay); +// } } else if (cbPhase == END_RESP) // from initiator { @@ -358,17 +363,20 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c tSocket[static_cast(threadId)]->nb_transport_bw(tPayload, tPhase, tDelay); - if (!channelIsBusy[tChannelId]) - { - channelIsBusy[tChannelId] = true; + // TODO: move into REQ_ARBITRATION PEQ + payloadEventQueue.notify(tPayload, REQ_ARBITRATION, arbitrationDelayFw); - tPhase = BEGIN_REQ; - tDelay = lastEndReq[tChannelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; - - iSocket[static_cast(tChannelId)]->nb_transport_fw(tPayload, tPhase, tDelay); - } - else - pendingRequests[tChannelId].push(&tPayload); +// if (!channelIsBusy[tChannelId]) +// { +// channelIsBusy[tChannelId] = true; +// +// tPhase = BEGIN_REQ; +// tDelay = lastEndReq[tChannelId] == sc_time_stamp() ? tCK : SC_ZERO_TIME; +// +// iSocket[static_cast(tChannelId)]->nb_transport_fw(tPayload, tPhase, tDelay); +// } +// else +// pendingRequests[tChannelId].push(&tPayload); } else activeTransactions[threadId]--; @@ -387,6 +395,41 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c else threadIsBusy[threadId] = false; } + else if (cbPhase == REQ_ARBITRATION) + { + pendingRequests[channelId].push(&cbPayload); + + if (!channelIsBusy[channelId]) + { + channelIsBusy[channelId] = true; + + tlm_generic_payload &tPayload = *pendingRequests[channelId].front(); + pendingRequests[channelId].pop(); + tlm_phase tPhase = BEGIN_REQ; + 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 == RESP_ARBITRATION) + { + pendingResponses[threadId].push(&cbPayload); + + if (!threadIsBusy[threadId]) + { + threadIsBusy[threadId] = true; + + tlm_generic_payload &tPayload = *pendingResponses[threadId].front(); + pendingResponses[threadId].pop(); + tlm_phase tPhase = BEGIN_RESP; + 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); + // Early completion from initiator + if (returnValue == TLM_UPDATED) + payloadEventQueue.notify(tPayload, tPhase, tDelay); + } + } else SC_REPORT_FATAL(0, "Payload event queue in arbiter was triggered with unknown phase"); } diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index 3746e784..3ff5370d 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -51,6 +51,9 @@ #include "AddressDecoder.h" #include "../common/dramExtensions.h" +DECLARE_EXTENDED_PHASE(REQ_ARBITRATION); +DECLARE_EXTENDED_PHASE(RESP_ARBITRATION); + class Arbiter : public sc_module { public: