Added support for early completion on initiator side (BEGIN_RESP).

This commit is contained in:
Lukas Steiner
2020-04-30 13:37:08 +02:00
parent eb265f4bdd
commit 3598bdf090

View File

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