From 328a37184347feee6899b39de46809f4d96dbf0d Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Tue, 20 Oct 2020 09:32:28 +0200 Subject: [PATCH] Make controller easier to understand. --- DRAMSys/library/src/controller/Controller.cpp | 122 ++++++++++-------- DRAMSys/library/src/controller/Controller.h | 9 +- DRAMSys/library/src/simulation/Arbiter.h | 3 +- 3 files changed, 72 insertions(+), 62 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 8ff1d7f6..4176929e 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -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) diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index 9002c007..4fef0c65 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -88,10 +88,11 @@ private: std::vector refreshManagers; std::vector 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(); diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index a6373b33..c845e2b9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,7 @@ private: std::vector> 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> pendingResponses; + std::unordered_map> pendingResponses; // Initiated by initiator side // This function is called when an arbiter's target socket receives a transaction from a device