Make controller easier to understand.
This commit is contained in:
@@ -219,24 +219,14 @@ Controller::~Controller()
|
||||
|
||||
void Controller::controllerMethod()
|
||||
{
|
||||
// clear command buffer
|
||||
readyCommands.clear();
|
||||
|
||||
// (1) Release payload if arbiter has accepted the result (finish END_RESP)
|
||||
if (payloadToRelease != nullptr && timeToRelease <= sc_time_stamp())
|
||||
finishEndResp();
|
||||
finishEndResp();
|
||||
|
||||
// (2) Send next result to arbiter (start BEGIN_RESP)
|
||||
if (payloadToRelease == nullptr)
|
||||
startBeginResp();
|
||||
startBeginResp();
|
||||
|
||||
// (3) Insert new request from arbiter into scheduler and restart appropriate BM (finish BEGIN_REQ)
|
||||
if (payloadToAcquire != nullptr && timeToAcquire <= sc_time_stamp())
|
||||
{
|
||||
unsigned bankID = DramExtension::getBank(payloadToAcquire).ID();
|
||||
finishBeginReq();
|
||||
bankMachines[bankID]->start();
|
||||
}
|
||||
finishBeginReq();
|
||||
|
||||
// (4) Start refresh and power-down managers to issue requests for the current time
|
||||
for (auto it : refreshManagers)
|
||||
@@ -244,8 +234,10 @@ void Controller::controllerMethod()
|
||||
for (auto it : powerDownManagers)
|
||||
it->start();
|
||||
|
||||
// (5) Choose one request and send it to DRAM
|
||||
// (5) Collect all ready commands from BMs, RMs and PDMs
|
||||
CommandTuple::Type commandTuple;
|
||||
// clear command buffer
|
||||
readyCommands.clear();
|
||||
|
||||
for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++)
|
||||
{
|
||||
@@ -270,6 +262,7 @@ void Controller::controllerMethod()
|
||||
}
|
||||
}
|
||||
|
||||
// (6) Select one of the ready commands and issue it to the DRAM
|
||||
bool readyCmdBlocked = false;
|
||||
if (!readyCommands.empty())
|
||||
{
|
||||
@@ -314,12 +307,10 @@ void Controller::controllerMethod()
|
||||
readyCmdBlocked = true;
|
||||
}
|
||||
|
||||
// (6) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ)
|
||||
if (payloadToAcquire != nullptr && timeToAcquire == sc_max_time())
|
||||
startEndReq();
|
||||
// (7) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ)
|
||||
startEndReq();
|
||||
|
||||
// (7) Restart bank machines, refresh managers and power-down managers to issue new requests for the future
|
||||
// TODO: check if all calls are necessary
|
||||
// (8) Restart bank machines, refresh managers and power-down managers to issue new requests for the future
|
||||
sc_time timeForNextTrigger = sc_max_time();
|
||||
for (auto it : bankMachines)
|
||||
{
|
||||
@@ -343,13 +334,13 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload &trans,
|
||||
|
||||
if (phase == BEGIN_REQ)
|
||||
{
|
||||
payloadToAcquire = &trans;
|
||||
timeToAcquire = sc_time_stamp() + notificationDelay;
|
||||
transToAcquire.payload = &trans;
|
||||
transToAcquire.time = sc_time_stamp() + notificationDelay;
|
||||
beginReqEvent.notify(notificationDelay);
|
||||
}
|
||||
else if (phase == END_RESP)
|
||||
{
|
||||
timeToRelease = sc_time_stamp() + notificationDelay;
|
||||
transToRelease.time = sc_time_stamp() + notificationDelay;
|
||||
endRespEvent.notify(notificationDelay);
|
||||
}
|
||||
else
|
||||
@@ -375,63 +366,80 @@ unsigned int Controller::transport_dbg(tlm_generic_payload &trans)
|
||||
|
||||
void Controller::finishBeginReq()
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(payloadToAcquire);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
if (transToAcquire.payload != nullptr && transToAcquire.time <= sc_time_stamp())
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToAcquire.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system.");
|
||||
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.end();
|
||||
totalNumberOfPayloads++;
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.end();
|
||||
totalNumberOfPayloads++;
|
||||
|
||||
Rank rank = DramExtension::getRank(payloadToAcquire);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
Rank rank = DramExtension::getRank(transToAcquire.payload);
|
||||
if (ranksNumberOfPayloads[rank.ID()] == 0)
|
||||
powerDownManagers[rank.ID()]->triggerExit();
|
||||
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
ranksNumberOfPayloads[rank.ID()]++;
|
||||
|
||||
scheduler->storeRequest(payloadToAcquire);
|
||||
payloadToAcquire->acquire();
|
||||
timeToAcquire = sc_max_time();
|
||||
scheduler->storeRequest(transToAcquire.payload);
|
||||
transToAcquire.payload->acquire();
|
||||
transToAcquire.time = sc_max_time();
|
||||
|
||||
Bank bank = DramExtension::getBank(transToAcquire.payload);
|
||||
bankMachines[bank.ID()]->start();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::startEndReq()
|
||||
{
|
||||
if (scheduler->hasBufferSpace())
|
||||
if (transToAcquire.payload != nullptr && transToAcquire.time == sc_max_time())
|
||||
{
|
||||
payloadToAcquire->set_response_status(TLM_OK_RESPONSE);
|
||||
sendToFrontend(payloadToAcquire, END_REQ);
|
||||
payloadToAcquire = nullptr;
|
||||
if (scheduler->hasBufferSpace())
|
||||
{
|
||||
transToAcquire.payload->set_response_status(TLM_OK_RESPONSE);
|
||||
sendToFrontend(transToAcquire.payload, END_REQ);
|
||||
transToAcquire.payload = nullptr;
|
||||
}
|
||||
else
|
||||
PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!");
|
||||
}
|
||||
else
|
||||
PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!");
|
||||
}
|
||||
|
||||
void Controller::startBeginResp()
|
||||
{
|
||||
payloadToRelease = respQueue->nextPayload();
|
||||
|
||||
if (payloadToRelease != nullptr)
|
||||
sendToFrontend(payloadToRelease, BEGIN_RESP);
|
||||
else
|
||||
if (transToRelease.payload == nullptr)
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
transToRelease.payload = respQueue->nextPayload();
|
||||
|
||||
if (transToRelease.payload != nullptr)
|
||||
{
|
||||
transToRelease.time = sc_max_time();
|
||||
sendToFrontend(transToRelease.payload, BEGIN_RESP);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != sc_max_time())
|
||||
dataResponseEvent.notify(triggerTime - sc_time_stamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::finishEndResp()
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(payloadToRelease);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
|
||||
if (transToRelease.payload != nullptr && transToRelease.time <= sc_time_stamp())
|
||||
{
|
||||
NDEBUG_UNUSED(uint64_t id) = DramExtension::getPayloadID(transToRelease.payload);
|
||||
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
|
||||
|
||||
payloadToRelease->release();
|
||||
payloadToRelease = nullptr;
|
||||
timeToRelease = sc_max_time();
|
||||
numberOfTransactionsServed++;
|
||||
transToRelease.payload->release();
|
||||
transToRelease.payload = nullptr;
|
||||
numberOfTransactionsServed++;
|
||||
|
||||
totalNumberOfPayloads--;
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.start();
|
||||
totalNumberOfPayloads--;
|
||||
if (totalNumberOfPayloads == 0)
|
||||
idleTimeCollector.start();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase)
|
||||
|
||||
@@ -88,10 +88,11 @@ private:
|
||||
std::vector<RefreshManagerIF *> refreshManagers;
|
||||
std::vector<PowerDownManagerIF *> powerDownManagers;
|
||||
|
||||
tlm::tlm_generic_payload *payloadToAcquire = nullptr;
|
||||
sc_time timeToAcquire = sc_max_time();
|
||||
tlm::tlm_generic_payload *payloadToRelease = nullptr;
|
||||
sc_time timeToRelease = sc_max_time();
|
||||
struct Transaction
|
||||
{
|
||||
tlm::tlm_generic_payload *payload = nullptr;
|
||||
sc_time time = sc_max_time();
|
||||
} transToAcquire, transToRelease;
|
||||
|
||||
void finishBeginReq();
|
||||
void startEndReq();
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <tlm_utils/multi_passthrough_target_socket.h>
|
||||
#include <tlm_utils/multi_passthrough_initiator_socket.h>
|
||||
#include <tlm_utils/peq_with_cb_and_phase.h>
|
||||
@@ -70,7 +71,7 @@ private:
|
||||
std::vector<std::queue<tlm::tlm_generic_payload *>> pendingRequests;
|
||||
// used to account for the response_accept_delay in the initiators (traceplayer, core etc.)
|
||||
// This is a queue of responses comming from the memory side. The phase of these transactions is BEGIN_RESP.
|
||||
std::map<unsigned int, std::queue<tlm::tlm_generic_payload *>> pendingResponses;
|
||||
std::unordered_map<unsigned int, std::queue<tlm::tlm_generic_payload *>> pendingResponses;
|
||||
|
||||
// Initiated by initiator side
|
||||
// This function is called when an arbiter's target socket receives a transaction from a device
|
||||
|
||||
Reference in New Issue
Block a user