Fix arbitration delays in FIFO arbiter.

This commit is contained in:
Lukas Steiner
2021-07-02 14:37:47 +02:00
parent 9922201185
commit 7253b34800
2 changed files with 82 additions and 36 deletions

View File

@@ -280,22 +280,25 @@ void ArbiterFifo::peqCallback(tlm_generic_payload &cbPayload, const tlm_phase &c
tSocket[static_cast<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(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");
}

View File

@@ -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: