From fbbe306ee50f513c742ede3a21d146e2f6eec215 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Wed, 1 Apr 2020 16:01:07 +0200 Subject: [PATCH] New hardware-equivalent backpressure implementation. --- DRAMSys/library/src/controller/Controller.cpp | 127 +++++++++--------- DRAMSys/library/src/controller/Controller.h | 6 +- .../powerdown/PowerDownManagerStaggered.h | 2 +- .../controller/scheduler/SchedulerFifo.cpp | 7 +- .../src/controller/scheduler/SchedulerFifo.h | 3 +- .../controller/scheduler/SchedulerFrFcfs.cpp | 7 +- .../controller/scheduler/SchedulerFrFcfs.h | 3 +- .../scheduler/SchedulerFrFcfsGrp.cpp | 7 +- .../controller/scheduler/SchedulerFrFcfsGrp.h | 3 +- .../src/controller/scheduler/SchedulerIF.h | 2 +- 10 files changed, 88 insertions(+), 79 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 9256cb81..8da97ddc 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -65,7 +65,6 @@ Controller::Controller(sc_module_name name) : { SC_METHOD(controllerMethod); sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent; - dont_initialize(); Configuration &config = Configuration::getInstance(); memSpec = config.memSpec; @@ -162,8 +161,6 @@ Controller::Controller(sc_module_name name) : { PowerDownManagerIF *manager = new PowerDownManagerStaggered(Rank(rankID), checker); powerDownManagers.push_back(manager); - manager->triggerEntry(TriggerSource::Controller); - controllerEvent.notify(manager->start()); } } else @@ -182,7 +179,6 @@ Controller::Controller(sc_module_name name) : RefreshManagerIF *manager = new RefreshManagerRankwise (bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker); refreshManagers.push_back(manager); - controllerEvent.notify(manager->start()); } } else if (config.refreshPolicy == "Bankwise") @@ -193,7 +189,6 @@ Controller::Controller(sc_module_name name) : RefreshManagerIF *manager = new RefreshManagerBankwise (bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker); refreshManagers.push_back(manager); - controllerEvent.notify(manager->start()); } } else @@ -220,38 +215,20 @@ Controller::~Controller() void Controller::controllerMethod() { - // (1) Release payload if arbiter has accepted the result - if (sc_time_stamp() == timeToRelease && payloadToRelease != nullptr) - releasePayload(); + // (1) Release payload if arbiter has accepted the result (finish END_RESP) + if (payloadToRelease != nullptr && timeToRelease <= sc_time_stamp()) + finishEndResp(); - // (2) Send next result to arbiter + // (2) Send next result to arbiter (start BEGIN_RESP) if (payloadToRelease == nullptr) - { - payloadToRelease = respQueue->nextPayload(); + startBeginResp(); - if (payloadToRelease != nullptr) - sendToFrontend(payloadToRelease, BEGIN_RESP); - else - { - sc_time triggerTime = respQueue->getTriggerTime(); - if (triggerTime != sc_max_time()) - dataResponseEvent.notify(triggerTime - sc_time_stamp()); - } - } - - // (3) Accept new request from arbiter and start appropriate BM if necessary - if (sc_time_stamp() >= timeToAcquire && payloadToAcquire != nullptr) + // (3) Insert new request from arbiter into scheduler and restart appropriate BM (finish BEGIN_REQ) + if (payloadToAcquire != nullptr && timeToAcquire <= sc_time_stamp()) { - if (scheduler->hasBufferSpace(payloadToAcquire)) - { - Bank bank = DramExtension::getBank(payloadToAcquire); - acquirePayload(); - - if (bankMachines[bank.ID()]->isIdle()) - bankMachines[bank.ID()]->start(); - } - else - PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); + unsigned bankID = DramExtension::getBank(payloadToAcquire).ID(); + finishBeginReq(); + bankMachines[bankID]->start(); } // (4) Start refresh and power-down managers to issue requests for the current time @@ -334,7 +311,11 @@ void Controller::controllerMethod() readyCmdBlocked = true; } - // (6) Restart bank machines, refresh managers and power-down managers to issue new requests for the future + // (6) Accept request from arbiter if scheduler is not full, otherwise backpressure (start END_REQ) + if (payloadToAcquire != nullptr && timeToAcquire == sc_max_time()) + 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 sc_time timeForNextTrigger = sc_max_time(); for (auto it : bankMachines) @@ -343,8 +324,6 @@ void Controller::controllerMethod() if (!(localTime == sc_time_stamp() && readyCmdBlocked)) timeForNextTrigger = std::min(timeForNextTrigger, localTime); } - if (payloadToAcquire != nullptr && sc_time_stamp() >= timeToAcquire && scheduler->hasBufferSpace(payloadToAcquire)) - acquirePayload(); for (auto it : refreshManagers) timeForNextTrigger = std::min(timeForNextTrigger, it->start()); for (auto it : powerDownManagers) @@ -394,7 +373,55 @@ unsigned int Controller::transport_dbg(tlm_generic_payload &) return 0; } -void Controller::releasePayload() +void Controller::finishBeginReq() +{ + uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToAcquire); + PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system."); + + if (totalNumberOfPayloads == 0) + idleTimeCollector.end(); + totalNumberOfPayloads++; + + Rank rank = DramExtension::getRank(payloadToAcquire); + if (ranksNumberOfPayloads[rank.ID()] == 0) + { + refreshManagers[rank.ID()]->notifyActive(); + powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller); + } + ranksNumberOfPayloads[rank.ID()]++; + + scheduler->storeRequest(payloadToAcquire); + payloadToAcquire->acquire(); + timeToAcquire = sc_max_time(); +} + +void Controller::startEndReq() +{ + if (scheduler->hasBufferSpace()) + { + payloadToAcquire->set_response_status(TLM_OK_RESPONSE); + sendToFrontend(payloadToAcquire, END_REQ); + payloadToAcquire = nullptr; + } + else + PRINTDEBUGMESSAGE(name(), "Total number of payloads exceeded, backpressure!"); +} + +void Controller::startBeginResp() +{ + payloadToRelease = respQueue->nextPayload(); + + if (payloadToRelease != nullptr) + sendToFrontend(payloadToRelease, BEGIN_RESP); + else + { + sc_time triggerTime = respQueue->getTriggerTime(); + if (triggerTime != sc_max_time()) + dataResponseEvent.notify(triggerTime - sc_time_stamp()); + } +} + +void Controller::finishEndResp() { uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToRelease); PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system."); @@ -409,32 +436,6 @@ void Controller::releasePayload() idleTimeCollector.start(); } -void Controller::acquirePayload() -{ - uint64_t id __attribute__((unused)) = DramExtension::getPayloadID(payloadToAcquire); - PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " entered system."); - - Rank rank = DramExtension::getRank(payloadToAcquire); - - if (totalNumberOfPayloads == 0) - idleTimeCollector.end(); - totalNumberOfPayloads++; - - if(ranksNumberOfPayloads[rank.ID()] == 0) - { - refreshManagers[rank.ID()]->notifyActive(); - powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller); - } - ranksNumberOfPayloads[rank.ID()]++; - - scheduler->storeRequest(payloadToAcquire); - payloadToAcquire->acquire(); - payloadToAcquire->set_response_status(TLM_OK_RESPONSE); - sendToFrontend(payloadToAcquire, END_REQ); - payloadToAcquire = nullptr; - timeToAcquire = sc_max_time(); -} - void Controller::sendToFrontend(tlm_generic_payload *payload, tlm_phase phase) { sc_time delay = SC_ZERO_TIME; diff --git a/DRAMSys/library/src/controller/Controller.h b/DRAMSys/library/src/controller/Controller.h index e94a2262..4f0ce5f2 100644 --- a/DRAMSys/library/src/controller/Controller.h +++ b/DRAMSys/library/src/controller/Controller.h @@ -94,8 +94,10 @@ private: tlm_generic_payload *payloadToRelease = nullptr; sc_time timeToRelease = sc_max_time(); - void releasePayload(); - void acquirePayload(); + void finishBeginReq(); + void startEndReq(); + void startBeginResp(); + void finishEndResp(); void controllerMethod(); sc_event beginReqEvent, endRespEvent, controllerEvent, dataResponseEvent; diff --git a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h index 350e38b5..3ae9a7f1 100644 --- a/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h +++ b/DRAMSys/library/src/controller/powerdown/PowerDownManagerStaggered.h @@ -62,7 +62,7 @@ private: sc_time timeToSchedule; Command nextCommand; - bool triggered = false; + bool triggered = true; bool enterSelfRefresh = false; bool controllerIdle = true; unsigned activatedBanks = 0; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index d90d8dd6..6c4050ed 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -41,9 +41,9 @@ SchedulerFifo::SchedulerFifo() requestBufferSize = Configuration::getInstance().requestBufferSize; } -bool SchedulerFifo::hasBufferSpace(tlm_generic_payload *payload) +bool SchedulerFifo::hasBufferSpace() { - if (buffer[DramExtension::getBank(payload).ID()].size() < requestBufferSize) + if (buffer[lastBankID].size() < requestBufferSize) return true; else return false; @@ -51,7 +51,8 @@ bool SchedulerFifo::hasBufferSpace(tlm_generic_payload *payload) void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + lastBankID = DramExtension::getBank(payload).ID(); + buffer[lastBankID].push_back(payload); } void SchedulerFifo::removeRequest(tlm_generic_payload *payload) diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index 3acee039..51955c48 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -48,7 +48,7 @@ class SchedulerFifo : public SchedulerIF { public: SchedulerFifo(); - virtual bool hasBufferSpace(tlm_generic_payload *) override; + virtual bool hasBufferSpace() override; virtual void storeRequest(tlm_generic_payload *) override; virtual void removeRequest(tlm_generic_payload *) override; virtual tlm_generic_payload *getNextRequest(BankMachine *) override; @@ -57,6 +57,7 @@ public: private: std::vector> buffer; unsigned requestBufferSize; + unsigned lastBankID; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index 0262e009..4e87354c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -43,9 +43,9 @@ SchedulerFrFcfs::SchedulerFrFcfs() requestBufferSize = Configuration::getInstance().requestBufferSize; } -bool SchedulerFrFcfs::hasBufferSpace(tlm_generic_payload *payload) +bool SchedulerFrFcfs::hasBufferSpace() { - if (buffer[DramExtension::getBank(payload).ID()].size() < requestBufferSize) + if (buffer[lastBankID].size() < requestBufferSize) return true; else return false; @@ -53,7 +53,8 @@ bool SchedulerFrFcfs::hasBufferSpace(tlm_generic_payload *payload) void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + lastBankID = DramExtension::getBank(payload).ID(); + buffer[lastBankID].push_back(payload); } void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index c0250513..5470ff68 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -48,7 +48,7 @@ class SchedulerFrFcfs : public SchedulerIF { public: SchedulerFrFcfs(); - virtual bool hasBufferSpace(tlm_generic_payload *) override; + virtual bool hasBufferSpace() override; virtual void storeRequest(tlm_generic_payload *) override; virtual void removeRequest(tlm_generic_payload *) override; virtual tlm_generic_payload *getNextRequest(BankMachine *) override; @@ -57,6 +57,7 @@ public: private: std::vector> buffer; unsigned requestBufferSize; + unsigned lastBankID; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 077c6f9d..d62705ad 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -41,9 +41,9 @@ SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() requestBufferSize = Configuration::getInstance().requestBufferSize; } -bool SchedulerFrFcfsGrp::hasBufferSpace(tlm_generic_payload *payload) +bool SchedulerFrFcfsGrp::hasBufferSpace() { - if (buffer[DramExtension::getBank(payload).ID()].size() < requestBufferSize) + if (buffer[lastBankID].size() < requestBufferSize) return true; else return false; @@ -51,7 +51,8 @@ bool SchedulerFrFcfsGrp::hasBufferSpace(tlm_generic_payload *payload) void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].push_back(payload); + lastBankID = DramExtension::getBank(payload).ID(); + buffer[lastBankID].push_back(payload); } void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 0b7418df..fbc5e92c 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -49,7 +49,7 @@ class SchedulerFrFcfsGrp : public SchedulerIF { public: SchedulerFrFcfsGrp(); - virtual bool hasBufferSpace(tlm_generic_payload *) override; + virtual bool hasBufferSpace() override; virtual void storeRequest(tlm_generic_payload *) override; virtual void removeRequest(tlm_generic_payload *) override; virtual tlm_generic_payload *getNextRequest(BankMachine *) override; @@ -59,6 +59,7 @@ private: std::vector> buffer; unsigned requestBufferSize; tlm_command lastCommand = TLM_READ_COMMAND; + unsigned lastBankID; }; #endif // SCHEDULERFRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index d7504bbb..9ab2bc71 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -49,7 +49,7 @@ class SchedulerIF { public: virtual ~SchedulerIF() {} - virtual bool hasBufferSpace(tlm_generic_payload *) = 0; + virtual bool hasBufferSpace() = 0; virtual void storeRequest(tlm_generic_payload *) = 0; virtual void removeRequest(tlm_generic_payload *) = 0; virtual tlm_generic_payload *getNextRequest(BankMachine *) = 0;