From fa301d2bb4f7933c2f8e6f430e2422a514c52517 Mon Sep 17 00:00:00 2001 From: Lukas Steiner Date: Fri, 22 Nov 2019 01:01:08 +0100 Subject: [PATCH] Staggered power-down working, adapt per-bank refresh. --- DRAMSys/library/src/controller/Controller.cpp | 7 ++ .../src/controller/refresh/RefreshManager.cpp | 100 +++++++----------- .../src/controller/refresh/RefreshManager.h | 8 +- .../refresh/RefreshManagerBankwise.h | 3 + .../controller/refresh/RefreshManagerDummy.h | 3 + .../src/controller/refresh/RefreshManagerIF.h | 3 + 6 files changed, 63 insertions(+), 61 deletions(-) diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 56a1754c..f0af873c 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -170,6 +170,7 @@ Controller::Controller(sc_module_name name) : { for (unsigned rankID = 0; rankID < memSpec->NumberOfRanks; rankID++) { + // TODO: remove bankMachines in constructor RefreshManagerIF *manager = new RefreshManagerBankwise (bankMachinesOnRank[rankID], powerDownManagers[rankID], Rank(rankID), checker); refreshManagers.push_back(manager); @@ -357,7 +358,10 @@ tlm_sync_enum Controller::nb_transport_bw(tlm_generic_payload &trans, Rank rank = DramExtension::getRank(trans); ranksNumberOfPayloads[rank.ID()]--; if (ranksNumberOfPayloads[rank.ID()] == 0) + { + refreshManagers[rank.ID()]->messageIdle(); powerDownManagers[rank.ID()]->triggerEntry(TriggerSource::Controller); + } } return TLM_ACCEPTED; @@ -396,7 +400,10 @@ void Controller::acquirePayload() totalNumberOfPayloads++; if(ranksNumberOfPayloads[rank.ID()] == 0) + { + refreshManagers[rank.ID()]->messageActive(); powerDownManagers[rank.ID()]->triggerExit(TriggerSource::Controller); + } ranksNumberOfPayloads[rank.ID()]++; scheduler->storeRequest(payloadToAcquire); diff --git a/DRAMSys/library/src/controller/refresh/RefreshManager.cpp b/DRAMSys/library/src/controller/refresh/RefreshManager.cpp index 773fae5a..ccc836d4 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManager.cpp +++ b/DRAMSys/library/src/controller/refresh/RefreshManager.cpp @@ -52,6 +52,16 @@ RefreshManager::RefreshManager(std::vector &bankMachines, maxPulledin = -config.ControllerCoreRefMaxPulledIn; } +void RefreshManager::messageActive() +{ + controllerIdle = false; +} + +void RefreshManager::messageIdle() +{ + controllerIdle = true; +} + std::pair RefreshManager::getNextCommand() { if (sc_time_stamp() == timeToSchedule && !blocked) @@ -80,65 +90,38 @@ sc_time RefreshManager::start() if (state == RmState::Regular) { bool forcedRefresh = (flexibilityCounter == maxPostponed); - if (!forcedRefresh) + if (!forcedRefresh && !controllerIdle) { - for (auto it : bankMachines) - { - if (!it->isIdle()) - { - flexibilityCounter++; - timeForNextTrigger += memSpec->getRefreshIntervalAB(); - return timeForNextTrigger - sc_time_stamp(); - } - } + flexibilityCounter++; + timeForNextTrigger += memSpec->getRefreshIntervalAB(); + return timeForNextTrigger - sc_time_stamp(); } - else // regular refresh that cannot be postponed -> force precharge + else { - for (auto it : bankMachines) - it->block(); - } - - for (auto it : bankMachines) - { - if (it->getState() == BmState::Activated) // at least one bank is active -> do PREA - { + if (activatedBanks > 0) nextCommand = Command::PREA; - delay = checker->delayToSatisfyConstraints(Command::PREA, rank, BankGroup(0), Bank(0)); - timeToSchedule = sc_time_stamp() + delay; - return delay; - } + else + nextCommand = Command::REFA; + delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0)); + timeToSchedule = sc_time_stamp() + delay; + return delay; } - - if (forcedRefresh) // if refresh is forced all banks will remain in precharged state - state = RmState::Precharged; - - nextCommand = Command::REFA; - delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0)); - timeToSchedule = sc_time_stamp() + delay; - return delay; } - else if (state == RmState::Pulledin) + else // if (state == RmState::Pulledin) { - for (auto it : bankMachines) + if (!controllerIdle) { - if (!it->isIdle()) // at least one bank has a payload -> abort pulling in - { - state = RmState::Regular; - timeForNextTrigger += memSpec->getRefreshIntervalAB(); - return timeForNextTrigger - sc_time_stamp(); - } + state = RmState::Regular; + timeForNextTrigger += memSpec->getRefreshIntervalAB(); + return timeForNextTrigger - sc_time_stamp(); + } + else + { + // nextCommand stays Command::REFA + delay = checker->delayToSatisfyConstraints(nextCommand, rank, BankGroup(0), Bank(0)); + timeToSchedule = sc_time_stamp() + delay; + return delay; } - - delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0)); - timeToSchedule = sc_time_stamp() + delay; - return delay; - } - else // if (state == RmState::Precharged) - { - nextCommand = Command::REFA; - delay = checker->delayToSatisfyConstraints(Command::REFA, rank, BankGroup(0), Bank(0)); - timeToSchedule = sc_time_stamp() + delay; - return delay; } } else @@ -147,8 +130,13 @@ sc_time RefreshManager::start() void RefreshManager::updateState(Command command, tlm_generic_payload *) { - // TODO: first ask if RAS command, otherwise ignore it - if (command == Command::REFA) + if (command == Command::ACT) + activatedBanks++; + else if (command == Command::PRE) + activatedBanks--; + else if (command == Command::PREA) + activatedBanks = 0; + else if (command == Command::REFA) { if (blocked) { @@ -172,14 +160,6 @@ void RefreshManager::updateState(Command command, tlm_generic_payload *) } } } - else if (command == Command::PREA) - { - // if PREA was successful we will do the refresh in any case - for (auto it : bankMachines) - it->block(); - // TODO: remove for and insert blocking directly into BM - state = RmState::Precharged; - } else if (command == Command::PDEA || command == Command::PDEP) blocked = true; else if (command == Command::SREFEN) diff --git a/DRAMSys/library/src/controller/refresh/RefreshManager.h b/DRAMSys/library/src/controller/refresh/RefreshManager.h index b718b243..44f85fe0 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManager.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManager.h @@ -52,8 +52,11 @@ public: virtual sc_time start() override; virtual void updateState(Command, tlm_generic_payload *) override; + virtual void messageActive() override; + virtual void messageIdle() override; + private: - enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular; + enum class RmState {Regular, Pulledin} state = RmState::Regular; const MemSpec *memSpec; std::vector &bankMachines; PowerDownManagerIF *powerDownManager; @@ -64,6 +67,9 @@ private: CheckerIF *checker; Command nextCommand; + bool controllerIdle = true; + unsigned activatedBanks = 0; + int flexibilityCounter = 0; int maxPostponed = 0; int maxPulledin = 0; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h index 63f8f210..cdf457c1 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerBankwise.h @@ -54,6 +54,9 @@ public: virtual sc_time start() override; virtual void updateState(Command, tlm_generic_payload *) override; + virtual void messageActive() override {} + virtual void messageIdle() override {} + private: enum class RmState {Regular, Precharged, Pulledin} state = RmState::Regular; const MemSpec *memSpec; diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h index 3a62916a..a59a5112 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerDummy.h @@ -49,6 +49,9 @@ public: virtual std::pair getNextCommand() override; virtual sc_time start() override; virtual void updateState(Command, tlm_generic_payload *) override {} + + virtual void messageActive() override {} + virtual void messageIdle() override {} }; #endif // REFRESHMANAGERDUMMY_H diff --git a/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h b/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h index d1e589ca..fd428a37 100644 --- a/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h +++ b/DRAMSys/library/src/controller/refresh/RefreshManagerIF.h @@ -50,6 +50,9 @@ public: virtual std::pair getNextCommand() = 0; virtual sc_time start() = 0; virtual void updateState(Command, tlm_generic_payload *) = 0; + + virtual void messageIdle() = 0; + virtual void messageActive() = 0; }; #endif // REFRESHMANAGERIF_H